From owner-p4-projects@FreeBSD.ORG Sat Aug 8 15:52:40 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id F0F6810656D6; Sat, 8 Aug 2009 15:52:39 +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 A3CB310656C7 for ; Sat, 8 Aug 2009 15:52:39 +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 90F268FC31 for ; Sat, 8 Aug 2009 15:52:39 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n78FqddS036300 for ; Sat, 8 Aug 2009 15:52:39 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n78Fqd0D036298 for perforce@freebsd.org; Sat, 8 Aug 2009 15:52:39 GMT (envelope-from gk@FreeBSD.org) Date: Sat, 8 Aug 2009 15:52:39 GMT Message-Id: <200908081552.n78Fqd0D036298@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 167106 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: Sat, 08 Aug 2009 15:52:41 -0000 http://perforce.freebsd.org/chv.cgi?CH=167106 Change 167106 by gk@gk_h1 on 2009/08/08 15:52:18 readdir improvements: skip unknown entries in encrypted directories, merge cookies encrypt key chains use tailq for keychains implement randomchain do not call pefs_node_lookup_name from pefs_enccn_get (it's not needed) simplify readdir and pefs_enccn_lookup_dirent: use continious buffer (maximum size is page size) remove unused pefs_chunk_get (direct access to iovec is preferred) increase max key size to 512 bits. userspace always generates 512 bits of key material. particular algorithm is to use as much of it as it needs minor style improvements Affected files ... .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#3 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#3 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#3 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#2 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.h#2 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#8 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#6 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#8 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#7 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#9 edit Differences ... ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#3 (text+ko) ==== @@ -47,6 +47,7 @@ #include "pefs_keychain.h" #define PATH_UMOUNT "/sbin/umount" +#define PATH_DEVRANDOM "/dev/random" static int pefs_unmount(int argc, char *argv[]); static int pefs_addkey(int argc, char *argv[]); @@ -60,7 +61,7 @@ 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 *kc, int fd); +typedef int (*keyop_func_t)(struct pefs_keychain_head *kch, int fd); struct command { const char *name; @@ -124,7 +125,7 @@ pefs_keyop(keyop_func_t func, int argc, char *argv[]) { struct pefs_xkey k; - struct pefs_keychain *kc; + struct pefs_keychain_head kch; struct pefs_keyparam kp; int error, fd, i; int chain = PEFS_KEYCHAIN_IGNORE_MISSING; @@ -169,19 +170,18 @@ if (error != 0) return (error); - kc = pefs_keychain_get(argv[0], chain, &k); + error = pefs_keychain_get(&kch, argv[0], chain, &k); bzero(&k, sizeof(k)); - if (kc == NULL) { + if (error) return (EX_DATAERR); - } fd = open(argv[0], O_RDONLY); if (fd == -1) { err(EX_IOERR, "cannot open %s", argv[0]); } - error = func(kc, fd); + error = func(&kch, fd); - pefs_keychain_free(kc); + pefs_keychain_free(&kch); close(fd); @@ -189,9 +189,11 @@ } static int -pefs_addkey_op(struct pefs_keychain *kc, int fd) +pefs_addkey_op(struct pefs_keychain_head *kch, int fd) { - for (; kc; kc = kc->kc_next) { + struct pefs_keychain *kc; + + TAILQ_FOREACH(kc, kch, kc_entry) { if (ioctl(fd, PEFS_ADDKEY, &kc->kc_key) == -1) { warn("cannot add key"); return (-1); @@ -202,9 +204,11 @@ } static int -pefs_delkey_op(struct pefs_keychain *kc, int fd) +pefs_delkey_op(struct pefs_keychain_head *kch, int fd) { - for (; kc; kc = kc->kc_next) { + struct pefs_keychain *kc; + + TAILQ_FOREACH(kc, kch, kc_entry) { if (ioctl(fd, PEFS_DELKEY, &kc->kc_key) == -1) { warn("cannot delete key"); } @@ -229,7 +233,7 @@ pefs_setkey(int argc, char *argv[]) { struct pefs_xkey k; - struct pefs_keychain *kc; + struct pefs_keychain_head kch; struct pefs_keyparam kp; int error, fd, i; int addkey = 0; @@ -285,11 +289,11 @@ if (error != 0) return (error); - kc = pefs_keychain_get(argv[0], chain, &k); - if (kc == NULL) { + error = pefs_keychain_get(&kch, argv[0], chain, &k); + bzero(&k, sizeof(k)); + if (error) return (EX_DATAERR); - } - pefs_keychain_free(kc); + pefs_keychain_free(&kch); bzero(k.pxk_key, PEFS_KEY_SIZE); @@ -414,18 +418,23 @@ static int pefs_setchain(int argc, char *argv[]) { - struct pefs_keychain *kc, *kci; + struct pefs_keychain *kc; + struct pefs_keychain_head kch; struct { struct pefs_xkey k; struct pefs_keyparam kp; } p[2]; struct pefs_xkey *k1 = &p[0].k, *k2 = &p[1].k; + int verbose = 0; int error, i; pefs_keyparam_init(&p[0].kp); pefs_keyparam_init(&p[1].kp); - while ((i = getopt(argc, argv, "pPa:A:i:I:k:K:")) != -1) + while ((i = getopt(argc, argv, "vpPa:A:i:I:k:K:")) != -1) switch(i) { + case 'v': + verbose = 1; + break; case 'a': case 'A': p[isupper(i) ? 1 : 0].kp.kp_alg = optarg; @@ -468,10 +477,10 @@ return (error); } - kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_IGNORE_MISSING, k1); - for (kci = kc; kci; kci = kci->kc_next) { - if (memcmp(k2->pxk_keyid, kci->kc_key.pxk_keyid, PEFS_KEYID_SIZE) == 0) { - pefs_keychain_free(kc); + 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) { + pefs_keychain_free(&kch); bzero(k1->pxk_key, PEFS_KEY_SIZE); bzero(k2->pxk_key, PEFS_KEY_SIZE); errx(EX_DATAERR, "key chain is already set: %016jx -> %016jx", @@ -479,19 +488,25 @@ pefs_keyid_as_int(k2->pxk_keyid)); } } - if (kc->kc_next != NULL) { + kc = TAILQ_FIRST(&kch); + if (TAILQ_NEXT(kc, kc_entry) != NULL) { bzero(k1->pxk_key, PEFS_KEY_SIZE); 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(kc->kc_next->kc_key.pxk_keyid)); - pefs_keychain_free(kc); + pefs_keyid_as_int(TAILQ_NEXT(kc, kc_entry)->kc_key.pxk_keyid)); + pefs_keychain_free(&kch); exit(EX_DATAERR); } error = pefs_keychain_set(argv[0], k1, k2); 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)); + } return (0); } @@ -501,16 +516,20 @@ { struct pefs_xkey k; struct pefs_keyparam kp; - struct pefs_keychain *kc, *kci; + struct pefs_keychain *kc; + struct pefs_keychain_head kch; + int force = 0, verbose = 0;; int error, i; - int force = 0; pefs_keyparam_init(&kp); - while ((i = getopt(argc, argv, "fpa:i:k:")) != -1) + while ((i = getopt(argc, argv, "fvpa:i:k:")) != -1) switch(i) { case 'f': force = 1; break; + case 'v': + verbose = 1; + break; case 'a': kp.kp_alg = optarg; break; @@ -541,18 +560,25 @@ if (error != 0) return (error); - kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_USE, &k); - if (kc == NULL) { + error = pefs_keychain_get(&kch, argv[0], PEFS_KEYCHAIN_USE, &k); + if (error) { bzero(&k, sizeof(k)); return (EX_DATAERR); } - for (kci = kc; kci != NULL && kci->kc_next != NULL; kci = kci->kc_next) { - pefs_keychain_del(argv[0], &kci->kc_key); + TAILQ_FOREACH(kc, &kch, kc_entry) { + if (!TAILQ_NEXT(kc, kc_entry)) + break; + pefs_keychain_del(argv[0], &kc->kc_key); + 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)); + } if (!force) break; } - pefs_keychain_free(kc); + pefs_keychain_free(&kch); return (0); } @@ -562,7 +588,8 @@ { struct pefs_xkey k; struct pefs_keyparam kp; - struct pefs_keychain *kc, *kci; + struct pefs_keychain *kc; + struct pefs_keychain_head kch; int error, i; pefs_keyparam_init(&kp); @@ -598,25 +625,87 @@ if (error != 0) return (error); - kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_USE, &k); - if (kc == NULL) { - bzero(&k, sizeof(k)); + error = pefs_keychain_get(&kch, argv[0], PEFS_KEYCHAIN_USE, &k); + bzero(&k, sizeof(k)); + if (error) { return (EX_DATAERR); } printf("Key chain:\n"); - bzero(&k, sizeof(k)); - for (i = 1, kci = kc; kci != NULL; i++, kci = kci->kc_next) { - pefs_key_show(&kci->kc_key, i); + i = 1; + TAILQ_FOREACH(kc, &kch, kc_entry) { + pefs_key_show(&kc->kc_key, i++); } - pefs_keychain_free(kc); + pefs_keychain_free(&kch); return (0); } static int -pefs_randomchain(int argc __unused, char *argv[] __unused) +pefs_randomchain(int argc, char *argv[]) { + struct pefs_xkey k[2]; + int nmin = PEFS_RANDOMCHAIN_MIN, nmax = PEFS_RANDOMCHAIN_MAX; + int verbose = 0; + int i, n, fd; + + k[0].pxk_index = k[1].pxk_index = -1; + while ((i = getopt(argc, argv, "va:n:N:")) != -1) + switch(i) { + case 'v': + verbose = 1; + break; + case 'a': + k[0].pxk_alg = k[1].pxk_alg = pefs_alg_id(optarg); + if (k[0].pxk_alg < 0) + errx(EX_USAGE, "invalid algorithm %s", optarg); + break; + case 'n': + if ((nmin = atoi(optarg)) <= 0) { + warnx("invalid lower bound argument: %s", optarg); + pefs_usage(); + } + break; + case 'N': + if ((nmax = atoi(optarg)) <= 0) { + warnx("invalid lower bound argument: %s", optarg); + pefs_usage(); + } + break; + default: + pefs_usage(); + } + argc -= optind; + argv += optind; + + if (nmin >= nmax) { + errx(EX_USAGE, "invalid arguments: lower bound (%d) >= upper bound (%d)", nmin, nmax); + } + + if (!checkargs_fs(argc, argv)) { + pefs_usage(); + } + + n = arc4random_uniform(nmax - nmin) + nmin; + + fd = open(PATH_DEVRANDOM, O_RDONLY); + if (fd == -1) + err(EX_IOERR, "%s", PATH_DEVRANDOM); + + 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)); + } + } + } + + close(fd); + return (0); } @@ -627,15 +716,15 @@ 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 [-xcCp] [-a alg] [-i iterations] [-k keyfile] directory\n" + " pefs setkey [-cCpx] [-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 [-pP] [-a alg] [-i iterations] [-k keyfile]\n" + " pefs setchain [-pPv] [-a alg] [-i iterations] [-k keyfile]\n" " [-A alg] [-I iterations] [-K keyfile] filesystem\n" - " pefs delchain [-pP] [-a alg] [-i iterations] [-k keyfile]\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 [-a alg] [-n min] [-N max] filesystem\n" + " pefs randomchain [-v] [-a alg] [-n min] [-N max] filesystem\n" " pefs showkeys filesystem\n"); exit(EX_USAGE); } ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#3 (text+ko) ==== @@ -25,10 +25,14 @@ * * $FreeBSD$ */ + #define PEFS_ALG_DEFAULT PEFS_ALG_SALSA20 #define PEFS_KDF_ITERATIONS 50000 +#define PEFS_RANDOMCHAIN_MIN 16 +#define PEFS_RANDOMCHAIN_MAX 64 + struct pefs_xkey; struct pefs_keyparam { @@ -48,10 +52,12 @@ } void pefs_usage(void); -int pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify, - struct pefs_keyparam *kp); int pefs_mount(int argc, char *argv[]); int pefs_mount_prog(int argc, char *argv[]); +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); uintmax_t pefs_keyid_as_int(char *keyid); const char * pefs_alg_name(int alg_id); +int pefs_alg_id(const char *name); ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#3 (text+ko) ==== @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -42,10 +43,14 @@ #include #include +#include + #include "pefs_ctl.h" #define PEFS_KEY_PROMPT_DEFAULT "passphrase" +#define PEFS_CIPHERKEY_ITERATIONS 1000 + struct algorithm { const char *name; int id; @@ -70,10 +75,22 @@ } int +pefs_alg_id(const char *algname) +{ + struct algorithm *alg; + + for (alg = algs; alg->name != NULL; alg++) { + if (strcmp(algname, alg->name) == 0) + return (alg->id); + } + + return (-1); +} + +int pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify, struct pefs_keyparam *kp) { struct hmac_ctx ctx; - struct algorithm *alg; char promptbuf[64], buf[BUFSIZ], buf2[BUFSIZ], *p; ssize_t done; int fd, i; @@ -82,11 +99,9 @@ xk->pxk_alg = PEFS_ALG_DEFAULT; if (kp->kp_alg != NULL) { - for (alg = algs; alg->name != NULL; alg++) { - if (strcmp(kp->kp_alg, alg->name) == 0) - xk->pxk_alg = alg->id; - } - errx(EX_USAGE, "invalid algorithm %s", optarg); + xk->pxk_alg = pefs_alg_id(kp->kp_alg); + if (xk->pxk_alg < 0) + errx(EX_USAGE, "invalid algorithm %s", kp->kp_alg); } g_eli_crypto_hmac_init(&ctx, NULL, 0); @@ -153,3 +168,53 @@ return (0); } +static int +pefs_key_cipher(struct pefs_xkey *xk, 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; + EVP_CIPHER_CTX ctx; + u_char iv[keysize]; + u_char key[keysize]; + int outsize; + + pkcs5v2_genkey(key, keysize, NULL, 0, xk_parent->pxk_key, PEFS_CIPHERKEY_ITERATIONS); + + 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); + bzero(key, sizeof(key)); + + if (EVP_CipherUpdate(&ctx, data, &outsize, data, datasize) == 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + return (EINVAL); + } + assert(outsize == (int)datasize); + + if (EVP_CipherFinal_ex(&ctx, data + outsize, &outsize) == 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + return (EINVAL); + } + assert(outsize == 0); + + EVP_CIPHER_CTX_cleanup(&ctx); + return (0); +} + +int +pefs_key_encrypt(struct pefs_xkey *xk, const struct pefs_xkey *xk_parent) +{ + return (pefs_key_cipher(xk, 1, xk_parent)); +} + +int +pefs_key_decrypt(struct pefs_xkey *xk, const struct pefs_xkey *xk_parent) +{ + return (pefs_key_cipher(xk, 0, xk_parent)); +} + ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#2 (text+ko) ==== @@ -62,120 +62,129 @@ return (db); } -void pefs_keychain_free(struct pefs_keychain *kc) +void +pefs_keychain_free(struct pefs_keychain_head *kch) { - struct pefs_keychain *prev; + struct pefs_keychain *kc; - while (kc) { - if (kc == NULL) - break; - + if (kch == NULL) + return; + while ((kc = TAILQ_FIRST(kch)) != NULL) { + TAILQ_REMOVE(kch, kc, kc_entry); bzero(kc, sizeof(struct pefs_keychain)); - prev = kc; - kc = kc->kc_next; - free(prev); + free(kc); } } -static struct pefs_keychain * -pefs_keychain_get_db(DB *db, struct pefs_xkey *xk) +static int +pefs_keychain_get_db(DB *db, struct pefs_keychain_head *kch) { - struct pefs_keychain *kc_head = NULL, **kc_prev = NULL, *kc; + struct pefs_keychain *kc_parent = NULL, *kc; DBT db_key, db_data; int error; while (1) { - for (kc = kc_head; kc != NULL; kc = kc->kc_next) { - if (memcmp(xk->pxk_keyid, kc->kc_key.pxk_keyid, PEFS_KEYID_SIZE) == 0) { - pefs_keychain_free(kc_head); + 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) { + pefs_keychain_free(kch); errx(EX_DATAERR, "keychain: loop detected: %016jx", - pefs_keyid_as_int(xk->pxk_keyid)); + pefs_keyid_as_int(kc->kc_key.pxk_keyid)); } } - - kc = calloc(1, sizeof(struct pefs_keychain)); - if (kc == NULL) - err(EX_OSERR, "calloc"); - if (kc_head == NULL) - kc_head = kc; - if (kc_prev != NULL) - *kc_prev = kc; - kc_prev = &kc->kc_next; - kc->kc_key = *xk; - - db_key.data = kc->kc_key.pxk_keyid; + db_key.data = kc_parent->kc_key.pxk_keyid; db_key.size = PEFS_KEYID_SIZE; error = db->get(db, &db_key, &db_data, 0); if (error != 0) { if (error == -1) warn("keychain"); - if (kc == kc_head) { - pefs_keychain_free(kc); - kc_head = NULL; - } + if (TAILQ_FIRST(kch) != kc_parent) + error = 0; break; } if (db_data.size != sizeof(struct pefs_xkey)) errx(EX_DATAERR, "keychain: db damaged"); - xk = db_data.data; + + 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); + if (error) + break; + if (pefs_alg_name(kc->kc_key.pxk_alg) == 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)); + } + TAILQ_INSERT_TAIL(kch, kc, kc_entry); } - return (kc_head); + return (error); } -struct pefs_keychain * -pefs_keychain_get(const char *filesystem, int flags, struct pefs_xkey *xk) +int +pefs_keychain_get(struct pefs_keychain_head *kch, const char *filesystem, + int flags, struct pefs_xkey *xk) { struct pefs_keychain *kc; DB *db; + int error; - assert(filesystem != NULL && xk != NULL); + assert(filesystem != NULL && kch != NULL && xk != NULL); - if (flags == 0) { - kc = calloc(1, sizeof(struct pefs_keychain)); - if (kc == NULL) - err(EX_OSERR, "calloc"); - kc->kc_key = *xk; + TAILQ_INIT(kch); - return (kc); - } + kc = calloc(1, sizeof(struct pefs_keychain)); + if (kc == NULL) + err(EX_OSERR, "calloc"); + kc->kc_key = *xk; + TAILQ_INSERT_HEAD(kch, kc, kc_entry); db = keychain_dbopen(filesystem, flags, O_RDONLY); if (db == NULL) { if (flags & PEFS_KEYCHAIN_IGNORE_MISSING) - return (pefs_keychain_get(filesystem, 0, xk)); - return (NULL); + return (0); + return (ENOENT); } - kc = pefs_keychain_get_db(db, xk); + error = pefs_keychain_get_db(db, kch); db->close(db); - if (kc == NULL) { + if (error) { if (flags & PEFS_KEYCHAIN_USE) errx(EX_DATAERR, "keychain: Key not found %016jx", pefs_keyid_as_int(xk->pxk_keyid)); - else if (flags & PEFS_KEYCHAIN_IGNORE_MISSING) - return (pefs_keychain_get(filesystem, 0, xk)); } - return (kc); + return (0); } int pefs_keychain_set(const char *filesystem, struct pefs_xkey *xk, struct pefs_xkey *xknext) { + struct pefs_xkey k; DBT db_key, db_data; DB *db; int error; + k = *xknext; + if (pefs_key_encrypt(&k, 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_key.data = xk->pxk_keyid; db_key.size = PEFS_KEYID_SIZE; - db_data.data = xknext; - db_data.size = sizeof(struct pefs_xkey); error = db->put(db, &db_key, &db_data, R_NOOVERWRITE); + bzero(&k, sizeof(struct pefs_xkey)); if (error != 0) { if (error == -1) warn("keychain"); ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.h#2 (text+ko) ==== @@ -26,17 +26,23 @@ * $FreeBSD$ */ +#include + #define PEFS_KEYCHAIN_USE 0x0001 #define PEFS_KEYCHAIN_IGNORE_MISSING 0x0002 struct pefs_keychain { + TAILQ_ENTRY(pefs_keychain) kc_entry; struct pefs_xkey kc_key; - struct pefs_keychain *kc_next; }; -struct pefs_keychain * pefs_keychain_get(const char *filesystem, int flags, struct pefs_xkey *xk); -int pefs_keychain_set(const char *filesystem, struct pefs_xkey *xk, struct pefs_xkey *xknext); -int pefs_keychain_del(const char *filesystem, struct pefs_xkey *xk); -void pefs_keychain_free(struct pefs_keychain *kc); +TAILQ_HEAD(pefs_keychain_head, pefs_keychain); + +int pefs_keychain_get(struct pefs_keychain_head *kch, + const char *filesystem, int flags, struct pefs_xkey *xk); +int pefs_keychain_set(const char *filesystem, struct pefs_xkey *xk, + struct pefs_xkey *xknext); +int pefs_keychain_del(const char *filesystem, struct pefs_xkey *xk); +void pefs_keychain_free(struct pefs_keychain_head *kch); ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#8 (text+ko) ==== @@ -47,7 +47,7 @@ #define PEFS_ALG_SALSA20 1 #define PEFS_TWEAK_SIZE 8 -#define PEFS_KEY_BITS 256 +#define PEFS_KEY_BITS 512 #define PEFS_KEY_SIZE (PEFS_KEY_BITS / 8) #define PEFS_KEYID_SIZE 8 #define PEFS_NAME_CSUM_SIZE 2 @@ -164,7 +164,6 @@ int pefs_node_get(struct mount *mp, struct vnode *lvp, struct vnode *ldvp, struct vnode **vpp, struct ucred *cred, struct pefs_tkey *ptk); void pefs_node_free(struct pefs_node *xp); -int pefs_node_lookup_name(struct vnode *lvp, struct vnode *ldvp, struct ucred *cred, char *encname, int *encname_len); struct pefs_key * pefs_node_key(struct pefs_node *pn); struct pefs_ctx * pefs_ctx_get(void); @@ -194,7 +193,6 @@ void* pefs_chunk_pullup(struct pefs_chunk *pc, size_t size); struct uio * pefs_chunk_uio(struct pefs_chunk *pc, off_t uio_offset, enum uio_rw uio_rw); struct uio * pefs_chunk_uio_range(struct pefs_chunk *pc, size_t skip, size_t size, off_t uio_offset, enum uio_rw uio_rw); -void* pefs_chunk_get(struct pefs_chunk *pc, size_t *size, long *_state); void pefs_chunk_zero(struct pefs_chunk *pc); int pefs_chunk_copy(struct pefs_chunk *pc, size_t skip, struct uio *uio); void pefs_chunk_crop(struct pefs_chunk *pc, size_t skip_begin, size_t skip_end); @@ -228,7 +226,7 @@ #ifdef PEFS_DEBUG #define PEFSDEBUG(format, args...) printf(format ,## args) #else -#define PEFSDEBUG(format, args...) +#define PEFSDEBUG(format, args...) do { } while (0) #endif /* PEFS_DEBUG */ #endif /* _KERNEL */ ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#6 (text+ko) ==== @@ -79,7 +79,7 @@ struct pefs_ctx * pefs_ctx_get(void) { - return uma_zalloc(pefs_ctx_zone, M_WAITOK); + return (uma_zalloc(pefs_ctx_zone, M_WAITOK)); } void @@ -244,9 +244,7 @@ void pefs_data_encrypt(struct pefs_ctx *ctx, struct pefs_tkey *ptk, off_t offset, struct pefs_chunk *pc) { - long arg = 0; - char *mem; - size_t size; + struct iovec *iov; int free_ctx = 0; if (ptk->ptk_key == NULL) { @@ -260,11 +258,9 @@ salsa20_keysetup(&ctx->pctx_salsa, ptk->ptk_key->pk_data, PEFS_KEY_BITS); salsa20_ivsetup(&ctx->pctx_salsa, ptk->ptk_tweak, offset); - while (1) { - mem = pefs_chunk_get(pc, &size, &arg); - if (mem == NULL) - break; - salsa20_crypt(&ctx->pctx_salsa, mem, mem, size); + for (iov = pc->pc_iov; iov < pc->pc_iov + pc->pc_iovcnt; iov++) { + salsa20_crypt(&ctx->pctx_salsa, iov->iov_base, iov->iov_base, + iov->iov_len); } if (free_ctx) @@ -356,7 +352,7 @@ free(buf, M_PEFSBUF); - return r; + return (r); } int @@ -395,7 +391,6 @@ else dec = plain; do { - PEFSDEBUG("pefs_name_decrypt: check key %p\n", ki); salsa20_keysetup(&ctx->pctx_salsa, ki->pk_name, PEFS_KEY_BITS); salsa20_ivsetup(&ctx->pctx_salsa, magic_tweak_name, 0); salsa20_crypt(&ctx->pctx_salsa, plain, dec, r); @@ -411,7 +406,6 @@ if (!ki_rev) { ki = TAILQ_NEXT(ki, pk_entry); - PEFSDEBUG("pefs_name_decrypt: next key %p\n", ki); if (ki == NULL) { ki_rev = 1; ki = pk; @@ -419,7 +413,6 @@ } if (ki_rev) { ki = TAILQ_PREV(ki, pefs_key_head, pk_entry); - PEFSDEBUG("pefs_name_decrypt: prev key %p\n", ki); } } while (ki != NULL); @@ -438,8 +431,8 @@ memcpy(plain, dec + PEFS_TWEAK_SIZE, r); plain[r] = '\0'; - PEFSDEBUG("pefs_name_decrypt: %d; %.*s => %.*s\n", r, enc_len, enc, r < 0 ? 0 : r, plain); + // PEFSDEBUG("pefs_name_decrypt: %d; %.*s => %.*s\n", r, enc_len, enc, r < 0 ? 0 : r, plain); - return r; + return (r); } ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#8 (text+ko) ==== @@ -191,7 +191,7 @@ vput(vp); } -int +static int pefs_node_lookup_name(struct vnode *lvp, struct vnode *ldvp, struct ucred *cred, char *encname, int *encname_len) { struct vnode *nldvp; @@ -229,7 +229,7 @@ encname[*encname_len] = '\0'; PEFSDEBUG("%s: len=%d %s\n", __func__, *encname_len, encname); - return 0; + return (0); } static int @@ -463,7 +463,7 @@ struct uio* pefs_chunk_uio(struct pefs_chunk *pc, off_t uio_offset, enum uio_rw uio_rw) { - return pefs_chunk_uio_range(pc, 0, pc->pc_size, uio_offset, uio_rw); + return (pefs_chunk_uio_range(pc, 0, pc->pc_size, uio_offset, uio_rw)); } struct uio* @@ -497,23 +497,6 @@ return (&pc->pc_uio); } -void* -pefs_chunk_get(struct pefs_chunk *pc, size_t *size, long *state) -{ - void *mem; - - if (!size || !state || *state < 0) - panic("pefs_chunk_get: invalid args"); - if (*state >= pc->pc_iovcnt) { - *size = 0; - return (NULL); - } - mem = pc->pc_iov[*state].iov_base; - *size = pc->pc_iov[*state].iov_len; - (*state)++; - return (mem); -} - void pefs_chunk_zero(struct pefs_chunk *pc) { @@ -653,6 +636,6 @@ a->pn_lowervp, vrefcnt(a->pn_lowervp), fil, lno); #endif - return a->pn_lowervp; + return (a->pn_lowervp); } #endif ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vfsops.c#7 (text+ko) ==== @@ -62,7 +62,7 @@ int error = 0; struct vnode *lowerrootvp, *vp; struct vnode *pm_rootvp; - struct pefs_mount *xmp; + struct pefs_mount *pm; char *target; int isvnunlocked = 0, len; struct nameidata nd, *ndp = &nd; @@ -129,16 +129,16 @@ return (EDEADLK); } - xmp = (struct pefs_mount *) malloc(sizeof(struct pefs_mount), - M_PEFSMNT, M_WAITOK | M_ZERO); /* XXX */ + pm = (struct pefs_mount *)malloc(sizeof(struct pefs_mount), M_PEFSMNT, + M_WAITOK | M_ZERO); - mtx_init(&xmp->pm_keys_lock, "pefs_mount lock", NULL, MTX_DEF); - TAILQ_INIT(&xmp->pm_keys); + mtx_init(&pm->pm_keys_lock, "pefs_mount lock", NULL, MTX_DEF); + TAILQ_INIT(&pm->pm_keys); /* * Save reference to underlying FS */ - xmp->pm_lowervfs = lowerrootvp->v_mount; + pm->pm_lowervfs = lowerrootvp->v_mount; /* * Save reference. Each mount also holds @@ -151,7 +151,7 @@ if (error) { VOP_UNLOCK(vp, 0); vrele(lowerrootvp); - free(xmp, M_PEFSMNT); /* XXX */ + free(pm, M_PEFSMNT); return (error); } @@ -161,7 +161,7 @@ */ pm_rootvp = vp; pm_rootvp->v_vflag |= VV_ROOT; - xmp->pm_rootvp = pm_rootvp; + pm->pm_rootvp = pm_rootvp; /* * Unlock the node (either the lower or the alias) @@ -176,7 +176,7 @@ MNT_ILOCK(mp); mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE; MNT_IUNLOCK(mp); - mp->mnt_data = xmp; + mp->mnt_data = pm; vfs_getnewfsid(mp); vfs_mountedfrom(mp, target); @@ -214,7 +214,7 @@ pefs_key_remove_all(pm); mtx_destroy(&pm->pm_keys_lock); free(pm, M_PEFSMNT); - return 0; >>> TRUNCATED FOR MAIL (1000 lines) <<<