diff options
author | cperciva <cperciva@FreeBSD.org> | 2006-02-08 06:52:15 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2006-02-08 06:52:15 +0000 |
commit | b14cd9989e45914ce34f0b31ecc31a16337e76c0 (patch) | |
tree | a9d91a4aef336ec1fe63a8775d2c0f15dd851482 /sbin | |
parent | b07370a680650f0c83bc96ab16d2c401638a2190 (diff) | |
download | FreeBSD-src-b14cd9989e45914ce34f0b31ecc31a16337e76c0.zip FreeBSD-src-b14cd9989e45914ce34f0b31ecc31a16337e76c0.tar.gz |
Teach gbde(8) to use a key file in addition to a passphrase. This
makes it practical to use GBDE for "something you have plus something
you know" security together with a USB flash drive.
Reviewed by: phk
MFC after: 7 days
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/gbde/gbde.8 | 24 | ||||
-rw-r--r-- | sbin/gbde/gbde.c | 86 |
2 files changed, 85 insertions, 25 deletions
diff --git a/sbin/gbde/gbde.8 b/sbin/gbde/gbde.8 index fe3d55d..d9994ea 100644 --- a/sbin/gbde/gbde.8 +++ b/sbin/gbde/gbde.8 @@ -41,6 +41,7 @@ .Nm .Cm attach .Ar destination +.Op Fl k Ar keyfile .Op Fl l Ar lockfile .Op Fl p Ar pass-phrase .Nm @@ -51,25 +52,30 @@ .Ar destination .Op Fl i .Op Fl f Ar filename +.Op Fl K Ar new-keyfile .Op Fl L Ar new-lockfile .Op Fl P Ar new-pass-phrase .Nm .Cm setkey .Ar destination .Op Fl n Ar key +.Op Fl k Ar keyfile .Op Fl l Ar lockfile .Op Fl p Ar pass-phrase +.Op Fl K Ar new-keyfile .Op Fl L Ar new-lockfile .Op Fl P Ar new-pass-phrase .Nm .Cm nuke .Ar destination .Op Fl n Ar key +.Op Fl k Ar keyfile .Op Fl l Ar lockfile .Op Fl p Ar pass-phrase .Nm .Cm destroy .Ar destination +.Op Fl k Ar keyfile .Op Fl l Ar lockfile .Op Fl p Ar pass-phrase .Sh DESCRIPTION @@ -180,6 +186,24 @@ Be aware that using this option may expose the pass-phrase to other users who happen to run .Xr ps 1 or similar while the command is running. +.Pp +The +.Fl k Ar keyfile +argument specifies a key file to be used in combination with the +pass-phrase (whether the pass-phrase is specified on the command line +or entered from the terminal) for opening the device. +The device will only be opened if the contents of the key file and the +pass-phrase are both correct. +.Pp +The +.Fl K Ar new-keyfile +argument can be used to specify a new key file to the +.Cm init +and +.Cm setkey +subcommands. +If not specified, no key file will be used (even if one was previously +used). .Sh EXAMPLES To initialize a device, using default parameters: .Pp diff --git a/sbin/gbde/gbde.c b/sbin/gbde/gbde.c index 00c8e1c..0a1e740 100644 --- a/sbin/gbde/gbde.c +++ b/sbin/gbde/gbde.c @@ -134,14 +134,16 @@ usage(void) { (void)fprintf(stderr, -"usage: gbde attach destination [-l lockfile] [-p pass-phrase]\n" +"usage: gbde attach destination [-k keyfile] [-l lockfile] [-p pass-phrase]\n" " gbde detach destination\n" -" gbde init destination [-i] [-f filename] [-L new-lockfile]\n" -" [-P new-pass-phrase]\n" -" gbde setkey destination [-n key] [-l lockfile] [-p pass-phrase]\n" +" gbde init destination [-i] [-f filename] [-K new-keyfile]\n" " [-L new-lockfile] [-P new-pass-phrase]\n" -" gbde nuke destination [-n key] [-l lockfile] [-p pass-phrase]\n" -" gbde destroy destination [-l lockfile] [-p pass-phrase]\n"); +" gbde setkey destination [-n key]\n" +" [-k keyfile] [-l lockfile] [-p pass-phrase]\n" +" [-K new-keyfile] [-L new-lockfile] [-P new-pass-phrase]\n" +" gbde nuke destination [-n key]\n" +" [-k keyfile] [-l lockfile] [-p pass-phrase]\n" +" gbde destroy destination [-k keyfile] [-l lockfile] [-p pass-phrase]\n"); exit(1); } @@ -195,42 +197,67 @@ reset_passphrase(struct g_bde_softc *sc) } static void -setup_passphrase(struct g_bde_softc *sc, int sure, const char *input) +setup_passphrase(struct g_bde_softc *sc, int sure, const char *input, + const char *keyfile) { - char buf1[BUFSIZ], buf2[BUFSIZ], *p; + char buf1[BUFSIZ + SHA512_DIGEST_LENGTH]; + char buf2[BUFSIZ + SHA512_DIGEST_LENGTH]; + char *p; + int kfd, klen, bpos = 0; + + if (keyfile != NULL) { + /* Read up to BUFSIZ bytes from keyfile */ + kfd = open(keyfile, O_RDONLY, 0); + if (kfd < 0) + err(1, "%s", keyfile); + klen = read(kfd, buf1, BUFSIZ); + if (klen == -1) + err(1, "%s", keyfile); + close(kfd); + + /* Prepend the passphrase with the hash of the key read */ + g_bde_hash_pass(sc, buf1, klen); + memcpy(buf1, sc->sha2, SHA512_DIGEST_LENGTH); + memcpy(buf2, sc->sha2, SHA512_DIGEST_LENGTH); + bpos = SHA512_DIGEST_LENGTH; + } if (input != NULL) { - g_bde_hash_pass(sc, input, strlen(input)); + if (strlen(input) >= BUFSIZ) + errx(1, "Passphrase too long"); + strcpy(buf1 + bpos, input); + + g_bde_hash_pass(sc, buf1, strlen(buf1 + bpos) + bpos); memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH); return; } for (;;) { p = readpassphrase( sure ? "Enter new passphrase:" : "Enter passphrase: ", - buf1, sizeof buf1, + buf1 + bpos, sizeof buf1 - bpos, RPP_ECHO_OFF | RPP_REQUIRE_TTY); if (p == NULL) err(1, "readpassphrase"); if (sure) { p = readpassphrase("Reenter new passphrase: ", - buf2, sizeof buf2, + buf2 + bpos, sizeof buf2 - bpos, RPP_ECHO_OFF | RPP_REQUIRE_TTY); if (p == NULL) err(1, "readpassphrase"); - if (strcmp(buf1, buf2)) { + if (strcmp(buf1 + bpos, buf2 + bpos)) { printf("They didn't match.\n"); continue; } } - if (strlen(buf1) < 3) { + if (strlen(buf1 + bpos) < 3) { printf("Too short passphrase.\n"); continue; } break; } - g_bde_hash_pass(sc, buf1, strlen(buf1)); + g_bde_hash_pass(sc, buf1, strlen(buf1 + bpos) + bpos); memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH); } @@ -708,6 +735,7 @@ int main(int argc, char **argv) { const char *opts; + const char *k_opt, *K_opt; const char *l_opt, *L_opt; const char *p_opt, *P_opt; const char *f_opt; @@ -730,26 +758,26 @@ main(int argc, char **argv) doopen = 0; if (!strcmp(argv[1], "attach")) { action = ACT_ATTACH; - opts = "l:p:"; + opts = "k:l:p:"; } else if (!strcmp(argv[1], "detach")) { action = ACT_DETACH; opts = ""; } else if (!strcmp(argv[1], "init")) { action = ACT_INIT; doopen = 1; - opts = "f:iL:P:"; + opts = "f:iK:L:P:"; } else if (!strcmp(argv[1], "setkey")) { action = ACT_SETKEY; doopen = 1; - opts = "l:L:n:p:P:"; + opts = "k:K:l:L:n:p:P:"; } else if (!strcmp(argv[1], "destroy")) { action = ACT_DESTROY; doopen = 1; - opts = "l:p:"; + opts = "k:l:p:"; } else if (!strcmp(argv[1], "nuke")) { action = ACT_NUKE; doopen = 1; - opts = "l:n:p:"; + opts = "k:l:n:p:"; } else { usage(); } @@ -762,6 +790,8 @@ main(int argc, char **argv) p_opt = NULL; P_opt = NULL; + k_opt = NULL; + K_opt = NULL; l_opt = NULL; L_opt = NULL; f_opt = NULL; @@ -775,6 +805,12 @@ main(int argc, char **argv) break; case 'i': i_opt = !i_opt; + case 'k': + k_opt = optarg; + break; + case 'K': + K_opt = optarg; + break; case 'l': l_opt = optarg; break; @@ -819,7 +855,7 @@ main(int argc, char **argv) gl = &sc.key; switch(action) { case ACT_ATTACH: - setup_passphrase(&sc, 0, p_opt); + setup_passphrase(&sc, 0, p_opt, k_opt); cmd_attach(&sc, dest, l_opt); break; case ACT_DETACH: @@ -827,26 +863,26 @@ main(int argc, char **argv) break; case ACT_INIT: cmd_init(gl, dfd, f_opt, i_opt, L_opt); - setup_passphrase(&sc, 1, P_opt); + setup_passphrase(&sc, 1, P_opt, K_opt); cmd_write(gl, &sc, dfd, 0, L_opt); break; case ACT_SETKEY: - setup_passphrase(&sc, 0, p_opt); + setup_passphrase(&sc, 0, p_opt, k_opt); cmd_open(&sc, dfd, l_opt, &nkey); if (n_opt == 0) n_opt = nkey + 1; - setup_passphrase(&sc, 1, P_opt); + setup_passphrase(&sc, 1, P_opt, K_opt); cmd_write(gl, &sc, dfd, n_opt - 1, L_opt); break; case ACT_DESTROY: - setup_passphrase(&sc, 0, p_opt); + setup_passphrase(&sc, 0, p_opt, k_opt); cmd_open(&sc, dfd, l_opt, &nkey); cmd_destroy(gl, nkey); reset_passphrase(&sc); cmd_write(gl, &sc, dfd, nkey, l_opt); break; case ACT_NUKE: - setup_passphrase(&sc, 0, p_opt); + setup_passphrase(&sc, 0, p_opt, k_opt); cmd_open(&sc, dfd, l_opt, &nkey); if (n_opt == 0) n_opt = nkey + 1; |