diff options
author | pjd <pjd@FreeBSD.org> | 2011-05-08 09:17:56 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2011-05-08 09:17:56 +0000 |
commit | f18109261254e7d3e5f5dfcf14360c385941a4cc (patch) | |
tree | 8282dd55c9b5a8d44c447f22673a717a77e2ee3e /sys/geom | |
parent | f237c9d1bd2c10286b14fbc7c53110782a9ec164 (diff) | |
download | FreeBSD-src-f18109261254e7d3e5f5dfcf14360c385941a4cc.zip FreeBSD-src-f18109261254e7d3e5f5dfcf14360c385941a4cc.tar.gz |
When support for multiple encryption keys was committed, GELI integrity mode
was not updated to pass CRD_F_KEY_EXPLICIT flag to opencrypto. This resulted in
always using first key.
We need to support providers created with this bug, so set special
G_ELI_FLAG_FIRST_KEY flag for GELI provider in integrity mode with version
smaller than 6 and pass the CRD_F_KEY_EXPLICIT flag to opencrypto only if
G_ELI_FLAG_FIRST_KEY doesn't exist.
Reported by: Anton Yuzhaninov <citrin@citrin.ru>
MFC after: 1 week
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/eli/g_eli.c | 12 | ||||
-rw-r--r-- | sys/geom/eli/g_eli.h | 15 | ||||
-rw-r--r-- | sys/geom/eli/g_eli_integrity.c | 2 |
3 files changed, 26 insertions, 3 deletions
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 8b22ee5..cee4166 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -329,7 +329,12 @@ g_eli_newsession(struct g_eli_worker *wr) crie.cri_klen = sc->sc_ekeylen; if (sc->sc_ealgo == CRYPTO_AES_XTS) crie.cri_klen <<= 1; - crie.cri_key = sc->sc_ekey; + if ((sc->sc_flags & G_ELI_FLAG_FIRST_KEY) != 0) { + crie.cri_key = g_eli_key_hold(sc, 0, + LIST_FIRST(&sc->sc_geom->consumer)->provider->sectorsize); + } else { + crie.cri_key = sc->sc_ekey; + } if (sc->sc_flags & G_ELI_FLAG_AUTH) { bzero(&cria, sizeof(cria)); cria.cri_alg = sc->sc_aalgo; @@ -368,6 +373,9 @@ g_eli_newsession(struct g_eli_worker *wr) panic("%s: invalid condition", __func__); } + if ((sc->sc_flags & G_ELI_FLAG_FIRST_KEY) != 0) + g_eli_key_drop(sc, crie.cri_key); + return (error); } @@ -708,6 +716,8 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp, sc->sc_flags |= G_ELI_FLAG_NATIVE_BYTE_ORDER; if (md->md_version < 5) sc->sc_flags |= G_ELI_FLAG_SINGLE_KEY; + if (md->md_version < 6 && (sc->sc_flags & G_ELI_FLAG_AUTH) != 0) + sc->sc_flags |= G_ELI_FLAG_FIRST_KEY; 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 60e0d47..9c96e61 100644 --- a/sys/geom/eli/g_eli.h +++ b/sys/geom/eli/g_eli.h @@ -63,10 +63,19 @@ * 2 - Added G_ELI_FLAG_READONLY. * 3 - Added 'configure' subcommand. * 4 - IV is generated from offset converted to little-endian - * (flag G_ELI_FLAG_NATIVE_BYTE_ORDER will be set for older versions). + * (the G_ELI_FLAG_NATIVE_BYTE_ORDER flag will be set for older versions). * 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). */ -#define G_ELI_VERSION 5 +#define G_ELI_VERSION_00 0 +#define G_ELI_VERSION_01 1 +#define G_ELI_VERSION_02 2 +#define G_ELI_VERSION_03 3 +#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 /* ON DISK FLAGS. */ /* Use random, onetime keys. */ @@ -92,6 +101,8 @@ #define G_ELI_FLAG_SINGLE_KEY 0x00080000 /* Device suspended. */ #define G_ELI_FLAG_SUSPEND 0x00100000 +/* Provider uses first encryption key. */ +#define G_ELI_FLAG_FIRST_KEY 0x00200000 #define G_ELI_NEW_BIO 255 diff --git a/sys/geom/eli/g_eli_integrity.c b/sys/geom/eli/g_eli_integrity.c index 947b8d7..50f2a31 100644 --- a/sys/geom/eli/g_eli_integrity.c +++ b/sys/geom/eli/g_eli_integrity.c @@ -513,6 +513,8 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) crde->crd_skip = sc->sc_alen; crde->crd_len = data_secsize; crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; + if ((sc->sc_flags & G_ELI_FLAG_FIRST_KEY) == 0) + crde->crd_flags |= CRD_F_KEY_EXPLICIT; if (bp->bio_cmd == BIO_WRITE) crde->crd_flags |= CRD_F_ENCRYPT; crde->crd_alg = sc->sc_ealgo; |