summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-11-04 09:27:01 +0000
committerphk <phk@FreeBSD.org>2002-11-04 09:27:01 +0000
commit16874ad9231c653cc0923d057079cb01dc655144 (patch)
treef63c9d7688c826251a2cc69a8cbf9eace1f02f75 /sbin
parent8f58d0f543eb1d2ede1aa0736e9fe5e958cba1d6 (diff)
downloadFreeBSD-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')
-rw-r--r--sbin/gbde/Makefile7
-rw-r--r--sbin/gbde/gbde.834
-rw-r--r--sbin/gbde/gbde.c113
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, &sectorsize);
+ 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)
OpenPOWER on IntegriCloud