summaryrefslogtreecommitdiffstats
path: root/sys/geom/eli
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2011-10-25 13:57:50 +0000
committerpjd <pjd@FreeBSD.org>2011-10-25 13:57:50 +0000
commitdf493c630e427108e6a11aefe72cb786a421ac22 (patch)
treefa76710fc589753eb33ec21359c6f8b2f57e6c38 /sys/geom/eli
parent9df0cca1543d03a0a0131f37eb927f9df4592b7b (diff)
downloadFreeBSD-src-df493c630e427108e6a11aefe72cb786a421ac22.zip
FreeBSD-src-df493c630e427108e6a11aefe72cb786a421ac22.tar.gz
Add support for creating GELI devices with older metadata version for use
with older FreeBSD versions: - Add -V option to 'geli init' to specify version number. If no -V is given the most recent version is used. - If -V is given don't allow to use features not supported by this version. - Print version in 'geli list' output. - Update manual page and add table describing which GELI version is supported by which FreeBSD version, so one can use it when preparing GELI device for older FreeBSD version. Inspired by: Garrett Cooper <yanegomi@gmail.com> MFC after: 3 days
Diffstat (limited to 'sys/geom/eli')
-rw-r--r--sys/geom/eli/g_eli.c2
-rw-r--r--sys/geom/eli/g_eli.h59
2 files changed, 56 insertions, 5 deletions
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c
index fce52ae..b5e4f7b 100644
--- a/sys/geom/eli/g_eli.c
+++ b/sys/geom/eli/g_eli.c
@@ -713,6 +713,7 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp,
else
gp->access = g_std_access;
+ sc->sc_version = md->md_version;
sc->sc_inflight = 0;
sc->sc_crypto = G_ELI_CRYPTO_UNKNOWN;
sc->sc_flags = md->md_flags;
@@ -1210,6 +1211,7 @@ g_eli_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
sbuf_printf(sb, "%s<UsedKey>%u</UsedKey>\n", indent,
sc->sc_nkey);
}
+ sbuf_printf(sb, "%s<Version>%u</Version>\n", indent, sc->sc_version);
sbuf_printf(sb, "%s<Crypto>", indent);
switch (sc->sc_crypto) {
case G_ELI_CRYPTO_HW:
diff --git a/sys/geom/eli/g_eli.h b/sys/geom/eli/g_eli.h
index 0f35cd6..0b48db2 100644
--- a/sys/geom/eli/g_eli.h
+++ b/sys/geom/eli/g_eli.h
@@ -43,6 +43,7 @@
#include <sys/tree.h>
#include <geom/geom.h>
#else
+#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
@@ -166,6 +167,7 @@ struct g_eli_worker {
struct g_eli_softc {
struct g_geom *sc_geom;
+ u_int sc_version;
u_int sc_crypto;
uint8_t sc_mkey[G_ELI_DATAIVKEYLEN];
uint8_t sc_ekey[G_ELI_DATAKEYLEN];
@@ -217,14 +219,28 @@ struct g_eli_metadata {
} __packed;
#ifndef _OpenSSL_
static __inline void
-eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
+eli_metadata_encode_v0(struct g_eli_metadata *md, u_char **datap)
{
- MD5_CTX ctx;
u_char *p;
- p = data;
- bcopy(md->md_magic, p, sizeof(md->md_magic)); p += sizeof(md->md_magic);
- le32enc(p, md->md_version); p += sizeof(md->md_version);
+ p = *datap;
+ le32enc(p, md->md_flags); p += sizeof(md->md_flags);
+ le16enc(p, md->md_ealgo); p += sizeof(md->md_ealgo);
+ le16enc(p, md->md_keylen); p += sizeof(md->md_keylen);
+ le64enc(p, md->md_provsize); p += sizeof(md->md_provsize);
+ le32enc(p, md->md_sectorsize); p += sizeof(md->md_sectorsize);
+ *p = md->md_keys; p += sizeof(md->md_keys);
+ le32enc(p, md->md_iterations); p += sizeof(md->md_iterations);
+ bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt);
+ bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys);
+ *datap = p;
+}
+static __inline void
+eli_metadata_encode_v1v2v3v4v5v6(struct g_eli_metadata *md, u_char **datap)
+{
+ u_char *p;
+
+ p = *datap;
le32enc(p, md->md_flags); p += sizeof(md->md_flags);
le16enc(p, md->md_ealgo); p += sizeof(md->md_ealgo);
le16enc(p, md->md_keylen); p += sizeof(md->md_keylen);
@@ -235,6 +251,39 @@ eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
le32enc(p, md->md_iterations); p += sizeof(md->md_iterations);
bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt);
bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys);
+ *datap = p;
+}
+static __inline void
+eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
+{
+ MD5_CTX ctx;
+ u_char *p;
+
+ p = data;
+ bcopy(md->md_magic, p, sizeof(md->md_magic));
+ p += sizeof(md->md_magic);
+ le32enc(p, md->md_version);
+ p += sizeof(md->md_version);
+ switch (md->md_version) {
+ case G_ELI_VERSION_00:
+ eli_metadata_encode_v0(md, &p);
+ break;
+ case G_ELI_VERSION_01:
+ case G_ELI_VERSION_02:
+ case G_ELI_VERSION_03:
+ case G_ELI_VERSION_04:
+ case G_ELI_VERSION_05:
+ case G_ELI_VERSION_06:
+ eli_metadata_encode_v1v2v3v4v5v6(md, &p);
+ break;
+ default:
+#ifdef _KERNEL
+ panic("%s: Unsupported version %u.", __func__,
+ (u_int)md->md_version);
+#else
+ assert(!"Unsupported metadata version.");
+#endif
+ }
MD5Init(&ctx);
MD5Update(&ctx, data, p - data);
MD5Final(md->md_hash, &ctx);
OpenPOWER on IntegriCloud