Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Sep 2009 19:14:26 GMT
From:      Gleb Kurtsou <gk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 168984 for review
Message-ID:  <200909281914.n8SJEQBx029883@repoman.freebsd.org>

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

Change 168984 by gk@gk_h1 on 2009/09/28 19:13:43

	change keyid generation
	authenticate keys in db (with hmac)
	use key as IV for encrypting keys in db (CFB mode is used)
	support chains with single key
	add invalid algorithm constant
	getopt and usage fixes
	wrap long lines. license cleanup

Affected files ...

.. //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#4 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#8 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#8 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#7 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#5 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_mount.c#4 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pkcs5v2-x.c#1 add
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pkcs5v2-x.h#1 add
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#12 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#12 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_hmac.c#2 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#12 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#11 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#17 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_xbase64.c#5 edit

Differences ...

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

@@ -7,7 +7,8 @@
 PROG=	pefs
 SRCS=	pefs_ctl.c pefs_key.c pefs_keychain.c pefs_mount.c
 SRCS+=	getmntopts.c
-SRCS+=	g_eli_crypto.c pkcs5v2.c sha2.c
+SRCS+=	g_eli_crypto.c sha2.c
+SRCS+=	pkcs5v2-x.c # Should patch original pkcs5v2.c instead
 
 LINKS=	${BINDIR}/pefs ${BINDIR}/mount_pefs
 NO_MAN=

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

@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/ioccom.h>
 #include <sys/module.h>
 #include <sys/mount.h>
 
@@ -65,7 +66,8 @@
 static int	pefs_showchain(int argc, char *argv[]);
 
 typedef int (*command_func_t)(int argc, char **argv);
-typedef int (*keyop_func_t)(struct pefs_keychain_head *kch, int fd);
+typedef int (*keyop_func_t)(struct pefs_keychain_head *kch, int fd,
+    int verbose);
 
 struct command {
 	const char *name;
@@ -162,7 +164,8 @@
 static inline void
 pefs_key_show(struct pefs_xkey *xk, int ind)
 {
-	printf("\t%-4d %016jx %s\n", ind, pefs_keyid_as_int(xk->pxk_keyid), pefs_alg_name(xk));
+	printf("\t%-4d %016jx %s\n", ind, pefs_keyid_as_int(xk->pxk_keyid),
+	    pefs_alg_name(xk));
 }
 
 static int
@@ -173,9 +176,10 @@
 	struct pefs_keyparam kp;
 	int error, fd, i;
 	int chain = PEFS_KEYCHAIN_IGNORE_MISSING;
+	int verbose = 0;
 
 	pefs_keyparam_init(&kp);
-	while ((i = getopt(argc, argv, "pcCa:i:k:")) != -1)
+	while ((i = getopt(argc, argv, "cCpva:i:k:")) != -1)
 		switch(i) {
 		case 'a':
 			kp.kp_alg = optarg;
@@ -192,13 +196,17 @@
 		case 'i':
 			kp.kp_iterations = atoi(optarg);
 			if (kp.kp_iterations <= 0) {
-				warnx("invalid iterations argument: %s", optarg);
+				warnx("invalid iterations argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
 		case 'k':
 			kp.kp_keyfile = optarg;
 			break;
+		case 'v':
+			verbose = 1;
+			break;
 		default:
 			pefs_usage();
 		}
@@ -209,6 +217,8 @@
 		bzero(&k, sizeof(k));
 		pefs_usage();
 	}
+	if (pefs_getfsroot(argv[0], NULL, 0) != 0)
+		return (EX_DATAERR);
 
 	error = pefs_key_get(&k, NULL, 0, &kp);
 	if (error != 0)
@@ -222,7 +232,7 @@
 	if (fd == -1)
 		return (EX_IOERR);
 
-	error = func(&kch, fd);
+	error = func(&kch, fd, verbose);
 
 	pefs_keychain_free(&kch);
 
@@ -232,7 +242,7 @@
 }
 
 static int
-pefs_addkey_op(struct pefs_keychain_head *kch, int fd)
+pefs_addkey_op(struct pefs_keychain_head *kch, int fd, int verbose)
 {
 	struct pefs_keychain *kc;
 
@@ -240,6 +250,9 @@
 		if (ioctl(fd, PEFS_ADDKEY, &kc->kc_key) == -1) {
 			warn("cannot add key");
 			return (-1);
+		} else if (verbose) {
+			printf("Key added: %016jx\n",
+			    pefs_keyid_as_int(kc->kc_key.pxk_keyid));
 		}
 	}
 
@@ -247,13 +260,16 @@
 }
 
 static int
-pefs_delkey_op(struct pefs_keychain_head *kch, int fd)
+pefs_delkey_op(struct pefs_keychain_head *kch, int fd, int verbose)
 {
 	struct pefs_keychain *kc;
 
 	TAILQ_FOREACH(kc, kch, kc_entry) {
 		if (ioctl(fd, PEFS_DELKEY, &kc->kc_key) == -1) {
 			warn("cannot delete key");
+		} else if (verbose) {
+			printf("Key deleted: %016jx\n",
+			    pefs_keyid_as_int(kc->kc_key.pxk_keyid));
 		}
 	}
 
@@ -284,7 +300,7 @@
 	int chain = PEFS_KEYCHAIN_IGNORE_MISSING;
 
 	pefs_keyparam_init(&kp);
-	while ((i = getopt(argc, argv, "vxpcCa:i:k:")) != -1)
+	while ((i = getopt(argc, argv, "cCpvxa:i:k:")) != -1)
 		switch(i) {
 		case 'v':
 			verbose = 1;
@@ -307,7 +323,8 @@
 		case 'i':
 			kp.kp_iterations = atoi(optarg);
 			if (kp.kp_iterations <= 0) {
-				warnx("invalid iterations argument: %s", optarg);
+				warnx("invalid iterations argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
@@ -333,7 +350,8 @@
 	}
 
 	/* only check filesystem type */
-	pefs_getfsroot(argv[0], NULL, 0);
+	if (pefs_getfsroot(argv[0], NULL, 0) != 0)
+		return (EX_DATAERR);
 
 	error = pefs_key_get(&k, NULL, 0, &kp);
 	if (error != 0)
@@ -475,32 +493,46 @@
 	} p[2];
 	struct pefs_xkey *k1 = &p[0].k, *k2 = &p[1].k;
 	int verbose = 0;
-	int error, i;
+	int zerochainedkey = 0, optchainedkey = 0;
+	int error, i, fd;
 
 	pefs_keyparam_init(&p[0].kp);
 	pefs_keyparam_init(&p[1].kp);
-	while ((i = getopt(argc, argv, "vpPa:A:i:I:k:K:")) != -1)
+	while ((i = getopt(argc, argv, "pPvZa:A:i:I:k:K:")) != -1)
 		switch(i) {
 		case 'v':
 			verbose = 1;
 			break;
+		case 'Z':
+			zerochainedkey = 1;
+			break;
 		case 'a':
 		case 'A':
+			if (isupper(i))
+				optchainedkey = i;
 			p[isupper(i) ? 1 : 0].kp.kp_alg = optarg;
 			break;
 		case 'p':
 		case 'P':
+			if (isupper(i))
+				optchainedkey = i;
 			p[isupper(i) ? 1 : 0].kp.kp_nopassphrase = 1;
 			break;
 		case 'i':
 		case 'I':
-			if ((p[isupper(i) ? 1 : 0].kp.kp_iterations = atoi(optarg)) <= 0) {
-				warnx("invalid iterations argument: %s", optarg);
+			if (isupper(i))
+				optchainedkey = i;
+			if ((p[isupper(i) ? 1 : 0].kp.kp_iterations =
+			    atoi(optarg)) <= 0) {
+				warnx("invalid iterations argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
 		case 'k':
 		case 'K':
+			if (isupper(i))
+				optchainedkey = i;
 			p[isupper(i) ? 1 : 0].kp.kp_keyfile = optarg;
 			break;
 		default:
@@ -509,6 +541,9 @@
 	argc -= optind;
 	argv += optind;
 
+	if (optchainedkey && zerochainedkey)
+		errx(EX_USAGE, "invalid argument combination: -Z -%c",
+		    optchainedkey);
 
 	if (!checkargs_fs(argc, argv)) {
 		bzero(p, sizeof(p));
@@ -520,6 +555,23 @@
 		bzero(p, sizeof(p));
 		return (error);
 	}
+
+	if (zerochainedkey) {
+		fd = open(PATH_DEVRANDOM, O_RDONLY);
+		if (fd == -1)
+			err(EX_IOERR, "%s", PATH_DEVRANDOM);
+		read(fd, k2, sizeof(struct pefs_keychain));
+		close(fd);
+		k2->pxk_alg = PEFS_ALG_INVALID;
+		error = pefs_keychain_set(argv[0], k1, k2);
+		if (error)
+			return (EX_DATAERR);
+		if (verbose) {
+		}
+
+		return (0);
+	}
+
 	error = pefs_key_get(k2, "chained key passphrase", 1, &p[1].kp);
 	if (error != 0) {
 		bzero(p, sizeof(p));
@@ -528,7 +580,8 @@
 
 	pefs_keychain_get(&kch, argv[0], PEFS_KEYCHAIN_IGNORE_MISSING, k1);
 	TAILQ_FOREACH(kc, &kch, kc_entry) {
-		if (memcmp(k2->pxk_keyid, kc->kc_key.pxk_keyid, PEFS_KEYID_SIZE) == 0) {
+		if (memcmp(k2->pxk_keyid, kc->kc_key.pxk_keyid,
+		    PEFS_KEYID_SIZE) == 0) {
 			pefs_keychain_free(&kch);
 			bzero(k1->pxk_key, PEFS_KEY_SIZE);
 			bzero(k2->pxk_key, PEFS_KEY_SIZE);
@@ -543,7 +596,8 @@
 		bzero(k2->pxk_key, PEFS_KEY_SIZE);
 		warnx("key chain for parent key is already set: %016jx -> %016jx",
 		    pefs_keyid_as_int(kc->kc_key.pxk_keyid),
-		    pefs_keyid_as_int(TAILQ_NEXT(kc, kc_entry)->kc_key.pxk_keyid));
+		    pefs_keyid_as_int(
+			TAILQ_NEXT(kc, kc_entry)->kc_key.pxk_keyid));
 		pefs_keychain_free(&kch);
 		exit(EX_DATAERR);
 	}
@@ -552,9 +606,13 @@
 	if (error)
 		return (EX_DATAERR);
 	if (verbose) {
-		printf("Key chain set: %016jx -> %016jx\n",
-		    pefs_keyid_as_int(k1->pxk_keyid),
-		    pefs_keyid_as_int(k2->pxk_keyid));
+		if (zerochainedkey)
+			printf("Key chain set: %016jx\n",
+			    pefs_keyid_as_int(k1->pxk_keyid));
+		else
+			printf("Key chain set: %016jx -> %016jx\n",
+			    pefs_keyid_as_int(k1->pxk_keyid),
+			    pefs_keyid_as_int(k2->pxk_keyid));
 	}
 
 	return (0);
@@ -571,7 +629,7 @@
 	int error, i;
 
 	pefs_keyparam_init(&kp);
-	while ((i = getopt(argc, argv, "fvpa:i:k:")) != -1)
+	while ((i = getopt(argc, argv, "fvpi:k:")) != -1)
 		switch(i) {
 		case 'f':
 			force = 1;
@@ -579,16 +637,14 @@
 		case 'v':
 			verbose = 1;
 			break;
-		case 'a':
-			kp.kp_alg = optarg;
-			break;
 		case 'p':
 			kp.kp_nopassphrase = 1;
 			break;
 		case 'i':
 			kp.kp_iterations = atoi(optarg);
 			if (kp.kp_iterations <= 0) {
-				warnx("invalid iterations argument: %s", optarg);
+				warnx("invalid iterations argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
@@ -622,7 +678,8 @@
 		if (verbose) {
 			printf("Key chain deleted: %016jx -> %016jx\n",
 			    pefs_keyid_as_int(kc->kc_key.pxk_keyid),
-			    pefs_keyid_as_int(TAILQ_NEXT(kc, kc_entry)->kc_key.pxk_keyid));
+			    pefs_keyid_as_int(
+				TAILQ_NEXT(kc, kc_entry)->kc_key.pxk_keyid));
 		}
 		if (!force)
 			break;
@@ -642,18 +699,16 @@
 	int error, i;
 
 	pefs_keyparam_init(&kp);
-	while ((i = getopt(argc, argv, "pa:i:k:")) != -1)
+	while ((i = getopt(argc, argv, "pi:k:")) != -1)
 		switch(i) {
-		case 'a':
-			kp.kp_alg = optarg;
-			break;
 		case 'p':
 			kp.kp_nopassphrase = 1;
 			break;
 		case 'i':
 			kp.kp_iterations = atoi(optarg);
 			if (kp.kp_iterations <= 0) {
-				warnx("invalid iterations argument: %s", optarg);
+				warnx("invalid iterations argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
@@ -699,25 +754,22 @@
 	int i, n, fd;
 
 	k[0].pxk_index = k[1].pxk_index = -1;
-	while ((i = getopt(argc, argv, "va:n:N:")) != -1)
+	while ((i = getopt(argc, argv, "vn:N:")) != -1)
 		switch(i) {
 		case 'v':
 			verbose = 1;
 			break;
-		case 'a':
-			if (pefs_alg_lookup(&k[0], optarg) < 0)
-				errx(EX_USAGE, "invalid algorithm %s", optarg);
-			k[1] = k[0];
-			break;
 		case 'n':
 			if ((nmin = atoi(optarg)) <= 0) {
-				warnx("invalid lower bound argument: %s", optarg);
+				warnx("invalid lower bound argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
 		case 'N':
 			if ((nmax = atoi(optarg)) <= 0) {
-				warnx("invalid lower bound argument: %s", optarg);
+				warnx("invalid lower bound argument: %s",
+				    optarg);
 				pefs_usage();
 			}
 			break;
@@ -728,7 +780,9 @@
 	argv += optind;
 
 	if (nmin >= nmax) {
-		errx(EX_USAGE, "invalid arguments: lower bound (%d) >= upper bound (%d)", nmin, nmax);
+		errx(EX_USAGE,
+		    "invalid arguments: lower bound (%d) >= upper bound (%d)",
+		    nmin, nmax);
 	}
 
 	if (!checkargs_fs(argc, argv)) {
@@ -736,6 +790,7 @@
 	}
 
 	n = arc4random_uniform(nmax - nmin) + nmin;
+	n /= 2;
 
 	fd = open(PATH_DEVRANDOM, O_RDONLY);
 	if (fd == -1)
@@ -743,13 +798,13 @@
 
 	for (i = 1; i <= n; i++) {
 		read(fd, k, 2 * sizeof(struct pefs_keychain));
-		if (i % 2 == 0) {
-			pefs_keychain_set(argv[0], &k[0], &k[1]);
-			if (verbose) {
-				printf("Key chain set: %016jx -> %016jx\n",
-				    pefs_keyid_as_int(k[0].pxk_keyid),
-				    pefs_keyid_as_int(k[1].pxk_keyid));
-			}
+		k[0].pxk_alg = PEFS_ALG_INVALID;
+		k[1].pxk_alg = PEFS_ALG_INVALID;
+		pefs_keychain_set(argv[0], &k[0], &k[1]);
+		if (verbose) {
+			printf("Key chain set: %016jx -> %016jx\n",
+			    pefs_keyid_as_int(k[0].pxk_keyid),
+			    pefs_keyid_as_int(k[1].pxk_keyid));
 		}
 	}
 	
@@ -762,19 +817,19 @@
 void
 pefs_usage(void)
 {
-	fprintf(stderr, "usage:	pefs mount [-o options] target filesystem\n"
-			"	pefs unmount [-fv] filesystem\n"
-			"	pefs addkey [-cCp] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
-			"	pefs setkey [-cCpvx] [-a alg] [-i iterations] [-k keyfile] directory\n"
-			"	pefs delkey [-cCp] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
-			"	pefs flushkeys filesystem\n"
-			"	pefs setchain [-pPv] [-a alg] [-i iterations] [-k keyfile]\n"
-			"		[-A alg] [-I iterations] [-K keyfile] filesystem\n"
-			"	pefs delchain [-pPv] [-a alg] [-i iterations] [-k keyfile]\n"
-			"		[-A alg] [-I iterations] [-K keyfile] filesystem\n"
-			"	pefs showchain [-a alg] [-n min] [-N max] filesystem\n"
-			"	pefs randomchain [-v] [-a alg] [-n min] [-N max] filesystem\n"
-			"	pefs showkeys filesystem\n");
+	fprintf(stderr,
+"usage:	pefs mount [-o options] from filesystem\n"
+"	pefs unmount [-fv] filesystem\n"
+"	pefs addkey [-cCpv] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
+"	pefs setkey [-cCpvx] [-a alg] [-i iterations] [-k keyfile] directory\n"
+"	pefs delkey [-cCpv] [-i iterations] [-k keyfile] filesystem\n"
+"	pefs flushkeys filesystem\n"
+"	pefs setchain [-pPvZ] [-a alg] [-i iterations] [-k keyfile]\n"
+"		[-A alg] [-I iterations] [-K keyfile] filesystem\n"
+"	pefs delchain [-pv] [-i iterations] [-k keyfile] filesystem\n"
+"	pefs showchain [-p] [-i iterations] [-k keyfile] filesystem\n"
+"	pefs randomchain [-v] [-a alg] [-n min] [-N max] filesystem\n"
+"	pefs showkeys filesystem\n");
 	exit(EX_USAGE);
 }
 
@@ -783,7 +838,8 @@
 {
 	if (modfind(PEFS_KLD) < 0)
 		if (kld_load(PEFS_KLD) < 0 || modfind(PEFS_KLD) < 0)
-			errx(EX_OSERR, "cannot find or load \"%s\" kernel module",
+			errx(EX_OSERR,
+			    "cannot find or load \"%s\" kernel module",
 			    PEFS_KLD);
 }
 

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#8 (text+ko) ====

@@ -37,7 +37,14 @@
 #define PEFS_RANDOMCHAIN_MIN		16
 #define PEFS_RANDOMCHAIN_MAX		64
 
-struct pefs_xkey;
+#define PEFS_KEYENC_MAC_SIZE		(PEFS_KEY_SIZE / 2)
+
+struct pefs_xkeyenc {
+	struct pefs_xkey chained;
+	uint32_t alg;
+	uint32_t keybits;
+	u_char mac[PEFS_KEYENC_MAC_SIZE];
+};
 
 struct pefs_keyparam {
 	int kp_nopassphrase;
@@ -59,9 +66,12 @@
 int	pefs_mount(int argc, char *argv[]);
 int	pefs_mount_prog(int argc, char *argv[]);
 int	pefs_getfsroot(const char *path, char *fsroot, size_t size);
-int	pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify, struct pefs_keyparam *kp);
-int	pefs_key_encrypt(struct pefs_xkey *xk, const struct pefs_xkey *xk_parent);
-int	pefs_key_decrypt(struct pefs_xkey *xk, const struct pefs_xkey *xk_parent);
+int	pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify,
+    struct pefs_keyparam *kp);
+int	pefs_key_encrypt(struct pefs_xkeyenc *xe,
+    const struct pefs_xkey *xk_parent);
+int	pefs_key_decrypt(struct pefs_xkeyenc *xe,
+    const struct pefs_xkey *xk_parent);
 uintmax_t	pefs_keyid_as_int(char *keyid);
 const char *	pefs_alg_name(struct pefs_xkey *xk);
 int	pefs_alg_lookup(struct pefs_xkey *xk, const char *algname);

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

@@ -40,16 +40,16 @@
 #include <readpassphrase.h>
 
 #include <geom/eli/g_eli.h>
-#include <geom/eli/pkcs5v2.h>
 #include <fs/pefs/pefs.h>
 
 #include <openssl/evp.h>
 
 #include "pefs_ctl.h"
+#include "pkcs5v2-x.h"
 
 #define PEFS_KEY_PROMPT_DEFAULT			"passphrase"
 
-#define PEFS_CIPHERKEY_ITERATIONS		1000
+#define PEFS_KEYENC_ITERATIONS			1000
 
 struct algorithm {
 	const char *name;
@@ -104,7 +104,8 @@
 }
 
 int
-pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify, struct pefs_keyparam *kp)
+pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify,
+    struct pefs_keyparam *kp)
 {
 	struct hmac_ctx ctx;
 	char promptbuf[64], buf[BUFSIZ], buf2[BUFSIZ], *p;
@@ -134,7 +135,8 @@
 		else {
 			fd = open(kp->kp_keyfile, O_RDONLY);
 			if (fd == -1)
-				err(EX_IOERR, "cannot open keyfile %s", kp->kp_keyfile);
+				err(EX_IOERR, "cannot open keyfile %s",
+				    kp->kp_keyfile);
 		}
 		while ((done = read(fd, buf, sizeof(buf))) > 0)
 			g_eli_crypto_hmac_update(&ctx, buf, done);
@@ -170,40 +172,52 @@
 		if (kp->kp_iterations == 0) {
 			g_eli_crypto_hmac_update(&ctx, buf, strlen(buf));
 		} else {
-			pkcs5v2_genkey(xk->pxk_key, PEFS_KEY_SIZE, buf, 0, buf, kp->kp_iterations);
-			g_eli_crypto_hmac_update(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
+			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,
+			    PEFS_KEY_SIZE);
 		}
 		bzero(buf, sizeof(buf));
 	}
 	g_eli_crypto_hmac_final(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
 
-	g_eli_crypto_hmac_init(&ctx, NULL, 0);
-	g_eli_crypto_hmac_update(&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);
 
 	return (0);
 }
 
 static int
-pefs_key_cipher(struct pefs_xkey *xk, int enc, const struct pefs_xkey *xk_parent)
+pefs_key_cipher(struct pefs_xkeyenc *xe, int enc,
+    const struct pefs_xkey *xk_parent)
 {
 	const int keysize = 128 / 8;
-	const int datasize = sizeof(struct pefs_xkey);
-	u_char *data = (u_char *) xk;
+	const int datasize = sizeof(struct pefs_xkeyenc) - PEFS_KEYENC_MAC_SIZE;
+	struct hmac_ctx hmac_ctx;
+	u_char *data = (u_char *) xe;
 	EVP_CIPHER_CTX ctx;
-	u_char iv[keysize];
 	u_char key[keysize];
+	u_char mac[PEFS_KEYENC_MAC_SIZE];
 	int outsize;
 
-	pkcs5v2_genkey(key, keysize, NULL, 0, xk_parent->pxk_key, PEFS_CIPHERKEY_ITERATIONS);
+	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);
+	if (!enc) {
+		g_eli_crypto_hmac_update(&hmac_ctx, data, datasize);
+		g_eli_crypto_hmac_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);
+	}
 
 	EVP_CIPHER_CTX_init(&ctx);
-
 	EVP_CipherInit_ex(&ctx, EVP_aes_128_cfb(), NULL, NULL, NULL, enc);
 	EVP_CIPHER_CTX_set_key_length(&ctx, keysize);
 	EVP_CIPHER_CTX_set_padding(&ctx, 0);
-	bzero(iv, sizeof(iv));
-	EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, enc);
+	EVP_CipherInit_ex(&ctx, NULL, NULL, key, key, enc);
 	bzero(key, sizeof(key));
 
 	if (EVP_CipherUpdate(&ctx, data, &outsize, data, datasize) == 0) {
@@ -219,18 +233,26 @@
 	assert(outsize == 0);
 
 	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,
+		    PEFS_KEYENC_MAC_SIZE);
+		bzero(&hmac_ctx, sizeof(hmac_ctx));
+	}
+
 	return (0);
 }
 
 int
-pefs_key_encrypt(struct pefs_xkey *xk, const struct pefs_xkey *xk_parent)
+pefs_key_encrypt(struct pefs_xkeyenc *xe, const struct pefs_xkey *xk_parent)
 {
-	return (pefs_key_cipher(xk, 1, xk_parent));
+	return (pefs_key_cipher(xe, 1, xk_parent));
 }
 
 int
-pefs_key_decrypt(struct pefs_xkey *xk, const struct pefs_xkey *xk_parent)
+pefs_key_decrypt(struct pefs_xkeyenc *xe, const struct pefs_xkey *xk_parent)
 {
-	return (pefs_key_cipher(xk, 0, xk_parent));
+	return (pefs_key_cipher(xe, 0, xk_parent));
 }
 

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

@@ -22,13 +22,12 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
  */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/endian.h>
 #include <sys/stat.h>
 #include <assert.h>
@@ -84,16 +83,20 @@
 pefs_keychain_get_db(DB *db, struct pefs_keychain_head *kch)
 {
 	struct pefs_keychain *kc_parent = NULL, *kc;
+	struct pefs_xkeyenc ke;
 	DBT db_key, db_data;
 	int error;
 
 	while (1) {
 		kc_parent = TAILQ_LAST(kch, pefs_keychain_head);
 		TAILQ_FOREACH(kc, kch, kc_entry) {
-			if (kc != kc_parent && memcmp(kc->kc_key.pxk_keyid,
-			    kc_parent->kc_key.pxk_keyid, PEFS_KEYID_SIZE) == 0) {
+			if (kc != kc_parent &&
+			    memcmp(kc->kc_key.pxk_keyid,
+			    kc_parent->kc_key.pxk_keyid,
+			    PEFS_KEYID_SIZE) == 0) {
 				pefs_keychain_free(kch);
-				errx(EX_DATAERR, "keychain: loop detected: %016jx",
+				errx(EX_DATAERR,
+				    "keychain: loop detected: %016jx",
 				    pefs_keyid_as_int(kc->kc_key.pxk_keyid));
 			}
 		}
@@ -107,25 +110,36 @@
 				error = 0;
 			break;
 		}
-		if (db_data.size != sizeof(struct pefs_xkey))
+		if (db_data.size != sizeof(struct pefs_xkeyenc))
 			errx(EX_DATAERR, "keychain: db damaged");
 		
 		kc = calloc(1, sizeof(struct pefs_keychain));
 		if (kc == NULL)
 			err(EX_OSERR, "calloc");
 		
-		memcpy(&kc->kc_key, db_data.data, sizeof(struct pefs_xkey));
-		error = pefs_key_decrypt(&kc->kc_key, &kc_parent->kc_key);
+		memcpy(&ke, db_data.data, sizeof(struct pefs_xkeyenc));
+		error = pefs_key_decrypt(&ke, &kc_parent->kc_key);
 		if (error)
 			break;
+		kc->kc_key = ke.chained;
+		kc_parent->kc_key.pxk_alg = le32toh(ke.alg);
+		kc_parent->kc_key.pxk_keybits = le32toh(ke.keybits);
+		if (pefs_alg_name(&kc_parent->kc_key) == NULL)
+			errx(EX_DATAERR, "keychain: db damaged");
 		kc->kc_key.pxk_index = -1;
 		kc->kc_key.pxk_alg = le32toh(kc->kc_key.pxk_alg);
 		kc->kc_key.pxk_keybits = le32toh(kc->kc_key.pxk_keybits);
-		if (pefs_alg_name(&kc->kc_key) == NULL) {
+
+		if (kc->kc_key.pxk_alg == PEFS_ALG_INVALID ||
+		    pefs_alg_name(&kc->kc_key) == NULL) {
 			bzero(&kc->kc_key, sizeof(struct pefs_xkey));
-			warn("keychain %016jx -> %016jx: invalid algorithm (decyption failed)",
-			    pefs_keyid_as_int(kc_parent->kc_key.pxk_keyid),
-			    pefs_keyid_as_int(kc->kc_key.pxk_keyid));
+			if (kc->kc_key.pxk_alg != PEFS_ALG_INVALID)
+				warn("keychain %016jx -> %016jx: invalid algorithm (decyption failed)",
+				    pefs_keyid_as_int(
+				    kc_parent->kc_key.pxk_keyid),
+				    pefs_keyid_as_int(kc->kc_key.pxk_keyid));
+			free(kc);
+			break;
 		}
 		TAILQ_INSERT_TAIL(kch, kc, kc_entry);
 	}
@@ -167,42 +181,47 @@
 
 	if (error) {
 		if (flags & PEFS_KEYCHAIN_USE)
-			errx(EX_DATAERR, "keychain: Key not found %016jx", pefs_keyid_as_int(xk->pxk_keyid));
+			errx(EX_DATAERR, "keychain: Key not found %016jx",
+			    pefs_keyid_as_int(xk->pxk_keyid));
 	}
 
 	return (0);
 }
 
 int
-pefs_keychain_set(const char *filesystem, struct pefs_xkey *xk, struct pefs_xkey *xknext)
+pefs_keychain_set(const char *filesystem, struct pefs_xkey *xk,
+    struct pefs_xkey *xknext)
 {
-	struct pefs_xkey k;
+	struct pefs_xkeyenc ke;
 	DBT db_key, db_data;
 	DB *db;
 	int error;
 
-	k = *xknext;
-	k.pxk_index = (uint32_t)random();
-	k.pxk_alg = htole32(k.pxk_alg);
-	k.pxk_keybits = htole32(k.pxk_keybits);
-	if (pefs_key_encrypt(&k, xk) != 0)
+	ke.chained = *xknext;
+	ke.chained.pxk_index = (uint32_t)random();
+	ke.chained.pxk_alg = htole32(ke.chained.pxk_alg);
+	ke.chained.pxk_keybits = htole32(ke.chained.pxk_keybits);
+	ke.alg = htole32(xk->pxk_alg);
+	ke.keybits = htole32(xk->pxk_keybits);
+	if (pefs_key_encrypt(&ke, xk) != 0)
 		return (-1);
 	
 	db = keychain_dbopen(filesystem, PEFS_KEYCHAIN_USE, O_RDWR | O_CREAT);
 	if (db == NULL)
 		return (-1);
 
-	db_data.data = &k;
-	db_data.size = sizeof(struct pefs_xkey);
+	db_data.data = &ke;
+	db_data.size = sizeof(struct pefs_xkeyenc);
 	db_key.data = xk->pxk_keyid;
 	db_key.size = PEFS_KEYID_SIZE;
 	error = db->put(db, &db_key, &db_data, R_NOOVERWRITE);
-	bzero(&k, sizeof(struct pefs_xkey));
+	bzero(&ke, sizeof(struct pefs_xkeyenc));
 	if (error != 0) {
 		if (error == -1)
 			warn("keychain");
 		else
-			warnx("keychain: cannot set key chain %016jx", pefs_keyid_as_int(xk->pxk_keyid));
+			warnx("keychain: cannot set key chain %016jx",
+			    pefs_keyid_as_int(xk->pxk_keyid));
 	}
 	db->close(db);
 
@@ -226,7 +245,8 @@
 		if (error == -1)
 			warn("keychain");
 		else
-			warnx("keychain: cannot delete key chain %016jx", pefs_keyid_as_int(xk->pxk_keyid));
+			warnx("keychain: cannot delete key chain %016jx",
+			    pefs_keyid_as_int(xk->pxk_keyid));
 	}
 	db->close(db);
 

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

@@ -30,10 +30,6 @@
  * SUCH DAMAGE.
  */
 
-/*
- * Ancestors:
- *	FreeBSD: head/sbin/mount_nullfs/mount_nullfs.c 152670 2005-11-21 22:51:16Z rodrigc
- */
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -49,6 +45,8 @@
 #include <sysexits.h>
 #include <unistd.h>
 
+#include <fs/pefs/pefs.h>
+
 #include "mntopts.h"
 
 #include "pefs_ctl.h"

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#12 (text+ko) ====

@@ -1,10 +1,7 @@
 /*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 2009 Gleb Kurtsou <gk@FreeBSD.org>
+ * All rights reserved.
  *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -13,14 +10,11 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,21 +23,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)null.h	8.3 (Berkeley) 8/20/94
- *
- * Ancestors:
- *	FreeBSD: head/sys/fs/nullfs/null.h 143642 2005-03-15 13:49:33Z jeff
- *
  * $FreeBSD$
  */
 
-#include <sys/param.h>
-#include <sys/ioccom.h>
-#include <sys/mutex.h>
-#include <sys/refcount.h>
-#include <sys/queue.h>
-#include <sys/uio.h>
-
+#define PEFS_ALG_INVALID		0
 #define PEFS_ALG_SALSA20		1
 #define PEFS_ALG_AES_CTR		2
 #define PEFS_ALG_CAMELLIA_CTR		3
@@ -62,11 +45,13 @@
 	char pxk_key[PEFS_KEY_SIZE];
 };
 
+#ifdef _IO
 #define PEFS_GETKEY			_IOWR('p', 0, struct pefs_xkey)
 #define PEFS_ADDKEY			_IOWR('p', 1, struct pefs_xkey)
 #define PEFS_SETKEY			_IOWR('p', 2, struct pefs_xkey)
 #define PEFS_DELKEY			_IOWR('p', 3, struct pefs_xkey)
 #define PEFS_FLUSHKEYS			_IO('p', 4)
+#endif
 
 #ifdef _KERNEL
 
@@ -275,3 +260,4 @@
 #endif /* PEFS_DEBUG */
 
 #endif /* _KERNEL */
+

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

@@ -22,10 +22,11 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/param.h>
 #include <sys/dirent.h>
 #include <sys/endian.h>
@@ -33,6 +34,7 @@
 #include <sys/libkern.h>
 #include <sys/malloc.h>
 #include <sys/mount.h>
+#include <sys/refcount.h>
 #include <sys/queue.h>
 #include <sys/vnode.h>
 
@@ -54,9 +56,12 @@
 CTASSERT(PEFS_TWEAK_SIZE == 64/8);
 CTASSERT(CAMELLIA_BLOCK_SIZE == PEFS_CTR_BLOCK_SIZE);
 
-typedef void algop_keysetup_t(struct pefs_ctx *ctx, const uint8_t *key, uint32_t keybits);
-typedef void algop_ivsetup_t(struct pefs_ctx *ctx, const uint8_t *iv, uint64_t offset);
-typedef void algop_crypt_t(struct pefs_ctx *ctx, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t len);
+typedef void algop_keysetup_t(struct pefs_ctx *ctx, const uint8_t *key,
+    uint32_t keybits);
+typedef void algop_ivsetup_t(struct pefs_ctx *ctx, const uint8_t *iv,
+    uint64_t offset);
+typedef void algop_crypt_t(struct pefs_ctx *ctx, const uint8_t *plaintext,
+    uint8_t *ciphertext, uint32_t len);
 typedef void algop_cryptblock_t(struct pefs_ctx *ctx, uint8_t *data);
 
 struct pefs_alg {
@@ -139,11 +144,9 @@
 pefs_crypto_init(void)
 {
 	pefs_ctx_zone = uma_zcreate("pefs_ctx", sizeof(struct pefs_ctx), 
-			NULL, NULL, NULL, (uma_fini)bzero, 
-			UMA_ALIGN_PTR, 0);
+	    NULL, NULL, NULL, (uma_fini)bzero, UMA_ALIGN_PTR, 0);
 	pefs_key_zone = uma_zcreate("pefs_key", sizeof(struct pefs_key), 
-			NULL, NULL, NULL, (uma_fini)bzero, 
-			UMA_ALIGN_PTR, 0);
+	    NULL, NULL, NULL, (uma_fini)bzero, UMA_ALIGN_PTR, 0);
 }
 
 void
@@ -194,7 +197,8 @@
 	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, PEFS_TWEAK_SIZE);
+	pefs_hmac_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);
 	pk->pk_alg->pa_keysetup(pk->pk_data_ctx, key, pk->pk_keybits);
@@ -202,7 +206,8 @@
 	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, PEFS_TWEAK_SIZE);
+	pefs_hmac_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);
 	pefs_aes_keysetup(pk->pk_name_ctx, key, 128);
@@ -210,7 +215,8 @@
 	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, PEFS_TWEAK_SIZE);
+	pefs_hmac_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);
 	vmac_set_key(key, &pk->pk_name_csum_ctx->o.pctx_vmac);
@@ -249,7 +255,8 @@
 	}
 	if (pk->pk_keybits == 0) {
 		uma_zfree(pefs_key_zone, pk);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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