svn commit: r333439 - in head: sbin/geom/class/eli stand/geli sys/geom/eli
Mariusz Zaborski
oshogbo at FreeBSD.org
Wed May 9 20:53:40 UTC 2018
Author: oshogbo
Date: Wed May 9 20:53:38 2018
New Revision: 333439
URL: https://svnweb.freebsd.org/changeset/base/333439
Log:
Introduce the 'n' flag for the geli attach command.
If the 'n' flag is provided the provided key number will be used to
decrypt device. This can be used combined with dryrun to verify if the key
is set correctly. This can be also used to determine which key slot we want to
change on already attached device.
Reviewed by: allanjude
Differential Revision: https://reviews.freebsd.org/D15309
Modified:
head/sbin/geom/class/eli/geli.8
head/sbin/geom/class/eli/geom_eli.c
head/stand/geli/geliboot.c
head/sys/geom/eli/g_eli.c
head/sys/geom/eli/g_eli.h
head/sys/geom/eli/g_eli_ctl.c
head/sys/geom/eli/g_eli_key.c
Modified: head/sbin/geom/class/eli/geli.8
==============================================================================
--- head/sbin/geom/class/eli/geli.8 Wed May 9 20:51:16 2018 (r333438)
+++ head/sbin/geom/class/eli/geli.8 Wed May 9 20:53:38 2018 (r333439)
@@ -68,6 +68,7 @@ utility:
.Nm
.Cm attach
.Op Fl Cdprv
+.Op Fl n Ar keyno
.Op Fl j Ar passfile
.Op Fl k Ar keyfile
.Ar prov
@@ -407,6 +408,9 @@ Probably a better choice is the
option for the
.Cm detach
subcommand.
+.It Fl n Ar keyno
+Specifies the index number of the Master Key copy to use (could be 0 or 1).
+If the index number is not provided all keys will be tested.
.It Fl j Ar passfile
Specifies a file which contains the passphrase component of the User Key
(or part of it).
Modified: head/sbin/geom/class/eli/geom_eli.c
==============================================================================
--- head/sbin/geom/class/eli/geom_eli.c Wed May 9 20:51:16 2018 (r333438)
+++ head/sbin/geom/class/eli/geom_eli.c Wed May 9 20:53:38 2018 (r333439)
@@ -86,7 +86,7 @@ static int eli_backup_create(struct gctl_req *req, con
*
* init [-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov
* label - alias for 'init'
- * attach [-Cdprv] [-j passfile] [-k keyfile] prov
+ * attach [-Cdprv] [-n keyno] [-j passfile] [-k keyfile] prov
* detach [-fl] prov ...
* stop - alias for 'detach'
* onetime [-d] [-a aalgo] [-e ealgo] [-l keylen] prov
@@ -149,11 +149,12 @@ struct g_command class_commands[] = {
{ 'd', "detach", NULL, G_TYPE_BOOL },
{ 'j', "passfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'k', "keyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
+ { 'n', "keyno", "-1", G_TYPE_NUMBER },
{ 'p', "nopassphrase", NULL, G_TYPE_BOOL },
{ 'r', "readonly", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
- "[-Cdprv] [-j passfile] [-k keyfile] prov"
+ "[-Cdprv] [-n keyno] [-j passfile] [-k keyfile] prov"
},
{ "detach", 0, NULL,
{
@@ -1129,7 +1130,7 @@ eli_setkey_detached(struct gctl_req *req, const char *
}
/* Decrypt Master Key. */
- error = g_eli_mkey_decrypt(md, key, mkey, &nkey);
+ error = g_eli_mkey_decrypt_any(md, key, mkey, &nkey);
bzero(key, sizeof(key));
if (error != 0) {
bzero(md, sizeof(*md));
Modified: head/stand/geli/geliboot.c
==============================================================================
--- head/stand/geli/geliboot.c Wed May 9 20:51:16 2018 (r333438)
+++ head/stand/geli/geliboot.c Wed May 9 20:53:38 2018 (r333439)
@@ -121,14 +121,14 @@ geli_findkey(struct geli_entry *ge, struct dsk *dskp,
int i;
if (ge->keybuf_slot >= 0) {
- if (g_eli_mkey_decrypt(&ge->md, saved_keys[ge->keybuf_slot],
+ if (g_eli_mkey_decrypt_any(&ge->md, saved_keys[ge->keybuf_slot],
mkey, &keynum) == 0) {
return (0);
}
}
for (i = 0; i < nsaved_keys; i++) {
- if (g_eli_mkey_decrypt(&ge->md, saved_keys[i], mkey,
+ if (g_eli_mkey_decrypt_any(&ge->md, saved_keys[i], mkey,
&keynum) == 0) {
ge->keybuf_slot = i;
return (0);
@@ -266,7 +266,7 @@ geli_attach(struct geli_entry *ge, struct dsk *dskp, c
g_eli_crypto_hmac_final(&ctx, key, 0);
- error = g_eli_mkey_decrypt(&geli_e->md, key, mkey, &keynum);
+ error = g_eli_mkey_decrypt_any(&geli_e->md, key, mkey, &keynum);
if (error == -1) {
explicit_bzero(mkey, sizeof(mkey));
explicit_bzero(key, sizeof(key));
Modified: head/sys/geom/eli/g_eli.c
==============================================================================
--- head/sys/geom/eli/g_eli.c Wed May 9 20:51:16 2018 (r333438)
+++ head/sys/geom/eli/g_eli.c Wed May 9 20:53:38 2018 (r333439)
@@ -1086,7 +1086,7 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp,
memcpy(key, keybuf->kb_ents[i].ke_data,
sizeof(key));
- if (g_eli_mkey_decrypt(&md, key,
+ if (g_eli_mkey_decrypt_any(&md, key,
mkey, &nkey) == 0 ) {
explicit_bzero(key, sizeof(key));
goto have_key;
@@ -1161,7 +1161,7 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp,
/*
* Decrypt Master-Key.
*/
- error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
+ error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
bzero(key, sizeof(key));
if (error == -1) {
if (i == tries) {
Modified: head/sys/geom/eli/g_eli.h
==============================================================================
--- head/sys/geom/eli/g_eli.h Wed May 9 20:51:16 2018 (r333438)
+++ head/sys/geom/eli/g_eli.h Wed May 9 20:53:38 2018 (r333439)
@@ -688,6 +688,8 @@ void g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t
void g_eli_mkey_hmac(unsigned char *mkey, const unsigned char *key);
int g_eli_mkey_decrypt(const struct g_eli_metadata *md,
+ const unsigned char *key, unsigned char *mkey, unsigned keyp);
+int g_eli_mkey_decrypt_any(const struct g_eli_metadata *md,
const unsigned char *key, unsigned char *mkey, unsigned *nkeyp);
int g_eli_mkey_encrypt(unsigned algo, const unsigned char *key, unsigned keylen,
unsigned char *mkey);
Modified: head/sys/geom/eli/g_eli_ctl.c
==============================================================================
--- head/sys/geom/eli/g_eli_ctl.c Wed May 9 20:51:16 2018 (r333438)
+++ head/sys/geom/eli/g_eli_ctl.c Wed May 9 20:53:38 2018 (r333439)
@@ -60,8 +60,8 @@ g_eli_ctl_attach(struct gctl_req *req, struct g_class
const char *name;
u_char *key, mkey[G_ELI_DATAIVKEYLEN];
int *nargs, *detach, *readonly, *dryrun;
- int keysize, error;
- u_int nkey;
+ int keysize, error, nkey;
+ intmax_t *valp;
g_topology_assert();
@@ -81,6 +81,17 @@ g_eli_ctl_attach(struct gctl_req *req, struct g_class
return;
}
+ valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
+ if (valp == NULL) {
+ gctl_error(req, "No '%s' argument.", "keyno");
+ return;
+ }
+ nkey = *valp;
+ if (nkey < -1 || nkey >= G_ELI_MAXMKEYS) {
+ gctl_error(req, "Invalid '%s' argument.", "keyno");
+ return;
+ }
+
readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly));
if (readonly == NULL) {
gctl_error(req, "No '%s' argument.", "readonly");
@@ -129,7 +140,10 @@ g_eli_ctl_attach(struct gctl_req *req, struct g_class
return;
}
- error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
+ if (nkey == -1)
+ error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
+ else
+ error = g_eli_mkey_decrypt(&md, key, mkey, nkey);
explicit_bzero(key, keysize);
if (error == -1) {
explicit_bzero(&md, sizeof(md));
@@ -981,7 +995,7 @@ g_eli_ctl_resume(struct gctl_req *req, struct g_class
return;
}
- error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
+ error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
explicit_bzero(key, keysize);
if (error == -1) {
explicit_bzero(&md, sizeof(md));
Modified: head/sys/geom/eli/g_eli_key.c
==============================================================================
--- head/sys/geom/eli/g_eli_key.c Wed May 9 20:51:16 2018 (r333438)
+++ head/sys/geom/eli/g_eli_key.c Wed May 9 20:53:38 2018 (r333439)
@@ -103,52 +103,77 @@ g_eli_mkey_hmac(unsigned char *mkey, const unsigned ch
}
/*
- * Find and decrypt Master Key encrypted with 'key'.
- * Return decrypted Master Key number in 'nkeyp' if not NULL.
+ * Find and decrypt Master Key encrypted with 'key' at slot 'nkey'.
* Return 0 on success, > 0 on failure, -1 on bad key.
*/
int
g_eli_mkey_decrypt(const struct g_eli_metadata *md, const unsigned char *key,
- unsigned char *mkey, unsigned *nkeyp)
+ unsigned char *mkey, unsigned nkey)
{
unsigned char tmpmkey[G_ELI_MKEYLEN];
unsigned char enckey[SHA512_MDLEN]; /* Key for encryption. */
const unsigned char *mmkey;
- int bit, error, nkey;
+ int bit, error;
- if (nkeyp != NULL)
- *nkeyp = -1;
+ if (nkey > G_ELI_MKEYLEN)
+ return (-1);
/*
* The key for encryption is: enckey = HMAC_SHA512(Derived-Key, 1)
*/
g_eli_crypto_hmac(key, G_ELI_USERKEYLEN, "\x01", 1, enckey, 0);
- mmkey = md->md_mkeys;
- for (nkey = 0; nkey < G_ELI_MAXMKEYS; nkey++, mmkey += G_ELI_MKEYLEN) {
- bit = (1 << nkey);
- if (!(md->md_keys & bit))
- continue;
- bcopy(mmkey, tmpmkey, G_ELI_MKEYLEN);
- error = g_eli_crypto_decrypt(md->md_ealgo, tmpmkey,
- G_ELI_MKEYLEN, enckey, md->md_keylen);
- if (error != 0) {
- explicit_bzero(tmpmkey, sizeof(tmpmkey));
- explicit_bzero(enckey, sizeof(enckey));
- return (error);
- }
- if (g_eli_mkey_verify(tmpmkey, key)) {
- bcopy(tmpmkey, mkey, G_ELI_DATAIVKEYLEN);
- explicit_bzero(tmpmkey, sizeof(tmpmkey));
- explicit_bzero(enckey, sizeof(enckey));
- if (nkeyp != NULL)
- *nkeyp = nkey;
- return (0);
- }
+ mmkey = md->md_mkeys + G_ELI_MKEYLEN * nkey;
+ bit = (1 << nkey);
+ if (!(md->md_keys & bit))
+ return (-1);
+ bcopy(mmkey, tmpmkey, G_ELI_MKEYLEN);
+ error = g_eli_crypto_decrypt(md->md_ealgo, tmpmkey,
+ G_ELI_MKEYLEN, enckey, md->md_keylen);
+ if (error != 0) {
+ explicit_bzero(tmpmkey, sizeof(tmpmkey));
+ explicit_bzero(enckey, sizeof(enckey));
+ return (error);
}
+ if (g_eli_mkey_verify(tmpmkey, key)) {
+ bcopy(tmpmkey, mkey, G_ELI_DATAIVKEYLEN);
+ explicit_bzero(tmpmkey, sizeof(tmpmkey));
+ explicit_bzero(enckey, sizeof(enckey));
+ return (0);
+ }
explicit_bzero(enckey, sizeof(enckey));
explicit_bzero(tmpmkey, sizeof(tmpmkey));
+
return (-1);
+}
+
+/*
+ * Find and decrypt Master Key encrypted with 'key'.
+ * Return decrypted Master Key number in 'nkeyp' if not NULL.
+ * Return 0 on success, > 0 on failure, -1 on bad key.
+ */
+int
+g_eli_mkey_decrypt_any(const struct g_eli_metadata *md,
+ const unsigned char *key, unsigned char *mkey, unsigned *nkeyp)
+{
+ int error, nkey;
+
+ if (nkeyp != NULL)
+ *nkeyp = -1;
+
+ error = -1;
+ for (nkey = 0; nkey < G_ELI_MAXMKEYS; nkey++) {
+ error = g_eli_mkey_decrypt(md, key, mkey, nkey);
+ if (error == 0) {
+ if (nkeyp != NULL)
+ *nkeyp = nkey;
+ break;
+ } else if (error > 0) {
+ break;
+ }
+ }
+
+ return (error);
}
/*
More information about the svn-src-all
mailing list