Date: Sat, 1 Aug 2009 18:38:22 GMT From: Gleb Kurtsou <gk@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 166896 for review Message-ID: <200908011838.n71IcMgW049383@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166896 Change 166896 by gk@gk_h1 on 2009/08/01 18:37:48 Implement changing directory key (pefs setkey) Implement key chaining Fix vop_link: forbid creation of link to unencrypted file, use same tweak and key for created link Affected files ... .. //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#2 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#2 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#2 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#2 edit .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#1 add .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.h#1 add .. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_mount.c#2 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#5 edit .. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#8 edit Differences ... ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#2 (text+ko) ==== @@ -5,7 +5,7 @@ .PATH: ${MOUNT} ${SYS}/geom/eli ${SYS}/crypto/sha2 PROG= pefs -SRCS= pefs_ctl.c pefs_mount.c pefs_key.c +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 ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#2 (text+ko) ==== @@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> +#include <assert.h> +#include <ctype.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> @@ -42,6 +44,7 @@ #include <fs/pefs/pefs.h> #include "pefs_ctl.h" +#include "pefs_keychain.h" #define PATH_UMOUNT "/sbin/umount" @@ -50,9 +53,14 @@ static int pefs_setkey(int argc, char *argv[]); static int pefs_delkey(int argc, char *argv[]); static int pefs_flushkeys(int argc, char *argv[]); -static int pefs_status(int argc, char *argv[]); +static int pefs_setchain(int argc, char *argv[]); +static int pefs_delchain(int argc, char *argv[]); +static int pefs_randomchain(int argc, char *argv[]); +static int pefs_showkeys(int argc, char *argv[]); +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); struct command { const char *name; @@ -67,88 +75,237 @@ { "setkey", pefs_setkey }, { "delkey", pefs_delkey }, { "flushkeys", pefs_flushkeys }, - { "status", pefs_status }, + { "showkeys", pefs_showkeys }, + { "status", pefs_showkeys }, + { "randomchain", pefs_randomchain }, + { "setchain", pefs_setchain }, + { "delchain", pefs_delchain }, + { "showchain", pefs_showchain }, { NULL, NULL }, }; static int -pefs_addkey(int argc, char *argv[]) +checkargs_fs(int argc, char **argv __unused) +{ + if (argc != 1) { + if (argc == 0) + warnx("missing filesystem argument"); + else + warnx("too many arguments"); + return (0); + } + + return (1); +} + +uintmax_t +pefs_keyid_as_int(char *keyid) +{ + uintmax_t r; + int i; + + assert(sizeof(uintmax_t) >= PEFS_KEYID_SIZE); + for (i = 0, r = 0; i < PEFS_KEYID_SIZE; i++) { + if (i) + r <<= 8; + r |= keyid[i] & 0xff; + } + + return (r); +} + +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->pxk_alg)); +} + +static int +pefs_keyop(keyop_func_t func, int argc, char *argv[]) { struct pefs_xkey k; - int error, fd; + struct pefs_keychain *kc; + struct pefs_keyparam kp; + int error, fd, i; + int chain = PEFS_KEYCHAIN_IGNORE_MISSING; - error = pefs_get_key(&k, &argc, argv); - if (error != 0) - return (error); + pefs_keyparam_init(&kp); + while ((i = getopt(argc, argv, "pcCa:i:k:")) != -1) + switch(i) { + case 'a': + kp.kp_alg = optarg; + break; + case 'c': + chain = PEFS_KEYCHAIN_USE; + break; + case 'C': + chain = 0; + 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); + pefs_usage(); + } + break; + case 'k': + kp.kp_keyfile = optarg; + break; + default: + pefs_usage(); + } + argc -= optind; + argv += optind; - if (argc != 1) { + if (!checkargs_fs(argc, argv)) { bzero(&k, sizeof(k)); - if (argc == 0) - warnx("missing filesystem argument"); - else if (getopt(argc, argv, "") == -1) - warnx("too many arguments"); pefs_usage(); } + error = pefs_key_get(&k, NULL, 0, &kp); + if (error != 0) + return (error); + + kc = pefs_keychain_get(argv[0], chain, &k); + bzero(&k, sizeof(k)); + if (kc == NULL) { + return (EX_DATAERR); + } fd = open(argv[0], O_RDONLY); if (fd == -1) { - bzero(&k, sizeof(k)); err(EX_IOERR, "cannot open %s", argv[0]); } - if (ioctl(fd, PEFS_ADDKEY, &k) == -1) { - bzero(&k, sizeof(k)); - err(EX_IOERR, "cannot add key"); + + error = func(kc, fd); + + pefs_keychain_free(kc); + + close(fd); + + return (error); +} + +static int +pefs_addkey_op(struct pefs_keychain *kc, int fd) +{ + for (; kc; kc = kc->kc_next) { + if (ioctl(fd, PEFS_ADDKEY, &kc->kc_key) == -1) { + warn("cannot add key"); + return (-1); + } } - bzero(&k, sizeof(k)); - close(fd); return (0); } static int -pefs_setkey(int argc __unused, char *argv[] __unused) +pefs_delkey_op(struct pefs_keychain *kc, int fd) { - pefs_usage(); + for (; kc; kc = kc->kc_next) { + if (ioctl(fd, PEFS_DELKEY, &kc->kc_key) == -1) { + warn("cannot delete key"); + } + } return (0); } static int +pefs_addkey(int argc, char *argv[]) +{ + return (pefs_keyop(pefs_addkey_op, argc, argv)); +} + +static int pefs_delkey(int argc, char *argv[]) { + return (pefs_keyop(pefs_delkey_op, argc, argv)); +} + +static int +pefs_setkey(int argc, char *argv[]) +{ struct pefs_xkey k; - int error, fd; + struct pefs_keychain *kc; + struct pefs_keyparam kp; + int error, fd, i; + int addkey = 0; + int chain = PEFS_KEYCHAIN_IGNORE_MISSING; + + pefs_keyparam_init(&kp); + while ((i = getopt(argc, argv, "xpcCa:i:k:")) != -1) + switch(i) { + case 'x': + addkey = 1; + break; + case 'a': + kp.kp_alg = optarg; + break; + case 'c': + chain = PEFS_KEYCHAIN_USE; + break; + case 'C': + chain = 0; + 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); + pefs_usage(); + } + break; + case 'k': + kp.kp_keyfile = optarg; + break; + default: + pefs_usage(); + } + argc -= optind; + argv += optind; - error = pefs_get_key(&k, &argc, argv); - if (error != 0) - return (error); + if (chain == PEFS_KEYCHAIN_USE && addkey) + errx(EX_USAGE, "invalid arguments: -x -c"); - bzero(k.pxk_key, PEFS_KEY_SIZE); if (argc != 1) { - bzero(&k, sizeof(k)); if (argc == 0) - warnx("missing filesystem argument"); - else if (getopt(argc, argv, "") == -1) + warnx("missing directory argument"); + else warnx("too many arguments"); + bzero(&k, sizeof(k)); pefs_usage(); } + error = pefs_key_get(&k, NULL, 0, &kp); + if (error != 0) + return (error); + + kc = pefs_keychain_get(argv[0], chain, &k); + if (kc == NULL) { + return (EX_DATAERR); + } + pefs_keychain_free(kc); + + bzero(k.pxk_key, PEFS_KEY_SIZE); + fd = open(argv[0], O_RDONLY); if (fd == -1) { - bzero(&k, sizeof(k)); err(EX_IOERR, "cannot open %s", argv[0]); } - if (ioctl(fd, PEFS_DELKEY, &k) == -1) { - bzero(&k, sizeof(k)); - err(EX_IOERR, "cannot delete key"); + + if (ioctl(fd, PEFS_SETKEY, &k) == -1) { + warn("cannot set key"); + error = EX_OSERR; } - bzero(&k, sizeof(k)); + close(fd); - return (0); - pefs_usage(); - - return (0); + return (error); } static int @@ -156,11 +313,7 @@ { int fd; - if (argc != 1) { - if (argc == 0) - warnx("missing filesystem argument"); - else if (getopt(argc, argv, "") == -1) - warnx("too many arguments"); + if (!checkargs_fs(argc, argv)) { pefs_usage(); } @@ -177,17 +330,22 @@ } static int -pefs_status(int argc, char *argv[]) +pefs_showkeys(int argc, char *argv[]) { struct pefs_xkey k; - char buf[PEFS_KEYID_SIZE * 2 + 1]; - int fd, i; + int chain, fd, i; + + chain = 1; + while ((i = getopt(argc, argv, "")) != -1) + switch(i) { + case '?': + default: + pefs_usage(); + } + argc -= optind; + argv += optind; - if (argc != 1) { - if (argc == 0) - warnx("missing filesystem argument"); - else if (getopt(argc, argv, "") == -1) - warnx("too many arguments"); + if (!checkargs_fs(argc, argv)) { pefs_usage(); } @@ -205,11 +363,7 @@ } else { printf("Keys:\n"); while (1) { - for (i = 0; i < PEFS_KEYID_SIZE; i++) { - snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x", - k.pxk_keyid[i] & 0xff); - } - printf("\t%-4d %16s %s\n", k.pxk_index, buf, pefs_alg_name(k.pxk_alg)); + pefs_key_show(&k, k.pxk_index); k.pxk_index++; if (ioctl(fd, PEFS_GETKEY, &k) == -1) break; @@ -217,6 +371,9 @@ } close(fd); + if (chain) { + } + return (0); } @@ -235,14 +392,13 @@ default: pefs_usage(); } - if (argc - optind == 0) { - warnx("missing filesystem argument"); + argc -= optind; + argv += optind; + + if (!checkargs_fs(argc, argv)) { pefs_usage(); } - if (argc - optind > 1) { - warnx("too many arguments"); - pefs_usage(); - } + nargv = malloc((argc + 2) * sizeof(*nargv)); for (i = 0; i < argc; i++) nargv[i + 1] = argv[i]; @@ -251,19 +407,236 @@ if (execv(PATH_UMOUNT, nargv) == -1) errx(EX_OSERR, "exec %s", PATH_UMOUNT); + + return (0); +} + +static int +pefs_setchain(int argc, char *argv[]) +{ + struct pefs_keychain *kc, *kci; + struct { + struct pefs_xkey k; + struct pefs_keyparam kp; + } p[2]; + struct pefs_xkey *k1 = &p[0].k, *k2 = &p[1].k; + 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) + switch(i) { + case 'a': + case 'A': + p[isupper(i) ? 1 : 0].kp.kp_alg = optarg; + break; + case 'p': + case 'P': + 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); + pefs_usage(); + } + break; + case 'k': + case 'K': + p[isupper(i) ? 1 : 0].kp.kp_keyfile = optarg; + break; + default: + pefs_usage(); + } + argc -= optind; + argv += optind; + + + if (!checkargs_fs(argc, argv)) { + bzero(p, sizeof(p)); + pefs_usage(); + } + + error = pefs_key_get(k1, "parent key passphrase", 1, &p[0].kp); + if (error != 0) { + bzero(p, sizeof(p)); + return (error); + } + error = pefs_key_get(k2, "chained key passphrase", 1, &p[1].kp); + if (error != 0) { + bzero(p, sizeof(p)); + 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); + bzero(k1->pxk_key, PEFS_KEY_SIZE); + bzero(k2->pxk_key, PEFS_KEY_SIZE); + errx(EX_DATAERR, "key chain is already set: %016jx -> %016jx", + pefs_keyid_as_int(k1->pxk_keyid), + pefs_keyid_as_int(k2->pxk_keyid)); + } + } + if (kc->kc_next != 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); + exit(EX_DATAERR); + } + + error = pefs_keychain_set(argv[0], k1, k2); + if (error) + return (EX_DATAERR); + return (0); } +static int +pefs_delchain(int argc, char *argv[]) +{ + struct pefs_xkey k; + struct pefs_keyparam kp; + struct pefs_keychain *kc, *kci; + int error, i; + int force = 0; + + pefs_keyparam_init(&kp); + while ((i = getopt(argc, argv, "fpa:i:k:")) != -1) + switch(i) { + case 'f': + force = 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); + pefs_usage(); + } + break; + case 'k': + kp.kp_keyfile = optarg; + break; + default: + pefs_usage(); + } + argc -= optind; + argv += optind; + + if (!checkargs_fs(argc, argv)) { + pefs_usage(); + } + + error = pefs_key_get(&k, NULL, 0, &kp); + if (error != 0) + return (error); + + kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_USE, &k); + if (kc == NULL) { + 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); + if (!force) + break; + } + pefs_keychain_free(kc); + + return (0); +} + +static int +pefs_showchain(int argc, char *argv[]) +{ + struct pefs_xkey k; + struct pefs_keyparam kp; + struct pefs_keychain *kc, *kci; + int error, i; + + pefs_keyparam_init(&kp); + while ((i = getopt(argc, argv, "pa:i: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); + pefs_usage(); + } + break; + case 'k': + kp.kp_keyfile = optarg; + break; + default: + pefs_usage(); + } + argc -= optind; + argv += optind; + + if (!checkargs_fs(argc, argv)) { + pefs_usage(); + } + + error = pefs_key_get(&k, NULL, 0, &kp); + if (error != 0) + return (error); + + kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_USE, &k); + if (kc == NULL) { + bzero(&k, sizeof(k)); + 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); + } + pefs_keychain_free(kc); + + return (0); +} + +static int +pefs_randomchain(int argc __unused, char *argv[] __unused) +{ + return (0); +} + + void pefs_usage(void) { fprintf(stderr, "usage: pefs mount [-o options] target filesystem\n" " pefs unmount [-fv] filesystem\n" - " pefs addkey [-p] [-a alg] [-i iterations] [-k keyfile] filesystem\n" - " pefs setkey [-cp] [-a alg] [-i iterations] [-k keyfile] directory\n" - " pefs delkey [-p] [-a alg] [-i iterations] [-k keyfile] 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 delkey [-cCp] [-a alg] [-i iterations] [-k keyfile] filesystem\n" " pefs flushkeys filesystem\n" - " pefs status filesystem\n"); + " pefs setchain [-pP] [-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" + " [-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 showkeys filesystem\n"); exit(EX_USAGE); } ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#2 (text+ko) ==== @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2009 Gleb Kurtsou. All rights reserved. + * Copyright (c) 2009 Gleb Kurtsou <gk@FreeBSD.org> + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,16 +25,33 @@ * * $FreeBSD$ */ - #define PEFS_ALG_DEFAULT PEFS_ALG_SALSA20 #define PEFS_KDF_ITERATIONS 50000 struct pefs_xkey; +struct pefs_keyparam { + int kp_nopassphrase; + int kp_iterations; + char *kp_keyfile; + char *kp_alg; +}; + +static inline void +pefs_keyparam_init(struct pefs_keyparam *kp) +{ + kp->kp_nopassphrase = 0; + kp->kp_iterations = PEFS_KDF_ITERATIONS; + kp->kp_keyfile = NULL; + kp->kp_alg = NULL; +} + void pefs_usage(void); -int pefs_get_key(struct pefs_xkey *xk, int *pargc, char *argv[]); +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[]); +uintmax_t pefs_keyid_as_int(char *keyid); const char * pefs_alg_name(int alg_id); ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#2 (text+ko) ==== @@ -44,6 +44,8 @@ #include "pefs_ctl.h" +#define PEFS_KEY_PROMPT_DEFAULT "passphrase" + struct algorithm { const char *name; int id; @@ -68,95 +70,76 @@ } int -pefs_get_key(struct pefs_xkey *xk, int *pargc, char *argv[]) +pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify, struct pefs_keyparam *kp) { struct hmac_ctx ctx; struct algorithm *alg; - char buf[BUFSIZ], *p; - char *keyfile = NULL; + char promptbuf[64], buf[BUFSIZ], buf2[BUFSIZ], *p; ssize_t done; - int nopassphrase = 0; - int iterations = PEFS_KDF_ITERATIONS; - int i, fd, xargc = 0, orig_opterr; + int fd, i; xk->pxk_index = -1; xk->pxk_alg = PEFS_ALG_DEFAULT; - orig_opterr = opterr; - opterr = 0; - while ((i = getopt(*pargc, argv, "pi:k:")) != -1) - switch(i) { - case 'a': - for (alg = algs; alg->name != NULL; alg++) { - if (strcmp(optarg, alg->name) == 0) - xk->pxk_alg = alg->id; - } - errx(EX_USAGE, "invalid algorithm %s", optarg); - break; - case 'p': - nopassphrase = 1; - break; - case 'i': - iterations = atoi(optarg); - if (iterations <= 0) { - warnx("invalid iterations argument: %s", optarg); - pefs_usage(); - } - break; - case 'k': - keyfile = optarg; - break; - default: - argv[xargc++] = argv[optind - 1]; + 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; } - if (optind != *pargc) { - if (strcmp(argv[optind - 1], "--") == 0) - optind--; - for (i = optind; i < *pargc; i++) { - argv[xargc++] = argv[i]; - } + errx(EX_USAGE, "invalid algorithm %s", optarg); } - *pargc = xargc; - opterr = orig_opterr; - optind = 0; - optreset = 1; g_eli_crypto_hmac_init(&ctx, NULL, 0); - if (keyfile != NULL && keyfile[0] == '\0') - keyfile = NULL; - if (keyfile == NULL && nopassphrase) { + if (kp->kp_keyfile != NULL && kp->kp_keyfile[0] == '\0') + kp->kp_keyfile = NULL; + if (kp->kp_keyfile == NULL && kp->kp_nopassphrase) { warnx("no key components given"); pefs_usage(); } - if (keyfile != NULL) { - if (strcmp(keyfile, "-") == 0) + if (kp->kp_keyfile != NULL) { + if (strcmp(kp->kp_keyfile, "-") == 0) fd = STDIN_FILENO; else { - fd = open(keyfile, O_RDONLY); + fd = open(kp->kp_keyfile, O_RDONLY); if (fd == -1) - err(EX_IOERR, "cannot open keyfile %s", 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); bzero(buf, sizeof(buf)); if (done == -1) - err(EX_IOERR, "cannot read keyfile %s", keyfile); + err(EX_IOERR, "cannot read keyfile %s", kp->kp_keyfile); if (fd != STDIN_FILENO) close(fd); } - if (!nopassphrase) { - p = readpassphrase("Enter passphrase:", buf, sizeof(buf), - RPP_ECHO_OFF | RPP_REQUIRE_TTY); - if (p == NULL) { + if (!kp->kp_nopassphrase) { + if (verify) + verify = 1; + if (prompt == NULL) + prompt = PEFS_KEY_PROMPT_DEFAULT; + for (i = 0; i <= verify; i++) { + snprintf(promptbuf, sizeof(promptbuf), "%s %s:", + !i ? "Enter" : "Reenter", prompt); + p = readpassphrase(promptbuf, !i ? buf : buf2, BUFSIZ, + RPP_ECHO_OFF | RPP_REQUIRE_TTY); + if (p == NULL) { + bzero(buf, sizeof(buf)); + bzero(buf2, sizeof(buf2)); + errx(EX_DATAERR, "unable to read passphrase"); + } + } + if (verify && strcmp(buf, buf2) != 0) { bzero(buf, sizeof(buf)); - errx(EX_DATAERR, "unable to read passphrase"); + bzero(buf2, sizeof(buf2)); + errx(EX_DATAERR, "passphrases didn't match"); } - if (iterations == 0) { + bzero(buf2, sizeof(buf2)); + 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, iterations); + 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); } bzero(buf, sizeof(buf)); ==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_mount.c#2 (text+ko) ==== @@ -30,28 +30,18 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1992, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)mount_null.c 8.6 (Berkeley) 4/26/95"; -#endif /* * Ancestors: * FreeBSD: head/sbin/mount_nullfs/mount_nullfs.c 152670 2005-11-21 22:51:16Z rodrigc */ -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/mount.h> #include <sys/uio.h> +#include <inttypes.h> #include <err.h> #include <stdio.h> #include <stdlib.h> ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#5 (text+ko) ==== @@ -119,6 +119,7 @@ case PEFS_ALG_SALSA20: break; default: + printf("pefs: unknown algorithm %d\n", alg); return (NULL); } ==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#8 (text+ko) ==== @@ -43,6 +43,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/conf.h> +#include <sys/fcntl.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -104,7 +105,7 @@ } static int -pefs_enccn_create(struct pefs_enccn *pec, struct pefs_key *pk, struct componentname *cnp) +pefs_enccn_create(struct pefs_enccn *pec, struct pefs_key *pk, char *tweak, struct componentname *cnp) { int r; @@ -115,7 +116,10 @@ pefs_enccn_init(pec, NULL, cnp->cn_nameptr, cnp->cn_namelen, cnp); return (0); } - arc4rand(pec->pec_tkey.ptk_tweak, PEFS_TWEAK_SIZE, 0); + if (tweak == NULL) + arc4rand(pec->pec_tkey.ptk_tweak, PEFS_TWEAK_SIZE, 0); + else + memcpy(pec->pec_tkey.ptk_tweak, tweak, PEFS_TWEAK_SIZE); pec->pec_tkey.ptk_key = pk; PEFSDEBUG("%s: pk=%p\n", __func__, pk); pec->pec_buf = uma_zalloc(namei_zone, M_WAITOK); @@ -251,7 +255,7 @@ if (error == ENOENT) { struct pefs_key *dpk = pefs_node_key(VP_TO_PN(dvp)); - error = pefs_enccn_create(pec, dpk, cnp); + error = pefs_enccn_create(pec, dpk, NULL, cnp); pefs_key_release(dpk); } PEFSDEBUG("%s: returning = %d\n", __func__, error); @@ -259,6 +263,22 @@ return (error); } +static inline int +pefs_enccn_lookup_createcopy(struct pefs_enccn *pec, struct pefs_tkey *ptk, struct vnode *dvp, struct componentname *cnp) +{ + int error; + + MPASS(ptk->ptk_key != NULL); + error = pefs_enccn_lookup(pec, dvp, cnp); + PEFSDEBUG("%s: lookup error = %d\n", __func__, error); + if (error == ENOENT) { + error = pefs_enccn_create(pec, ptk->ptk_key, ptk->ptk_tweak, cnp); + } + PEFSDEBUG("%s: returning = %d\n", __func__, error); + + return (error); +} + static int pefs_enccn_get(struct pefs_enccn *pec, struct vnode *vp, struct vnode *dvp, struct componentname *cnp) { @@ -297,14 +317,20 @@ * Recycle vnodes using key pk. * If pk is NULL recycle all vnodes with PN_HASKEY flag set. */ +#define PEFS_FLUSHKEY_ALL 1 + static int -pefs_flushkey(struct mount *mp, struct pefs_key *pk) +pefs_flushkey(struct mount *mp, struct thread *td, int flags, struct pefs_key *pk) { struct vnode *vp, *mvp; struct pefs_node *pn; int error; PEFSDEBUG("pefs_flushkey: pk=%p\n", pk); + + vflush(mp, 0, 0, td); + if ((flags & PEFS_FLUSHKEY_ALL) == 0 && pk == NULL) + goto loop_end; MNT_ILOCK(mp); loop: MNT_VNODE_FOREACH(vp, mp, mvp) { @@ -313,7 +339,7 @@ VI_LOCK(vp); pn = VP_TO_PN(vp); if ((pn->pn_flags & PN_HASKEY) && - (pk == NULL || pn->pn_tkey.ptk_key == pk)) { + ((flags & PEFS_FLUSHKEY_ALL) || pn->pn_tkey.ptk_key == pk)) { >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908011838.n71IcMgW049383>
