Date: Wed, 9 May 2018 20:53:38 +0000 (UTC) From: Mariusz Zaborski <oshogbo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333439 - in head: sbin/geom/class/eli stand/geli sys/geom/eli Message-ID: <201805092053.w49Krc3S081535@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805092053.w49Krc3S081535>