summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/geom/eli/g_eli.c2
-rw-r--r--sys/geom/eli/g_eli.h17
-rw-r--r--sys/geom/eli/g_eli_ctl.c6
-rw-r--r--sys/geom/eli/g_eli_key_cache.c8
4 files changed, 27 insertions, 6 deletions
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c
index 72f93f4..6819fcc 100644
--- a/sys/geom/eli/g_eli.c
+++ b/sys/geom/eli/g_eli.c
@@ -726,6 +726,8 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp,
(sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
sc->sc_flags |= G_ELI_FLAG_FIRST_KEY;
}
+ if (md->md_version < G_ELI_VERSION_07)
+ sc->sc_flags |= G_ELI_FLAG_ENC_IVKEY;
sc->sc_ealgo = md->md_ealgo;
sc->sc_nkey = nkey;
diff --git a/sys/geom/eli/g_eli.h b/sys/geom/eli/g_eli.h
index a5aad8f..835a1b3 100644
--- a/sys/geom/eli/g_eli.h
+++ b/sys/geom/eli/g_eli.h
@@ -68,6 +68,8 @@
* 5 - Added multiple encrypton keys and AES-XTS support.
* 6 - Fixed usage of multiple keys for authenticated providers (the
* G_ELI_FLAG_FIRST_KEY flag will be set for older versions).
+ * 7 - Encryption keys are now generated from the Data Key and not from the
+ * IV Key (the G_ELI_FLAG_ENC_IVKEY flag will be set for older versions).
*/
#define G_ELI_VERSION_00 0
#define G_ELI_VERSION_01 1
@@ -76,7 +78,8 @@
#define G_ELI_VERSION_04 4
#define G_ELI_VERSION_05 5
#define G_ELI_VERSION_06 6
-#define G_ELI_VERSION G_ELI_VERSION_06
+#define G_ELI_VERSION_07 7
+#define G_ELI_VERSION G_ELI_VERSION_07
/* ON DISK FLAGS. */
/* Use random, onetime keys. */
@@ -104,6 +107,8 @@
#define G_ELI_FLAG_SUSPEND 0x00100000
/* Provider uses first encryption key. */
#define G_ELI_FLAG_FIRST_KEY 0x00200000
+/* Provider uses IV-Key for encryption key generation. */
+#define G_ELI_FLAG_ENC_IVKEY 0x00400000
#define G_ELI_NEW_BIO 255
@@ -237,7 +242,7 @@ eli_metadata_encode_v0(struct g_eli_metadata *md, u_char **datap)
*datap = p;
}
static __inline void
-eli_metadata_encode_v1v2v3v4v5v6(struct g_eli_metadata *md, u_char **datap)
+eli_metadata_encode_v1v2v3v4v5v6v7(struct g_eli_metadata *md, u_char **datap)
{
u_char *p;
@@ -275,7 +280,8 @@ eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
case G_ELI_VERSION_04:
case G_ELI_VERSION_05:
case G_ELI_VERSION_06:
- eli_metadata_encode_v1v2v3v4v5v6(md, &p);
+ case G_ELI_VERSION_07:
+ eli_metadata_encode_v1v2v3v4v5v6v7(md, &p);
break;
default:
#ifdef _KERNEL
@@ -315,7 +321,7 @@ eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md)
}
static __inline int
-eli_metadata_decode_v1v2v3v4v5v6(const u_char *data, struct g_eli_metadata *md)
+eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md)
{
MD5_CTX ctx;
const u_char *p;
@@ -357,7 +363,8 @@ eli_metadata_decode(const u_char *data, struct g_eli_metadata *md)
case G_ELI_VERSION_04:
case G_ELI_VERSION_05:
case G_ELI_VERSION_06:
- error = eli_metadata_decode_v1v2v3v4v5v6(data, md);
+ case G_ELI_VERSION_07:
+ error = eli_metadata_decode_v1v2v3v4v5v6v7(data, md);
break;
default:
error = EOPNOTSUPP;
diff --git a/sys/geom/eli/g_eli_ctl.c b/sys/geom/eli/g_eli_ctl.c
index 65672d5..520d237 100644
--- a/sys/geom/eli/g_eli_ctl.c
+++ b/sys/geom/eli/g_eli_ctl.c
@@ -1020,6 +1020,12 @@ g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb)
/* Compatible. */
break;
}
+ if (G_ELI_VERSION == G_ELI_VERSION_07 &&
+ (*version == G_ELI_VERSION_05 ||
+ *version == G_ELI_VERSION_06)) {
+ /* Compatible. */
+ break;
+ }
gctl_error(req, "Userland and kernel parts are out of sync.");
return;
}
diff --git a/sys/geom/eli/g_eli_key_cache.c b/sys/geom/eli/g_eli_key_cache.c
index 33a2ca9..d7158e4 100644
--- a/sys/geom/eli/g_eli_key_cache.c
+++ b/sys/geom/eli/g_eli_key_cache.c
@@ -91,14 +91,20 @@ RB_GENERATE(g_eli_key_tree, g_eli_key, gek_link, g_eli_key_cmp);
static void
g_eli_key_fill(struct g_eli_softc *sc, struct g_eli_key *key, uint64_t keyno)
{
+ const uint8_t *ekey;
struct {
char magic[4];
uint8_t keyno[8];
} __packed hmacdata;
+ if ((sc->sc_flags & G_ELI_FLAG_ENC_IVKEY) != 0)
+ ekey = sc->sc_mkey;
+ else
+ ekey = sc->sc_ekey;
+
bcopy("ekey", hmacdata.magic, 4);
le64enc(hmacdata.keyno, keyno);
- g_eli_crypto_hmac(sc->sc_mkey, G_ELI_MAXKEYLEN, (uint8_t *)&hmacdata,
+ g_eli_crypto_hmac(ekey, G_ELI_MAXKEYLEN, (uint8_t *)&hmacdata,
sizeof(hmacdata), key->gek_key, 0);
key->gek_keyno = keyno;
key->gek_count = 0;
OpenPOWER on IntegriCloud