Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Oct 2009 15:51:43 GMT
From:      Gleb Kurtsou <gk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 169618 for review
Message-ID:  <200910201551.n9KFphrm068418@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=169618

Change 169618 by gk@gk_h1 on 2009/10/20 15:51:26

	enable dircache for pefs_enccn_get
	move salsa20 into crypto module
	move hmac implementation from g_eli to crypto/hmac/hmac_sha512
	add passphrase length argument to g_eli pkcs5v2_genkey

Affected files ...

.. //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#6 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#9 edit
.. //depot/projects/soc2009/gk_pefs/sys/crypto/hmac/hmac_sha512.c#1 add
.. //depot/projects/soc2009/gk_pefs/sys/crypto/hmac/hmac_sha512.h#1 add
.. //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.c#4 edit
.. //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.h#3 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#17 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#14 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#25 edit

Differences ...

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#6 (text+ko) ====

@@ -2,13 +2,13 @@
 
 MOUNT=	${.CURDIR}/../mount
 SYS=	${.CURDIR}/../../sys
-.PATH:	${MOUNT} ${SYS}/geom/eli ${SYS}/crypto/sha2
+.PATH:	${MOUNT} ${SYS}/geom/eli ${SYS}/crypto/hmac ${SYS}/crypto/sha2
 
 PROG=	pefs
 SRCS=	pefs_ctl.c pefs_key.c pefs_keychain.c pefs_mount.c
 SRCS+=	getmntopts.c
-SRCS+=	g_eli_crypto.c sha2.c
-SRCS+=	pkcs5v2-x.c # Should patch original pkcs5v2.c instead
+SRCS+=	hmac_sha512.c sha2.c
+SRCS+=	pkcs5v2.c
 
 LINKS=	${BINDIR}/pefs ${BINDIR}/mount_pefs
 NO_MAN=

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#9 (text+ko) ====

@@ -28,6 +28,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#include <sys/errno.h>
 #include <assert.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -39,13 +40,13 @@
 #include <fcntl.h>
 #include <readpassphrase.h>
 
-#include <geom/eli/g_eli.h>
+#include <crypto/hmac/hmac_sha512.h>
 #include <fs/pefs/pefs.h>
+#include <geom/eli/pkcs5v2.h>
 
 #include <openssl/evp.h>
 
 #include "pefs_ctl.h"
-#include "pkcs5v2-x.h"
 
 #define PEFS_KEY_PROMPT_DEFAULT			"passphrase"
 
@@ -126,7 +127,7 @@
 pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify,
     struct pefs_keyparam *kp)
 {
-	struct hmac_ctx ctx;
+	struct hmac_sha512_ctx ctx;
 	char promptbuf[64], buf[BUFSIZ], buf2[BUFSIZ], *p;
 	ssize_t done;
 	int fd, i;
@@ -143,7 +144,7 @@
 		}
 	}
 
-	g_eli_crypto_hmac_init(&ctx, NULL, 0);
+	hmac_sha512_init(&ctx, NULL, 0);
 
 	if (kp->kp_keyfile != NULL && kp->kp_keyfile[0] == '\0')
 		kp->kp_keyfile = NULL;
@@ -161,7 +162,7 @@
 				    kp->kp_keyfile);
 		}
 		while ((done = read(fd, buf, sizeof(buf))) > 0)
-			g_eli_crypto_hmac_update(&ctx, buf, done);
+			hmac_sha512_update(&ctx, buf, done);
 		bzero(buf, sizeof(buf));
 		if (done == -1)
 			err(EX_IOERR, "cannot read keyfile %s", kp->kp_keyfile);
@@ -192,20 +193,20 @@
 		}
 		bzero(buf2, sizeof(buf2));
 		if (kp->kp_iterations == 0) {
-			g_eli_crypto_hmac_update(&ctx, buf, strlen(buf));
+			hmac_sha512_update(&ctx, buf, strlen(buf));
 		} else {
 			pkcs5v2_genkey(xk->pxk_key, PEFS_KEY_SIZE, buf, 0, buf,
 			    strlen(buf), kp->kp_iterations);
-			g_eli_crypto_hmac_update(&ctx, xk->pxk_key,
+			hmac_sha512_update(&ctx, xk->pxk_key,
 			    PEFS_KEY_SIZE);
 		}
 		bzero(buf, sizeof(buf));
 	}
-	g_eli_crypto_hmac_final(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
+	hmac_sha512_final(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
 
-	g_eli_crypto_hmac_init(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
-	g_eli_crypto_hmac_update(&ctx, "<KEY ID>", 8);
-	g_eli_crypto_hmac_final(&ctx, xk->pxk_keyid, PEFS_KEYID_SIZE);
+	hmac_sha512_init(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx, "<KEY ID>", 8);
+	hmac_sha512_final(&ctx, xk->pxk_keyid, PEFS_KEYID_SIZE);
 
 	return (0);
 }
@@ -216,7 +217,7 @@
 {
 	const int keysize = 128 / 8;
 	const int datasize = sizeof(struct pefs_xkeyenc) - PEFS_KEYENC_MAC_SIZE;
-	struct hmac_ctx hmac_ctx;
+	struct hmac_sha512_ctx hmac_ctx;
 	u_char *data = (u_char *) xe;
 	EVP_CIPHER_CTX ctx;
 	u_char key[keysize];
@@ -226,10 +227,10 @@
 	pkcs5v2_genkey(key, keysize, xk_parent->pxk_keyid, PEFS_KEYID_SIZE,
 	    xk_parent->pxk_key, PEFS_KEY_SIZE, PEFS_KEYENC_ITERATIONS);
 
-	g_eli_crypto_hmac_init(&hmac_ctx, key, keysize);
+	hmac_sha512_init(&hmac_ctx, key, keysize);
 	if (!enc) {
-		g_eli_crypto_hmac_update(&hmac_ctx, data, datasize);
-		g_eli_crypto_hmac_final(&hmac_ctx, mac, PEFS_KEYENC_MAC_SIZE);
+		hmac_sha512_update(&hmac_ctx, data, datasize);
+		hmac_sha512_final(&hmac_ctx, mac, PEFS_KEYENC_MAC_SIZE);
 		bzero(&hmac_ctx, sizeof(hmac_ctx));
 		if (memcmp(mac, xe->mac, PEFS_KEYENC_MAC_SIZE) != 0)
 			return (-1);
@@ -257,8 +258,8 @@
 	EVP_CIPHER_CTX_cleanup(&ctx);
 
 	if (enc) {
-		g_eli_crypto_hmac_update(&hmac_ctx, data, datasize);
-		g_eli_crypto_hmac_final(&hmac_ctx, xe->mac,
+		hmac_sha512_update(&hmac_ctx, data, datasize);
+		hmac_sha512_final(&hmac_ctx, xe->mac,
 		    PEFS_KEYENC_MAC_SIZE);
 		bzero(&hmac_ctx, sizeof(hmac_ctx));
 	}

==== //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.c#4 (text+ko) ====

@@ -192,7 +192,8 @@
 		if (__predict_false(!x->j[8])) {
 			x->j[9] = PLUSONE(x->j[9]);
 			/*
-			 * stopping at 2^70 bytes per nonce is user's responsibility
+			 * stopping at 2^70 bytes per nonce is user's
+			 * responsibility
 			 */
 		}
 

==== //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.h#3 (text+ko) ====

@@ -4,8 +4,8 @@
  * Public domain.
  */
 
-#ifndef _SALSA20_H
-#define _SALSA20_H
+#ifndef _SYS_CRYPTO_SALSA20_H
+#define _SYS_CRYPTO_SALSA20_H
 
 #define SALSA20_MAXKEYSIZE		256
 #define SALSA20_IVSIZE			64

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#17 (text+ko) ====

@@ -41,11 +41,11 @@
 #include <vm/uma.h>
 
 #include <crypto/camellia/camellia.h>
+#include <crypto/hmac/hmac_sha512.h>
 #include <crypto/rijndael/rijndael.h>
 #include <crypto/salsa20/salsa20.h>
 
 #include <fs/pefs/pefs.h>
-#include <fs/pefs/pefs_hmac.h>
 #include <fs/pefs/vmac.h>
 
 #define PEFS_CTR_BLOCK_SIZE		16
@@ -82,7 +82,7 @@
 		camellia_ctx pctx_camellia;
 		rijndael_ctx pctx_aes;
 		salsa20_ctx pctx_salsa;
-		struct pefs_hmac_ctx pctx_hmac;
+		struct hmac_sha512_ctx pctx_hmac;
 		vmac_ctx_t pctx_vmac;
 	} o;
 };
@@ -193,30 +193,30 @@
 
 	idx = 1;
 	bzero(key, PEFS_KEY_SIZE);
-	pefs_hmac_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, magic_ctxinfo_data_key,
+	hmac_sha512_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, magic_ctxinfo_data_key,
 	    PEFS_TWEAK_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
-	pefs_hmac_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
+	hmac_sha512_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
 	pk->pk_alg->pa_keysetup(pk->pk_data_ctx, key, pk->pk_keybits);
 
 	idx = 2;
-	pefs_hmac_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, magic_ctxinfo_name_key,
+	hmac_sha512_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, magic_ctxinfo_name_key,
 	    PEFS_TWEAK_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
-	pefs_hmac_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
+	hmac_sha512_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
 	pefs_aes_keysetup(pk->pk_name_ctx, key, 128);
 
 	idx = 3;
-	pefs_hmac_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, magic_ctxinfo_name_key,
+	hmac_sha512_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, magic_ctxinfo_name_key,
 	    PEFS_TWEAK_SIZE);
-	pefs_hmac_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
-	pefs_hmac_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
+	hmac_sha512_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
 	vmac_set_key(key, &pk->pk_name_csum_ctx->o.pctx_vmac);
 
 	pefs_ctx_free(ctx);

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#14 (text+ko) ====

@@ -324,5 +324,4 @@
 
 VFS_SET(pefs_vfsops, pefs, VFCF_LOOPBACK);
 MODULE_DEPEND(pefs, crypto, 1, 1, 1);
-MODULE_DEPEND(pefs, salsa20, 1, 1, 1);
 

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#25 (text+ko) ====

@@ -112,6 +112,18 @@
 	return (va.va_gen);
 }
 
+static inline int
+pefs_tkey_cmp(struct pefs_tkey *a, struct pefs_tkey *b)
+{
+	int r;
+
+	r = (intptr_t)a->ptk_key - (intptr_t)b->ptk_key;
+	if (r == 0)
+		r = memcmp(a->ptk_tweak, b->ptk_tweak, PEFS_TWEAK_SIZE);
+
+	return (r);
+}
+
 static struct pefs_dircache_entry *
 pefs_cache_dirent(struct pefs_dircache *pd, struct dirent *de,
     struct pefs_ctx *ctx, struct pefs_key *pk)
@@ -349,10 +361,12 @@
 }
 
 static int
-pefs_enccn_get(struct pefs_enccn *pec, struct vnode *vp,
+pefs_enccn_get(struct pefs_enccn *pec, struct vnode *dvp, struct vnode *vp,
     struct componentname *cnp)
 {
+	struct pefs_node *dpn = VP_TO_PN(dvp);
 	struct pefs_node *pn = VP_TO_PN(vp);
+	struct pefs_dircache_entry *cache;
 	int error;
 
 	if ((pn->pn_flags & PN_HASKEY) == 0) {
@@ -361,6 +375,21 @@
 		return (0);
 	}
 
+	if (pefs_dircache_enable) {
+		pefs_dircache_lock(dpn->pn_dircache);
+		/* Do not check if cache valid check keys are equal instead */
+		cache = pefs_dircache_lookup(dpn->pn_dircache,
+		    cnp->cn_nameptr, cnp->cn_namelen);
+		if (cache != NULL &&
+		    pefs_tkey_cmp(&cache->pde_tkey, &pn->pn_tkey) == 0) {
+			pefs_enccn_set(pec, &pn->pn_tkey,
+			    cache->pde_encname, cache->pde_encnamelen, cnp);
+			pefs_dircache_unlock(dpn->pn_dircache);
+			return (0);
+		}
+		pefs_dircache_unlock(dpn->pn_dircache);
+	}
+
 	error = pefs_enccn_create(pec, pn->pn_tkey.ptk_key,
 	    pn->pn_tkey.ptk_tweak, cnp);
 	PEFSDEBUG("pefs_enccn_get: create: %s -> %s\n",
@@ -872,7 +901,7 @@
 		goto bad;
 	}
 
-	error = pefs_enccn_get(&fenccn, fvp, fcnp);
+	error = pefs_enccn_get(&fenccn, fdvp, fvp, fcnp);
 	if (error != 0) {
 		goto bad;
 	}
@@ -903,7 +932,7 @@
 			 *   After rename fvp will contain invalid key/tweak
 			 *   because it is rename of fvp.
 			 */
-			error = pefs_enccn_get(&tenccn, tvp, tcnp);
+			error = pefs_enccn_get(&tenccn, tdvp, tvp, tcnp);
 		} else if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
 			error = ENOTDIR;
 		} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
@@ -946,13 +975,13 @@
 		if (tvp != NULL && tvp->v_type != VDIR) {
 			/*
 			 * Remove old file. Double rename is not performed to
-			 * save data in case of error
+			 * prevent data loss in case of error
 			 */
 			pefs_enccn_free(&tenccn);
 			ASSERT_VOP_UNLOCKED(tdvp, "pefs_rename");
 			ASSERT_VOP_LOCKED(tvp, "pefs_rename");
 			vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);
-			error = pefs_enccn_get(&tenccn, tvp, tcnp);
+			error = pefs_enccn_get(&tenccn, tdvp, tvp, tcnp);
 			if (error == 0) {
 				error = VOP_REMOVE(ltdvp, PEFS_LOWERVP(tvp),
 				    &tenccn.pec_cn);
@@ -1447,7 +1476,7 @@
 	if (pefs_no_keys(vp))
 		return (EROFS);
 	pefs_enccn_init(&enccn);
-	error = pefs_enccn_get(&enccn, vp, cnp);
+	error = pefs_enccn_get(&enccn, dvp, vp, cnp);
 	if (error != 0) {
 		PEFSDEBUG("pefs_rmdir: pefs_enccn_get failed: %d\n", error);
 		return (error);
@@ -1511,7 +1540,7 @@
 	if (pefs_no_keys(dvp))
 		return (EROFS);
 	pefs_enccn_init(&enccn);
-	error = pefs_enccn_get(&enccn, vp, cnp);
+	error = pefs_enccn_get(&enccn, dvp, vp, cnp);
 	if (error != 0) {
 		return (error);
 	}
@@ -2029,7 +2058,7 @@
 
 	error = VOP_ACCESS(vp, VWRITE, cred, td);
 	if (error == 0)
-		error = pefs_enccn_get(&fenccn, vp, &cn);
+		error = pefs_enccn_get(&fenccn, dvp, vp, &cn);
 	if (error != 0) {
 		VOP_UNLOCK(vp, 0);
 		VOP_UNLOCK(dvp, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910201551.n9KFphrm068418>