summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/geom/bde/g_bde.h5
-rw-r--r--sys/geom/bde/g_bde_crypt.c53
-rw-r--r--sys/geom/bde/g_bde_lock.c10
3 files changed, 26 insertions, 42 deletions
diff --git a/sys/geom/bde/g_bde.h b/sys/geom/bde/g_bde.h
index 016db7b052db..6354411c4119 100644
--- a/sys/geom/bde/g_bde.h
+++ b/sys/geom/bde/g_bde.h
@@ -93,8 +93,9 @@ struct g_bde_key {
uint32_t flags;
/* 1 = lockfile in sector 0 */
uint8_t hash[16];
- uint8_t spare[48];
- uint8_t key[G_BDE_MKEYLEN];
+ uint8_t salt[16];
+ uint8_t spare[32];
+ uint8_t mkey[G_BDE_MKEYLEN];
/* Non-stored help-fields */
uint64_t zone_width; /* On-disk width of zone */
uint64_t zone_cont; /* Payload width of zone */
diff --git a/sys/geom/bde/g_bde_crypt.c b/sys/geom/bde/g_bde_crypt.c
index ee795f5288bc..6cabb521ec49 100644
--- a/sys/geom/bde/g_bde_crypt.c
+++ b/sys/geom/bde/g_bde_crypt.c
@@ -104,54 +104,35 @@ AES_decrypt(cipherInstance *ci, keyInstance *ki, void *in, void *out, u_int len)
* significantly help an attack on other kkeys and in particular does not
* weaken or compromised the mkey.
*
- * We do this by cherry-picking characters out of the mkey, feeding these to
- * MD5 with the sector offset in the middle and using the MD5 hash as kkey.
+ * First we MD5 hash the sectornumber with the salt from the lock sector.
+ * The salt prevents the precalculation and statistical analysis of the MD5
+ * output which would be possible if we only gave it the sectornumber.
*
- * The MD5 only acts as a "diode" against brute-force reversal, it offsers no
- * protection if the input to MD5 is predictable or insufficiently uncorrelated
- * from sector to sector.
+ * The MD5 hash is used to pick out 16 bytes from the masterkey, which
+ * are then hashed with MD5 together with the sector number.
*
- * The amount of entropy in a sector number is very low, and the amount of
- * entropy between two sector numbers is even lower, (only slightly higher than
- * one bit), so we rely heavily on the mkey to make the cherry picking non-
- * linear and irreversible.
- *
- * This strong dependency on the mkey is very desirable, but the low amount
- * of entropy from the sector number means that the algorithm is vulnerable
- * to mkeys which has a lumpy histogram of byte values or little entropy.
- *
- * If you read this comment in order to find a weak spot or the best way to
- * attack GBDE, you have probably come to the right place. Good luck.
+ * The resulting MD5 hash is the kkey.
*/
static void
g_bde_kkey(struct g_bde_softc *sc, keyInstance *ki, int dir, off_t sector)
{
- u_int u, v, w, t;
+ u_int t;
MD5_CTX ct;
- u_char buf[16], c;
+ u_char buf[16];
MD5Init(&ct);
- w = sector /= sc->sectorsize;
- v = w % 211; /* A prime slightly smaller than G_BDE_MKEYLEN */
- u = w % 19; /* A small prime */
- for (t = 0; t < G_BDE_SKEYLEN; t++) {
- u %= G_BDE_MKEYLEN;
- v %= G_BDE_MKEYLEN;
- c = sc->key.key[u] ^ sc->key.key[v];
- MD5Update(&ct, &c, 1);
- v += c + t;
- u += sc->key.key[c];
- if (w & 1)
- v += 13; /* A small prime */
- else
- u += 131; /* A prime roughly G_BDE_MKEYLEN / 2 */
- w >>= 1;
- if (t == G_BDE_SKEYLEN / 2)
+ MD5Update(&ct, sc->key.salt, 8);
+ MD5Update(&ct, (void *)&sector, sizeof sector);
+ MD5Update(&ct, sc->key.salt + 8, 8);
+ MD5Final(buf, &ct);
+
+ MD5Init(&ct);
+ for (t = 0; t < 16; t++) {
+ MD5Update(&ct, &sc->key.mkey[buf[t]], 1);
+ if (t == 8)
MD5Update(&ct, (void *)&sector, sizeof sector);
}
- w = v = u - 0;
- MD5Update(&ct, (void *)&sector, sizeof sector);
MD5Final(buf, &ct);
bzero(&ct, sizeof ct);
AES_makekey(ki, dir, G_BDE_KKEYBITS, buf);
diff --git a/sys/geom/bde/g_bde_lock.c b/sys/geom/bde/g_bde_lock.c
index 281152d95bdc..29c880c102e1 100644
--- a/sys/geom/bde/g_bde_lock.c
+++ b/sys/geom/bde/g_bde_lock.c
@@ -88,7 +88,8 @@ g_bde_encode_lock(struct g_bde_key *gl, u_char *ptr)
g_enc_le8(ptr + 64, gl->lsector[2]);
g_enc_le8(ptr + 72, gl->lsector[3]);
bcopy(gl->spare, ptr + 80, sizeof gl->spare);
- bcopy(gl->key, ptr + 128, sizeof gl->key);
+ bcopy(gl->salt, ptr + 112, sizeof gl->salt);
+ bcopy(gl->mkey, ptr + 128, sizeof gl->mkey);
}
void
@@ -105,7 +106,8 @@ g_bde_decode_lock(struct g_bde_key *gl, u_char *ptr)
gl->lsector[2] = g_dec_le8(ptr + 64);
gl->lsector[3] = g_dec_le8(ptr + 72);
bcopy(ptr + 80, gl->spare, sizeof gl->spare);
- bcopy(ptr + 128, gl->key, sizeof gl->key);
+ bcopy(ptr + 112, gl->salt, sizeof gl->salt);
+ bcopy(ptr + 128, gl->mkey, sizeof gl->mkey);
}
/*
@@ -303,8 +305,8 @@ g_bde_decrypt_lockx(struct g_bde_softc *sc, u_char *sbox, u_char *meta, off_t me
g_free(buf);
off[1] = 0;
- for (i = 0; i < (int)sizeof(gl->key); i++)
- off[1] += gl->key[i];
+ for (i = 0; i < (int)sizeof(gl->mkey); i++)
+ off[1] += gl->mkey[i];
if (off[1] == 0) {
off[0] = 0;