From owner-p4-projects@FreeBSD.ORG Fri Jul 3 17:06:03 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 68167106566C; Fri, 3 Jul 2009 17:06:03 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 26C0A1065672 for ; Fri, 3 Jul 2009 17:06:03 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 13A1E8FC16 for ; Fri, 3 Jul 2009 17:06:03 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n63H63ql017243 for ; Fri, 3 Jul 2009 17:06:03 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n63H63FH017241 for perforce@freebsd.org; Fri, 3 Jul 2009 17:06:03 GMT (envelope-from gk@FreeBSD.org) Date: Fri, 3 Jul 2009 17:06:03 GMT Message-Id: <200907031706.n63H63FH017241@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gk@FreeBSD.org using -f From: Gleb Kurtsou To: Perforce Change Reviews Cc: Subject: PERFORCE change 165570 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Jul 2009 17:06:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=165570 Change 165570 by gk@gk_h1 on 2009/07/03 17:05:56 temporally use rc4 for encryption Affected files ... .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#5 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#2 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#5 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#4 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#5 edit Differences ... ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#5 (text+ko) ==== @@ -59,16 +59,16 @@ char pk_data[PEFS_KEY_SIZE]; }; -struct pefs_node_key { - struct pefs_key *pnk_key; - char pnk_tweak[PEFS_TWEAK_SIZE]; +struct pefs_tkey { + struct pefs_key *ptk_key; + char ptk_tweak[PEFS_TWEAK_SIZE]; }; struct pefs_node { LIST_ENTRY(pefs_node) pn_hash; /* Hash list */ struct vnode *pn_lowervp; /* VREFed once */ struct vnode *pn_vnode; /* Back pointer */ - struct pefs_node_key pn_key; + struct pefs_tkey pn_tkey; }; struct pefs_mount { @@ -131,16 +131,19 @@ int pefs_init(struct vfsconf *vfsp); int pefs_uninit(struct vfsconf *vfsp); -int pefs_node_get(struct mount *mp, struct vnode *target, struct vnode **vpp); +int pefs_node_get(struct mount *mp, struct vnode *lowervp, struct vnode **vpp, struct pefs_tkey *ptk); void pefs_node_free(struct pefs_node *xp); +struct pefs_key* pefs_node_key(struct pefs_node *pn); +struct pefs_tkey* pefs_node_tkey(struct pefs_node *pn); -void pefs_data_encrypt(struct pefs_node *pn, off_t offset, struct pefs_chunk *pc); -void pefs_data_encrypt_buf(struct pefs_node *pn, off_t offset, void *mem, size_t size); -void pefs_data_decrypt(struct pefs_node *pn, off_t offset, struct pefs_chunk *pc); -void pefs_data_decrypt_buf(struct pefs_node *pn, off_t offset, void *mem, size_t size); +void pefs_data_encrypt(struct pefs_tkey *ptk, off_t offset, struct pefs_chunk *pc); +void pefs_data_encrypt_buf(struct pefs_tkey *ptk, off_t offset, void *mem, size_t size); +void pefs_data_decrypt(struct pefs_tkey *ptk, off_t offset, struct pefs_chunk *pc); +void pefs_data_decrypt_buf(struct pefs_tkey *ptk, off_t offset, void *mem, size_t size); + +int pefs_name_encrypt(struct pefs_tkey *ptk, const char *plain, size_t plain_len, char *enc, size_t enc_size); +int pefs_name_decrypt(struct pefs_key *pk, struct pefs_tkey *ptk, const char *enc, size_t enc_len, char *plain, size_t plain_size); -int pefs_name_encrypt(struct pefs_node_key *pnk, const char *plain, size_t plain_len, char *enc, size_t enc_size); -int pefs_name_decrypt(struct pefs_node_key *pnk, const char *enc, size_t enc_len, char *plain, size_t plain_size); int pefs_name_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); int pefs_name_pton(char const *src, size_t srclen, u_char *target, size_t targsize); ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#2 (text+ko) ==== @@ -32,9 +32,11 @@ #include #include +#include + #include - +#if 0 static void pefs_xor(void *mem, size_t size) { @@ -60,25 +62,63 @@ pefs_xor(mem, size); } } +#endif -void pefs_data_encrypt(struct pefs_node *pn, off_t offset, struct pefs_chunk *pc) +void +pefs_data_encrypt(struct pefs_tkey *ptk, off_t offset, struct pefs_chunk *pc) { - pefs_xor_chunk(pc); + long arg = 0; + char *mem; + size_t size; + + if (ptk->ptk_key == NULL) { + PEFSDEBUG("!!! %s: NULL ptk_key\n", __func__); + return; + } + if (offset % PEFS_BLOCK != 0) { + PEFSDEBUG("!!! %s: invalid offset %jd\n", __func__, offset); + return; + } + + // FIXME + struct rc4_state rc4state; + rc4_init(&rc4state, ptk->ptk_key->pk_data, PEFS_KEY_SIZE); + while (1) { + mem = pefs_chunk_get(pc, &size, &arg); + if (mem == NULL) + break; + rc4_crypt(&rc4state, mem, mem, size); + } } -void pefs_data_encrypt_buf(struct pefs_node *pn, off_t offset, void *mem, size_t size) +void +pefs_data_encrypt_buf(struct pefs_tkey *ptk, off_t offset, void *mem, size_t size) { - pefs_xor(mem, size); + if (ptk->ptk_key == NULL) { + PEFSDEBUG("!!! %s: NULL ptk_key\n", __func__); + return; + } + if (offset % PEFS_BLOCK != 0) { + PEFSDEBUG("!!! %s: invalid offset %jd\n", __func__, offset); + return; + } + + // FIXME + struct rc4_state rc4state; + rc4_init(&rc4state, ptk->ptk_key->pk_data, PEFS_KEY_SIZE); + rc4_crypt(&rc4state, mem, mem, size); } -void pefs_data_decrypt(struct pefs_node *pn, off_t offset, struct pefs_chunk *pc) +void +pefs_data_decrypt(struct pefs_tkey *ptk, off_t offset, struct pefs_chunk *pc) { - pefs_xor_chunk(pc); + pefs_data_encrypt(ptk, offset, pc); } -void pefs_data_decrypt_buf(struct pefs_node *pn, off_t offset, void *mem, size_t size) +void +pefs_data_decrypt_buf(struct pefs_tkey *ptk, off_t offset, void *mem, size_t size) { - pefs_xor(mem, size); + pefs_data_encrypt_buf(ptk, offset, mem, size); } /* @@ -107,13 +147,18 @@ } int -pefs_name_encrypt(struct pefs_node_key *pnk, const char *plain, size_t plain_len, char *enc, size_t enc_size) +pefs_name_encrypt(struct pefs_tkey *ptk, const char *plain, size_t plain_len, char *enc, size_t enc_size) { char *buf; size_t size; u_short csum; int r; + if (ptk == NULL || ptk->ptk_key == NULL) { + PEFSDEBUG("!!!! %s: NULL key\n", __func__); + return (-1); + } + size = PEFS_TWEAK_SIZE + plain_len + PEFS_NAME_CSUM_SIZE; if (enc_size < PEFS_NAME_NTOP_SIZE(size)) { PEFSDEBUG("%s: encname buffer is too short: length=%d; required=%d\n", @@ -123,15 +168,16 @@ buf = malloc(size, M_PEFSBUF, M_WAITOK); - memcpy(buf, pnk->pnk_tweak, PEFS_TWEAK_SIZE); + memcpy(buf, ptk->ptk_tweak, PEFS_TWEAK_SIZE); memcpy(buf + PEFS_TWEAK_SIZE, plain, plain_len); bzero(buf + size - PEFS_NAME_CSUM_SIZE, PEFS_NAME_CSUM_SIZE); csum = pefs_name_checksum(buf, size); memcpy(buf + size - PEFS_NAME_CSUM_SIZE, &csum, PEFS_NAME_CSUM_SIZE); // FIXME - for (int i = 0; i < size; i++) - buf[i] ^= 0xAA + i; + struct rc4_state rc4state; + rc4_init(&rc4state, ptk->ptk_key->pk_name, PEFS_KEY_SIZE); + rc4_crypt(&rc4state, buf, buf, size); r = pefs_name_ntop(buf, size, enc, enc_size); @@ -143,11 +189,16 @@ } int -pefs_name_decrypt(struct pefs_node_key *pnk, const char *enc, size_t enc_len, char *plain, size_t plain_size) +pefs_name_decrypt(struct pefs_key *pk, struct pefs_tkey *ptk, const char *enc, size_t enc_len, char *plain, size_t plain_size) { u_short csum; int r; + if (pk == NULL) { + PEFSDEBUG("!!!! %s: NULL pk\n", __func__); + return (-1); + } + r = pefs_name_pton(enc, enc_len, plain, plain_size); if (r < 0 || r <= PEFS_TWEAK_SIZE + PEFS_NAME_CSUM_SIZE) { PEFSDEBUG("%s: error: r=%d\n", __func__, r); @@ -155,15 +206,20 @@ } // FIXME - for (int i = 0; i < r; i++) - plain[i] ^= 0xAA + i; + struct rc4_state rc4state; + rc4_init(&rc4state, pk->pk_name, PEFS_KEY_SIZE); + rc4_crypt(&rc4state, plain, plain, r); csum = pefs_name_checksum(plain, r); if (csum != 0) { PEFSDEBUG("%s: invalid csum = %d\n", __func__, csum); return (-1); } - memcpy(plain, pnk->pnk_tweak, PEFS_TWEAK_SIZE); + + if (ptk) { + ptk->ptk_key = pk; + memcpy(plain, ptk->ptk_tweak, PEFS_TWEAK_SIZE); + } r -= PEFS_TWEAK_SIZE + PEFS_NAME_CSUM_SIZE; memcpy(plain, plain + PEFS_TWEAK_SIZE, r); ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#5 (text+ko) ==== @@ -186,7 +186,7 @@ * the caller's "spare" reference to created pefs vnode. */ int -pefs_node_get(struct mount *mp, struct vnode *lowervp, struct vnode **vpp) +pefs_node_get(struct mount *mp, struct vnode *lowervp, struct vnode **vpp, struct pefs_tkey *ptk) { struct pefs_node *xp; struct vnode *vp; @@ -221,6 +221,12 @@ return (error); } + if (ptk != NULL) + xp->pn_tkey = *ptk; + + if (!ptk) + PEFSDEBUG("%s: creating node without key: %p: %p->%p\n", __func__, xp, vp, lowervp); + xp->pn_vnode = vp; xp->pn_lowervp = lowervp; vp->v_type = lowervp->v_type; @@ -261,6 +267,28 @@ free(xp, M_PEFSNODE); } +struct pefs_key* +pefs_node_key(struct pefs_node *pn) +{ + if (pn->pn_tkey.ptk_key == NULL) { + PEFSDEBUG("!!!!! %s: key is not set: pn=%p\n", __func__, pn); + // FIXME !!!!! + pn->pn_tkey.ptk_key = SLIST_FIRST(&VFS_TO_PEFS(pn->pn_vnode->v_mount)->pm_keys); + } + return (pn->pn_tkey.ptk_key); + +} + +struct pefs_tkey* +pefs_node_tkey(struct pefs_node *pn) +{ + if (pn->pn_tkey.ptk_key == NULL) { + pefs_node_key(pn); + } + return (&pn->pn_tkey); + +} + struct pefs_chunk* pefs_chunk_create(size_t size) { ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#4 (text+ko) ==== @@ -67,6 +67,9 @@ int isvnunlocked = 0, len; struct nameidata nd, *ndp = &nd; + // FIXME + struct pefs_key *pk; + PEFSDEBUG("pefs_mount(mp = %p)\n", (void *)mp); if (mp->mnt_flag & MNT_ROOTFS) @@ -129,9 +132,18 @@ return (EDEADLK); } + // FIXME + pk = malloc(sizeof(struct pefs_key), M_PEFSBUF, M_WAITOK | M_ZERO); + memset(pk->pk_data, 0xaa, PEFS_KEY_SIZE); + memset(pk->pk_name, 0xbb, PEFS_KEY_SIZE); + xmp = (struct pefs_mount *) malloc(sizeof(struct pefs_mount), M_PEFSMNT, M_WAITOK); /* XXX */ + SLIST_INIT(&xmp->pm_keys); + // FIXME + SLIST_INSERT_HEAD(&xmp->pm_keys, pk, pk_entry); + /* * Save reference to underlying FS */ @@ -141,7 +153,7 @@ * Save reference. Each mount also holds * a reference on the root vnode. */ - error = pefs_node_get(mp, lowerrootvp, &vp); + error = pefs_node_get(mp, lowerrootvp, &vp, NULL); /* * Make sure the node alias worked */ @@ -189,7 +201,7 @@ static int pefs_unmount(struct mount *mp, int mntflags) { - void *mntdata; + struct pefs_mount *pm; int error; int flags = 0; @@ -206,9 +218,11 @@ /* * Finally, throw away the pefs_mount structure */ - mntdata = mp->mnt_data; + pm = VFS_TO_PEFS(mp); mp->mnt_data = 0; - free(mntdata, M_PEFSMNT); + //FIXME + free(SLIST_FIRST(&pm->pm_keys), M_PEFSMNT); + free(pm, M_PEFSMNT); return 0; } @@ -288,7 +302,7 @@ if (error) return (error); - return (pefs_node_get(mp, *vpp, vpp)); + return (pefs_node_get(mp, *vpp, vpp, NULL)); } static int @@ -300,7 +314,7 @@ if (error) return (error); - error = pefs_node_get(mp, *vpp, vpp); + error = pefs_node_get(mp, *vpp, vpp, NULL); printf("pefs_fhtovp: error=%d; vp=%p; v_object=%p\n", error, !error ? *vpp : NULL, !error ? (*vpp)->v_object : NULL); if (error) @@ -332,3 +346,4 @@ }; VFS_SET(pefs_vfsops, pefs, VFCF_LOOPBACK); +MODULE_DEPEND(pefs, rc4, 1, 1, 1); ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#5 (text+ko) ==== @@ -78,6 +78,7 @@ struct pefs_enccn { struct componentname pec_cn; void *pec_buf; + struct pefs_tkey pec_tkey; }; static inline int @@ -95,13 +96,18 @@ } static void -pefs_enccn_init(struct pefs_enccn *pec, char *encname, int encname_len, struct componentname *cnp) +pefs_enccn_init(struct pefs_enccn *pec, struct pefs_tkey *ptk, char *encname, int encname_len, struct componentname *cnp) { MPASS(pec != NULL && cnp != NULL); if (encname_len >= MAXPATHLEN) panic("invalid encrypted name length: %d", encname_len); + if (ptk) { + pec->pec_tkey = *ptk; + } else { + pec->pec_tkey.ptk_key = NULL; + } pec->pec_cn = *cnp; pec->pec_buf = uma_zalloc(namei_zone, M_WAITOK); memcpy(pec->pec_buf, encname, encname_len); @@ -116,20 +122,21 @@ static int pefs_enccn_create(struct pefs_enccn *pec, struct pefs_key *pk, struct componentname *cnp) { - struct pefs_node_key pnk; int r; MPASS(pec != NULL && cnp != NULL); pec->pec_cn = *cnp; if (/* pk == NULL || */ (cnp->cn_flags & ISDOTDOT) || pefs_name_skip(cnp->cn_nameptr, cnp->cn_namelen)) { - pefs_enccn_init(pec, cnp->cn_nameptr, cnp->cn_namelen, cnp); + pefs_enccn_init(pec, NULL, cnp->cn_nameptr, cnp->cn_namelen, cnp); return (0); } + arc4rand(pec->pec_tkey.ptk_tweak, PEFS_TWEAK_SIZE, 0); + pec->pec_tkey.ptk_key = pk; + PEFSDEBUG("%s: pk=%p\n", __func__, pk); pec->pec_buf = uma_zalloc(namei_zone, M_WAITOK); - pnk.pnk_key = pk; - arc4rand(pnk.pnk_tweak, PEFS_TWEAK_SIZE, 0); - r = pefs_name_encrypt(&pnk, cnp->cn_nameptr, cnp->cn_namelen, pec->pec_buf, MAXPATHLEN); + r = pefs_name_encrypt(&pec->pec_tkey, + cnp->cn_nameptr, cnp->cn_namelen, pec->pec_buf, MAXPATHLEN); if (r <= 0) { uma_zfree(namei_zone, pec->pec_buf); return (EIO); @@ -156,9 +163,8 @@ } static struct dirent* -pefs_enccn_lookup_dirent(void *mem, size_t sz, char *name, int namelen, char *buf, size_t buf_sz) +pefs_enccn_lookup_dirent(struct pefs_key *pk, struct pefs_tkey *ptk, void *mem, size_t sz, char *name, int namelen, char *buf, size_t buf_sz) { - struct pefs_node_key pnk; struct dirent *de; int d_namelen; int de_len; @@ -170,7 +176,7 @@ de_len = GENERIC_DIRSIZ(de); if (pefs_name_skip(de->d_name, de->d_namlen)) continue; - d_namelen = pefs_name_decrypt(&pnk, de->d_name, de->d_namlen, buf, buf_sz); + d_namelen = pefs_name_decrypt(pk, ptk, de->d_name, de->d_namlen, buf, buf_sz); PEFSDEBUG("%s =>; res=%d; %.*s --> %.*s\n", __func__, d_namelen, de->d_namlen, de->d_name, d_namelen < 0 ? 0 : d_namelen, buf); @@ -186,9 +192,11 @@ pefs_enccn_lookup(struct pefs_enccn *pec, struct vnode *dvp, struct componentname *cnp) { struct dirent *de; - struct pefs_chunk *pc; struct uio *uio; struct vnode *ldvp = PEFS_LOWERVP(dvp); + struct pefs_chunk *pc; + struct pefs_key *dpn_key; + struct pefs_tkey ptk; char *namebuf; off_t offset; int error, eofflag; @@ -196,34 +204,18 @@ MPASS(pec != NULL && dvp != NULL && cnp != NULL); if ((cnp->cn_flags & ISDOTDOT) || pefs_name_skip(cnp->cn_nameptr, cnp->cn_namelen)) { - pefs_enccn_init(pec, cnp->cn_nameptr, cnp->cn_namelen, cnp); + pefs_enccn_init(pec, NULL, cnp->cn_nameptr, cnp->cn_namelen, cnp); return (0); } - const char *op; - switch (cnp->cn_nameiop & OPMASK) { - case LOOKUP: - op = "LOOKUP"; - break; - case CREATE: - op = "CREATE"; - break; - case DELETE: - op = "DELETE"; - break; - case RENAME: - op = "RENAME"; - break; - default: - op = NULL; - } - PEFSDEBUG("XXX pefs_enccn_lookup: name=%.*s op=%s\n", (int) cnp->cn_namelen, cnp->cn_nameptr, op); + PEFSDEBUG("pefs_enccn_lookup: name=%.*s op=%d\n", (int) cnp->cn_namelen, cnp->cn_nameptr, (int) cnp->cn_nameiop); pc = pefs_chunk_create(PAGE_SIZE); namebuf = malloc(MAXNAMLEN + 1, M_PEFSBUF, M_WAITOK); offset = 0; eofflag = 0; de = NULL; + dpn_key = pefs_node_key(VP_TO_PN(dvp)); while (!eofflag && de == NULL) { long arg = 0; @@ -236,7 +228,6 @@ return (error); } - printf("%s: size = %d\n", __func__, pc->pc_size - uio->uio_resid); pefs_chunk_shrink(pc, pc->pc_size - uio->uio_resid); while (1) { size_t size; @@ -245,7 +236,7 @@ mem = pefs_chunk_get(pc, &size, &arg); if (mem == NULL) break; - de = pefs_enccn_lookup_dirent(mem, size, + de = pefs_enccn_lookup_dirent(dpn_key, &ptk, mem, size, cnp->cn_nameptr, cnp->cn_namelen, namebuf, MAXNAMLEN + 1); if (de != NULL) @@ -256,7 +247,7 @@ if (de != NULL) { PEFSDEBUG("%s: dirent found: %.*s\n", __func__, de->d_namlen, de->d_name); - pefs_enccn_init(pec, de->d_name, de->d_namlen, cnp); + pefs_enccn_init(pec, &ptk, de->d_name, de->d_namlen, cnp); } pefs_chunk_free(pc); @@ -274,8 +265,9 @@ error = pefs_enccn_lookup(pec, dvp, cnp); PEFSDEBUG("%s: lookup error = %d\n", __func__, error); - if (error == ENOENT) - error = pefs_enccn_create(pec, NULL, cnp); + if (error == ENOENT) { + error = pefs_enccn_create(pec, pefs_node_key(VP_TO_PN(dvp)), cnp); + } PEFSDEBUG("%s: returning = %d\n", __func__, error); return (error); @@ -306,7 +298,7 @@ * problems on rmdir'ing mount points and renaming?) */ static int -pefs_bypass(struct vop_generic_args *ap, struct pefs_enccn *enccn) +pefs_bypass(struct vop_generic_args *ap, struct pefs_tkey *ptk) { struct vnode **this_vp_p; int error; @@ -400,7 +392,7 @@ if (descp->vdesc_vpp_offset != VDESC_NO_OFFSET && !(descp->vdesc_flags & VDESC_NOMAP_VPP) && !error) { - if (enccn == NULL) { + if (ptk == NULL) { printf("PANIC: vop_bypass: map of outgoing vnode without encrypted name: %s", descp->vdesc_name); // panic("vop_bypass: map of outgoing vnode without encrypted name: %s", descp->vdesc_name); } @@ -415,7 +407,7 @@ vppp = VOPARG_OFFSETTO(struct vnode***, descp->vdesc_vpp_offset,ap); if (*vppp) - error = pefs_node_get(old_vps[0]->v_mount, **vppp, *vppp); + error = pefs_node_get(old_vps[0]->v_mount, **vppp, *vppp, ptk); } out: @@ -478,7 +470,7 @@ VREF(dvp); vrele(lvp); } else { - error = pefs_node_get(dvp->v_mount, lvp, &vp); + error = pefs_node_get(dvp->v_mount, lvp, &vp, &enccn.pec_tkey); if (error) { vput(lvp); } else { @@ -974,34 +966,30 @@ } static void -pefs_readdir_decrypt(void *mem, size_t sz) +pefs_readdir_decrypt(struct pefs_key *pk, void *mem, size_t sz, char *buf, size_t buf_sz) { - struct pefs_node_key pnk; struct dirent *de; - char *d_name; int d_namelen; int de_len; - d_name = malloc(MAXNAMLEN + 1, M_PEFSBUF, M_WAITOK); for (de = (struct dirent*) mem; sz > 0; sz -= de_len, de = (struct dirent *)(((caddr_t)de) + de_len)) { de_len = GENERIC_DIRSIZ(de); if (pefs_name_skip(de->d_name, de->d_namlen)) continue; - d_namelen = pefs_name_decrypt(&pnk, de->d_name, de->d_namlen, d_name, MAXPATHLEN + 1); + d_namelen = pefs_name_decrypt(pk, NULL, de->d_name, de->d_namlen, buf, buf_sz); PEFSDEBUG("%s =>; res=%d; %.*s --> %.*s\n", __func__, d_namelen, de->d_namlen, de->d_name, - d_namelen < 0 ? 0 : d_namelen, d_name); + d_namelen < 0 ? 0 : d_namelen, buf); if (d_namelen > 0) { /* * Do not change d_reclen */ - strlcpy(de->d_name, d_name, de->d_namlen + 1); + strlcpy(de->d_name, buf, de->d_namlen + 1); de->d_namlen = d_namelen; } } - free(d_name, M_PEFSBUF); } static int @@ -1009,7 +997,10 @@ { struct uio *uio = ap->a_uio; struct uio *puio; + struct pefs_node *pn = VP_TO_PN(ap->a_vp); + struct pefs_key *pn_key; struct pefs_chunk *pc; + char *buf; int o_resid; int error; @@ -1019,7 +1010,9 @@ ap->a_uio = puio; error = pefs_bypass((struct vop_generic_args *)ap, NULL); ap->a_uio = uio; + pn_key = pefs_node_key(pn); PEFSDEBUG("%s => %d; ncookies=%d\n", __func__, error, ap->a_ncookies ? *ap->a_ncookies : -1); + buf = malloc(MAXNAMLEN + 1, M_PEFSBUF, M_WAITOK); if (!error) { long arg = 0; char *mem; @@ -1032,12 +1025,13 @@ if (mem == NULL) break; printf("%s: convert mem=%p; size=%d\n", __func__, mem, size); - pefs_readdir_decrypt(mem, size); + pefs_readdir_decrypt(pn_key, mem, size, buf, MAXNAMLEN + 1); } pefs_chunk_copy(pc, 0, uio); uio->uio_offset = puio->uio_offset; uio->uio_resid = puio->uio_resid; } + free(buf, M_PEFSBUF); pefs_chunk_free(pc); return (error); } @@ -1058,7 +1052,7 @@ } ap->a_cnp = &enccn.pec_cn; - error = pefs_bypass((struct vop_generic_args *)ap, &enccn); + error = pefs_bypass((struct vop_generic_args *)ap, &enccn.pec_tkey); ap->a_cnp = cnp; pefs_enccn_free(&enccn); @@ -1114,7 +1108,7 @@ PEFSDEBUG("%s: cn_nameiop=%lx, cn_nameptr=%.*s\n", __func__, cnp->cn_nameiop, (int) cnp->cn_namelen, cnp->cn_nameptr); ap->a_cnp = &enccn.pec_cn; - error = pefs_bypass((struct vop_generic_args *)ap, &enccn); + error = pefs_bypass((struct vop_generic_args *)ap, &enccn.pec_tkey); ap->a_cnp = cnp; pefs_enccn_free(&enccn); @@ -1188,30 +1182,30 @@ size_t target_len; int error; + error = pefs_enccn_lookup_create(&enccn, dvp, cnp); + if (error) { + return (error); + } + target_len = strlen(ap->a_target); penc_target_len = PEFS_NAME_NTOP_SIZE(target_len) + 1; enc_target = malloc(target_len, M_PEFSBUF, M_WAITOK); penc_target = malloc(penc_target_len, M_PEFSBUF, M_WAITOK); memcpy(enc_target, target, target_len); - pefs_data_encrypt_buf(NULL, 0, enc_target, target_len); + pefs_data_encrypt_buf(&enccn.pec_tkey, 0, enc_target, target_len); pefs_name_ntop(enc_target, target_len, penc_target, penc_target_len); free(enc_target, M_PEFSBUF); enc_target = NULL; - error = pefs_enccn_lookup_create(&enccn, dvp, cnp); - if (error) { - return (error); - } - PEFSDEBUG("%s: %.*s; target=%s penc_target=%s\n", __func__, (int) cnp->cn_namelen, cnp->cn_nameptr, target, penc_target); ldvp = PEFS_LOWERVP(ap->a_dvp); error = VOP_SYMLINK(ldvp, &lvpp, &enccn.pec_cn, ap->a_vap, penc_target); if (!error) { - error = pefs_node_get(dvp->v_mount, lvpp, &vpp); + error = pefs_node_get(dvp->v_mount, lvpp, &vpp, &enccn.pec_tkey); if (error) vput(lvpp); else @@ -1232,6 +1226,7 @@ struct uio *uio = ap->a_uio; struct uio *puio; struct pefs_chunk *pc; + struct pefs_node *pn = VP_TO_PN(vp); off_t o_offset; int o_resid; int error; @@ -1261,7 +1256,7 @@ if (target_len < 0) { error = EIO; } else { - pefs_data_decrypt_buf(NULL, 0, target, target_len); + pefs_data_decrypt_buf(pefs_node_tkey(pn), 0, target, target_len); PEFSDEBUG("%s: target=%.*s\n", __func__, target_len, target); uiomove(target, target_len, uio); } @@ -1288,7 +1283,7 @@ PEFSDEBUG("%s: cn_nameiop=%lx, cn_nameptr=%.*s\n", __func__, cnp->cn_nameiop, (int) cnp->cn_namelen, cnp->cn_nameptr); ap->a_cnp = &enccn.pec_cn; - error = pefs_bypass((struct vop_generic_args *)ap, &enccn); + error = pefs_bypass((struct vop_generic_args *)ap, &enccn.pec_tkey); ap->a_cnp = cnp; pefs_enccn_free(&enccn); @@ -1350,7 +1345,7 @@ int done = pc->pc_size - puio->uio_resid; if (done > skip_begin) { pefs_chunk_shrink(pc, done); - pefs_data_decrypt(NULL, o_offset - skip_begin, pc); + pefs_data_decrypt(pefs_node_tkey(VP_TO_PN(vp)), o_offset - skip_begin, pc); pefs_chunk_copy(pc, skip_begin, uio); } } @@ -1367,6 +1362,7 @@ struct uio *uio = ap->a_uio; struct uio *puio; struct pefs_chunk *pc; + struct pefs_node *pn = VP_TO_PN(vp); struct vnode *lvp; size_t skip_begin, skip_end; off_t o_offset; @@ -1413,7 +1409,7 @@ done = PEFS_BLOCK - puio->uio_resid; PEFSDEBUG("%s: read skip_begin: puio_resid=%d; puio done=%d\n", __func__, puio->uio_resid, done); if (done > 0) { - pefs_data_decrypt_buf(NULL, o_offset - skip_begin, + pefs_data_decrypt_buf(pefs_node_tkey(pn), o_offset - skip_begin, (char *)puio->uio_iov[0].iov_base - done, done); } if (puio->uio_resid) { @@ -1442,7 +1438,7 @@ done = PEFS_BLOCK - puio->uio_resid; PEFSDEBUG("%s: read skip_end: puio_resid=%d\n", __func__, puio->uio_resid); if (done > 0) { - pefs_data_decrypt_buf(NULL, puio_offset, + pefs_data_decrypt_buf(pefs_node_tkey(pn), puio_offset, (char *)puio->uio_iov[0].iov_base - done, done); } } @@ -1460,7 +1456,7 @@ pefs_chunk_crop(pc, 0, va.va_size - o_offset - o_resid); } - pefs_data_encrypt(NULL, o_offset - skip_begin, pc); + pefs_data_encrypt(pefs_node_tkey(pn), o_offset - skip_begin, pc); puio = pefs_chunk_uio(pc, o_offset - skip_begin, uio->uio_rw); PEFSDEBUG("%s: puio_offset=%ju; o_offset=%ju; puio_resid=%d; o_resid=%d; pc_size=%d\n", __func__, (intmax_t) puio->uio_offset, (intmax_t) o_offset,