diff options
author | phk <phk@FreeBSD.org> | 2002-11-04 09:27:01 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2002-11-04 09:27:01 +0000 |
commit | 16874ad9231c653cc0923d057079cb01dc655144 (patch) | |
tree | f63c9d7688c826251a2cc69a8cbf9eace1f02f75 /sbin/gbde | |
parent | 8f58d0f543eb1d2ede1aa0736e9fe5e958cba1d6 (diff) | |
download | FreeBSD-src-16874ad9231c653cc0923d057079cb01dc655144.zip FreeBSD-src-16874ad9231c653cc0923d057079cb01dc655144.tar.gz |
Run a revision on the GBDE encryption facility.
Replace ARC4 with SHA2-512.
Change lock-structure encoding to use random ordering rather for obscurity.
Encrypt lock-structure with AES/256 instead of AES/128.
Change kkey derivation to be MD5 hash based.
Watch for malloc(M_NOWAIT) failures and ditch our cache when they happen.
Remove clause 3 of the license with NAI Labs consent.
Many thanks to "Lucky Green" <shamrock@cypherpunks.to> and "David
Wagner" <daw@cs.berkeley.edu>, for code reading, inputs and
suggestions.
This code has still not been stared at for 10 years by a gang of
hard-core cryptographers. Discretion advised.
NB: These changes result in the on-disk format changing: dump/restore needed.
Sponsored by: DARPA & NAI Labs.
Diffstat (limited to 'sbin/gbde')
-rw-r--r-- | sbin/gbde/Makefile | 7 | ||||
-rw-r--r-- | sbin/gbde/gbde.8 | 34 | ||||
-rw-r--r-- | sbin/gbde/gbde.c | 113 |
3 files changed, 106 insertions, 48 deletions
diff --git a/sbin/gbde/Makefile b/sbin/gbde/Makefile index 87488e0..906f196 100644 --- a/sbin/gbde/Makefile +++ b/sbin/gbde/Makefile @@ -5,11 +5,14 @@ SRCS= gbde.c template.c SRCS+= geom_enc.c SRCS+= rijndael-alg-fst.c SRCS+= rijndael-api-fst.c +SRCS+= sha2.c SRCS+= g_bde_lock.c CFLAGS+= -I${.CURDIR}/../../sys -.PATH: ${.CURDIR}/../../sys/geom ${.CURDIR}/../../sys/geom/bde \ - ${.CURDIR}/../../sys/crypto/rijndael +.PATH: ${.CURDIR}/../../sys/geom \ + ${.CURDIR}/../../sys/geom/bde \ + ${.CURDIR}/../../sys/crypto/rijndael \ + ${.CURDIR}/../../sys/crypto/sha2 CLEANFILES+= template.c diff --git a/sbin/gbde/gbde.8 b/sbin/gbde/gbde.8 index 2b1ec86..0ea3eef 100644 --- a/sbin/gbde/gbde.8 +++ b/sbin/gbde/gbde.8 @@ -16,9 +16,6 @@ .\" 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. -.\" 3. The names of the authors may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -69,9 +66,21 @@ .Ar destination .Op Fl n Ar key .Op Fl l Ar lockfile +.Op Fl p Ar pass-phrase .Op Fl L Ar lockfile +.Sh NOTICE +.Pp +Please be aware that this code has not yet received much review +and analysis by qualified cryptographers and therefore should be considered +a slightly suspect experimental facility. +.Pp +We cannot at this point guarantee that the on-disk format will not change +in response to reviews or bug-fixes, so potential users are adviced to +be prepared that +.Xr dump 8 / +.Xr restore 8 +based migrations may be called for in the future. .Sh DESCRIPTION -The .Nm program is the only official operation and management interface for the .Xr gbde 4 @@ -128,15 +137,27 @@ argument specifies the pass-phrase used to opening the device. If not specified, the controlling terminal will be used to prompt the user for the pass-phrase. +Be aware that using this option may exposed the pass-phrase to other +users who happen to run +.Xr +ps 1 +or similar while the command is running. .Pp The .Fl P Ar new-pass-phrase argument can be used to specify the new pass-phrase to the +.Cm init +and .Cm setkey -subcommand. +subcommands. If not specified, the user is prompted for the new pass-phrase on the controlling terminal. +Be aware that using this option may exposed the pass-phrase to other +users who happen to run +.Xr +ps 1 +or similar while the command is running. .Sh EXAMPLES To initialize a device, using default parameters: .Dl # gbde init /dev/ad0s1f -l /etc/ad0s1f.lock @@ -168,3 +189,6 @@ under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS research program. .Sh AUTHORS .An "Poul-Henning Kamp" Aq phk@FreeBSD.org +.Sh BUGS +The cryptographic algorithms and the over-all design has not been +attacked mercilessly for over 10 years by a gang or cryptoanalysts. diff --git a/sbin/gbde/gbde.c b/sbin/gbde/gbde.c index 4c427a6..a634c9c 100644 --- a/sbin/gbde/gbde.c +++ b/sbin/gbde/gbde.c @@ -16,9 +16,6 @@ * 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. - * 3. The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -51,13 +48,50 @@ #include <libutil.h> #include <sys/errno.h> #include <sys/disk.h> +#include <sys/stat.h> #include <crypto/rijndael/rijndael.h> +#include <crypto/sha2/sha2.h> + +#define KASSERT(foo, bar) do { if(!(foo)) { warn bar ; exit (1); } } while (0) #include <geom/geom.h> #include <geom/bde/g_bde.h> extern const char template[]; + +#if 0 +static void +g_hexdump(void *ptr, int length) +{ + int i, j, k; + unsigned char *cp; + + cp = ptr; + for (i = 0; i < length; i+= 16) { + printf("%04x ", i); + for (j = 0; j < 16; j++) { + k = i + j; + if (k < length) + printf(" %02x", cp[k]); + else + printf(" "); + } + printf(" |"); + for (j = 0; j < 16; j++) { + k = i + j; + if (k >= length) + printf(" "); + else if (cp[k] >= ' ' && cp[k] <= '~') + printf("%c", cp[k]); + else + printf("."); + } + printf("|\n"); + } +} +#endif + static void __dead2 usage(const char *reason) { @@ -114,14 +148,13 @@ random_bits(void *p, u_int len) } /* XXX: not nice */ -static u_char sbox[256]; +static u_char sha2[SHA512_DIGEST_LENGTH]; static void reset_passphrase(struct g_bde_softc *sc) { - memcpy(sc->arc4_sbox, sbox, 256); - sc->arc4_i = sc->arc4_j = 0; + memcpy(sc->sha2, sha2, SHA512_DIGEST_LENGTH); } static void @@ -130,8 +163,8 @@ setup_passphrase(struct g_bde_softc *sc, int sure, const char *input) char buf1[BUFSIZ], buf2[BUFSIZ], *p; if (input != NULL) { - g_bde_arc4_seed(sc, input, strlen(input)); - memcpy(sbox, sc->arc4_sbox, 256); + g_bde_hash_pass(sc, input, strlen(input)); + memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH); return; } for (;;) { @@ -160,12 +193,12 @@ setup_passphrase(struct g_bde_softc *sc, int sure, const char *input) } break; } - g_bde_arc4_seed(sc, buf1, strlen(buf1)); - memcpy(sbox, sc->arc4_sbox, 256); + g_bde_hash_pass(sc, buf1, strlen(buf1)); + memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH); } static void -encrypt_sector(void *d, int len, void *key) +encrypt_sector(void *d, int len, int klen, void *key) { keyInstance ki; cipherInstance ci; @@ -174,7 +207,7 @@ encrypt_sector(void *d, int len, void *key) error = rijndael_cipherInit(&ci, MODE_CBC, NULL); if (error <= 0) errx(1, "rijndael_cipherInit=%d", error); - error = rijndael_makeKey(&ki, DIR_ENCRYPT, 128, key); + error = rijndael_makeKey(&ki, DIR_ENCRYPT, klen, key); if (error <= 0) errx(1, "rijndael_makeKeY=%d", error); error = rijndael_blockEncrypt(&ci, &ki, d, len * 8, d); @@ -205,12 +238,12 @@ cmd_attach(const struct g_bde_softc *sc, const char *dest, const char *lfile) ffd = open(lfile, O_RDONLY, 0); if (ffd < 0) err(1, lfile); - read(ffd, buf + 256, 16); + read(ffd, buf + sizeof(sc->sha2), 16); close(ffd); } else { - memset(buf + 256, 0, 16); + memset(buf + sizeof(sc->sha2), 0, 16); } - memcpy(buf, sc->arc4_sbox, 256); + memcpy(buf, sc->sha2, sizeof(sc->sha2)); i = ioctl(gfd, GEOMCONFIGGEOM, &gcg); if (i != 0) @@ -241,12 +274,28 @@ cmd_detach(const char *dest) } static void -cmd_open(struct g_bde_softc *sc, int dfd __unused, const char *l_opt, u_int *nkey) +cmd_open(struct g_bde_softc *sc, int dfd , const char *l_opt, u_int *nkey) { int error; int ffd; u_char keyloc[16]; - + u_int sectorsize; + off_t mediasize; + struct stat st; + + error = ioctl(dfd, DIOCGSECTORSIZE, §orsize); + if (error) + sectorsize = 512; + error = ioctl(dfd, DIOCGMEDIASIZE, &mediasize); + if (error) { + error = fstat(dfd, &st); + if (error == 0 && S_ISREG(st.st_mode)) + mediasize = st.st_size; + else + error = ENOENT; + } + if (error) + mediasize = (off_t)-1; if (l_opt != NULL) { ffd = open(l_opt, O_RDONLY, 0); if (ffd < 0) @@ -257,8 +306,8 @@ cmd_open(struct g_bde_softc *sc, int dfd __unused, const char *l_opt, u_int *nke memset(keyloc, 0, sizeof keyloc); } - error = g_bde_decrypt_lock(sc, sbox, keyloc, 0xffffffff, - 512, nkey); + error = g_bde_decrypt_lock(sc, sc->sha2, keyloc, mediasize, + sectorsize, nkey); if (error == ENOENT) errx(1, "Lock was destroyed."); if (error == ESRCH) @@ -294,12 +343,10 @@ cmd_nuke(struct g_bde_key *gl, int dfd , int key) static void cmd_write(struct g_bde_key *gl, struct g_bde_softc *sc, int dfd , int key, const char *l_opt) { - char buf[BUFSIZ]; int i, ffd; uint64_t off[2]; u_char keyloc[16]; u_char *sbuf, *q; - MD5_CTX c; off_t offset, offset2; sbuf = malloc(gl->sectorsize); @@ -352,32 +399,16 @@ cmd_write(struct g_bde_key *gl, struct g_bde_softc *sc, int dfd , int key, const err(1, "malloc"); random_bits(sbuf, gl->sectorsize); - /* Fill in the hash field with something we can recognize again */ - g_bde_arc4_seq(sc, buf, 16); - MD5Init(&c); - MD5Update(&c, "0000", 4); /* XXX: for future versioning */ - MD5Update(&c, buf, 16); - MD5Final(gl->hash, &c); - /* Fill random bits in the spare field */ random_bits(gl->spare, sizeof(gl->spare)); /* Encode the structure where we want it */ q = sbuf + (off[0] % gl->sectorsize); - g_bde_encode_lock(gl, q); - - /* - * The encoded structure likely contains long sequences of zeros - * which stick out as a sore thumb, so we XOR with key-material - * to make it harder to recognize in a brute-force attack - */ - g_bde_arc4_seq(sc, buf, G_BDE_LOCKSIZE); - for (i = 0; i < G_BDE_LOCKSIZE; i++) - q[i] ^= buf[i]; - - g_bde_arc4_seq(sc, buf, 16); + i = g_bde_encode_lock(sc, gl, q); + if (i < 0) + errx(1, "programming error encoding lock"); - encrypt_sector(q, G_BDE_LOCKSIZE, buf); + encrypt_sector(q, G_BDE_LOCKSIZE, 256, sc->sha2 + 16); offset = gl->lsector[key] & ~(gl->sectorsize - 1); offset2 = lseek(dfd, offset, SEEK_SET); if (offset2 != offset) |