PERFORCE change 165570 for review

Gleb Kurtsou gk at FreeBSD.org
Fri Jul 3 17:06:04 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=165570

Change 165570 by gk at 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 <sys/mount.h>
 #include <sys/vnode.h>
 
+#include <crypto/rc4/rc4.h>
+
 #include <fs/pefs/pefs.h>
 
-
+#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,


More information about the p4-projects mailing list