summaryrefslogtreecommitdiffstats
path: root/sbin/geom
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 /sbin/geom
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 'sbin/geom')
-rw-r--r--sbin/geom/class/eli/geli.840
-rw-r--r--sbin/geom/class/eli/geom_eli.c51
2 files changed, 84 insertions, 7 deletions
diff --git a/sbin/geom/class/eli/geli.8 b/sbin/geom/class/eli/geli.8
index 59361ec..d6b607f 100644
--- a/sbin/geom/class/eli/geli.8
+++ b/sbin/geom/class/eli/geli.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 9, 2011
+.Dd October 25, 2011
.Dt GELI 8
.Os
.Sh NAME
@@ -60,6 +60,7 @@ utility:
.Op Fl K Ar newkeyfile
.Op Fl l Ar keylen
.Op Fl s Ar sectorsize
+.Op Fl V Ar version
.Ar prov
.Nm
.Cm label - an alias for
@@ -322,6 +323,15 @@ Change decrypted provider's sector size.
Increasing sector size allows to increase performance, because we need to
generate an IV and do encrypt/decrypt for every single sector - less number
of sectors means less work to do.
+.It Fl V Ar version
+Metadata version to use.
+This option is helpful when creating provider that may be used by older
+.Nm FreeBSD/GELI
+versions.
+Consult the
+.Sx HISTORY
+section to find which metadata version is supported by which FreeBSD version.
+Note that using older metadata version may limit numer of features available.
.El
.It Cm attach
Attach the given provider.
@@ -931,5 +941,33 @@ Support for
.Nm Camellia
block cipher is implemented by Yoshisato Yanagisawa in
.Fx 7.0 .
+.Pp
+Highest
+.Nm GELI
+metadata version supported by the given FreeBSD version:
+.Pp
+.Bl -column -offset indent ".Sy FreeBSD" ".Sy version"
+.It Sy FreeBSD Ta Sy GELI
+.It Sy version Ta Sy version
+.Pp
+.It Li 6.0 Ta 0
+.It Li 6.1 Ta 0
+.It Li 6.2 Ta 3
+.It Li 6.3 Ta 3
+.It Li 6.4 Ta 3
+.Pp
+.It Li 7.0 Ta 3
+.It Li 7.1 Ta 3
+.It Li 7.2 Ta 3
+.It Li 7.3 Ta 3
+.It Li 7.4 Ta 3
+.Pp
+.It Li 8.0 Ta 3
+.It Li 8.1 Ta 3
+.It Li 8.2 Ta 5
+.Pp
+.It Li 9.0 Ta 6
+.El
+.Pp
.Sh AUTHORS
.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org
diff --git a/sbin/geom/class/eli/geom_eli.c b/sbin/geom/class/eli/geom_eli.c
index f3553c5..f209800 100644
--- a/sbin/geom/class/eli/geom_eli.c
+++ b/sbin/geom/class/eli/geom_eli.c
@@ -82,7 +82,7 @@ static int eli_backup_create(struct gctl_req *req, const char *prov,
/*
* Available commands:
*
- * init [-bhPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] prov
+ * init [-bhPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-V version] prov
* label - alias for 'init'
* attach [-dprv] [-j passfile] [-k keyfile] prov
* detach [-fl] prov ...
@@ -107,29 +107,31 @@ struct g_command class_commands[] = {
{ 'a', "aalgo", "", G_TYPE_STRING },
{ 'b', "boot", NULL, G_TYPE_BOOL },
{ 'B', "backupfile", "", G_TYPE_STRING },
- { 'e', "ealgo", GELI_ENC_ALGO, G_TYPE_STRING },
+ { 'e', "ealgo", "", G_TYPE_STRING },
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
{ 'J', "newpassfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'K', "newkeyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'l', "keylen", "0", G_TYPE_NUMBER },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", "0", G_TYPE_NUMBER },
+ { 'V', "mdversion", "-1", G_TYPE_NUMBER },
G_OPT_SENTINEL
},
- "[-bPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] prov"
+ "[-bPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov"
},
{ "label", G_FLAG_VERBOSE, eli_main,
{
{ 'a', "aalgo", "", G_TYPE_STRING },
{ 'b', "boot", NULL, G_TYPE_BOOL },
{ 'B', "backupfile", "", G_TYPE_STRING },
- { 'e', "ealgo", GELI_ENC_ALGO, G_TYPE_STRING },
+ { 'e', "ealgo", "", G_TYPE_STRING },
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
{ 'J', "newpassfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'K', "newkeyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'l', "keylen", "0", G_TYPE_NUMBER },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", "0", G_TYPE_NUMBER },
+ { 'V', "mdversion", "-1", G_TYPE_NUMBER },
G_OPT_SENTINEL
},
"- an alias for 'init'"
@@ -672,7 +674,7 @@ eli_init(struct gctl_req *req)
unsigned char key[G_ELI_USERKEYLEN];
char backfile[MAXPATHLEN];
const char *str, *prov;
- unsigned secsize;
+ unsigned int secsize, version;
off_t mediasize;
intmax_t val;
int error, nargs;
@@ -693,13 +695,30 @@ eli_init(struct gctl_req *req)
bzero(&md, sizeof(md));
strlcpy(md.md_magic, G_ELI_MAGIC, sizeof(md.md_magic));
- md.md_version = G_ELI_VERSION;
+ val = gctl_get_intmax(req, "mdversion");
+ if (val == -1) {
+ version = G_ELI_VERSION;
+ } else if (val < 0 || val > G_ELI_VERSION) {
+ gctl_error(req,
+ "Invalid version specified should be between %u and %u.",
+ G_ELI_VERSION_00, G_ELI_VERSION);
+ return;
+ } else {
+ version = val;
+ }
+ md.md_version = version;
md.md_flags = 0;
if (gctl_get_int(req, "boot"))
md.md_flags |= G_ELI_FLAG_BOOT;
md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
str = gctl_get_ascii(req, "aalgo");
if (*str != '\0') {
+ if (version < G_ELI_VERSION_01) {
+ gctl_error(req,
+ "Data authentication is supported starting from version %u.",
+ G_ELI_VERSION_01);
+ return;
+ }
md.md_aalgo = g_eli_str2aalgo(str);
if (md.md_aalgo >= CRYPTO_ALGORITHM_MIN &&
md.md_aalgo <= CRYPTO_ALGORITHM_MAX) {
@@ -725,12 +744,32 @@ eli_init(struct gctl_req *req)
if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
str = gctl_get_ascii(req, "ealgo");
+ if (*str == '\0') {
+ if (version < G_ELI_VERSION_05)
+ str = "aes-cbc";
+ else
+ str = GELI_ENC_ALGO;
+ }
md.md_ealgo = g_eli_str2ealgo(str);
if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
gctl_error(req, "Invalid encryption algorithm.");
return;
}
+ if (md.md_ealgo == CRYPTO_CAMELLIA_CBC &&
+ version < G_ELI_VERSION_04) {
+ gctl_error(req,
+ "Camellia-CBC algorithm is supported starting from version %u.",
+ G_ELI_VERSION_04);
+ return;
+ }
+ if (md.md_ealgo == CRYPTO_AES_XTS &&
+ version < G_ELI_VERSION_05) {
+ gctl_error(req,
+ "AES-XTS algorithm is supported starting from version %u.",
+ G_ELI_VERSION_05);
+ return;
+ }
}
val = gctl_get_intmax(req, "keylen");
md.md_keylen = val;
OpenPOWER on IntegriCloud