- Add support for loading passphrase from a file (-J and -j options).
This is especially useful for things like installers, where regular geli prompt can't be used. - Add support for specifing multiple -K or -k options, so there is no need to cat all keyfiles and read them from standard input. Requested by: Kris Moore <kris@pcbsd.org>, thompsa MFC after: 2 weeks
This commit is contained in:
parent
5c181adf40
commit
1cf3d5ee99
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=213172
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 23, 2010
|
||||
.Dd September 25, 2010
|
||||
.Dt GELI 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -56,6 +56,7 @@ utility:
|
||||
.Op Fl B Ar backupfile
|
||||
.Op Fl e Ar ealgo
|
||||
.Op Fl i Ar iterations
|
||||
.Op Fl J Ar newpassfile
|
||||
.Op Fl K Ar newkeyfile
|
||||
.Op Fl l Ar keylen
|
||||
.Op Fl s Ar sectorsize
|
||||
@ -66,6 +67,7 @@ utility:
|
||||
.Nm
|
||||
.Cm attach
|
||||
.Op Fl dprv
|
||||
.Op Fl j Ar passfile
|
||||
.Op Fl k Ar keyfile
|
||||
.Ar prov
|
||||
.Nm
|
||||
@ -91,6 +93,8 @@ utility:
|
||||
.Cm setkey
|
||||
.Op Fl pPv
|
||||
.Op Fl i Ar iterations
|
||||
.Op Fl j Ar passfile
|
||||
.Op Fl J Ar newpassfile
|
||||
.Op Fl k Ar keyfile
|
||||
.Op Fl K Ar newkeyfile
|
||||
.Op Fl n Ar keyno
|
||||
@ -223,7 +227,7 @@ The metadata can be recovered with the
|
||||
subcommand described below.
|
||||
.Pp
|
||||
Additional options include:
|
||||
.Bl -tag -width ".Fl a Ar newkeyfile"
|
||||
.Bl -tag -width ".Fl J Ar newpassfile"
|
||||
.It Fl a Ar aalgo
|
||||
Enable data integrity verification (authentication) using the given algorithm.
|
||||
This will reduce size of available storage and also reduce speed.
|
||||
@ -272,15 +276,19 @@ If this option is not specified,
|
||||
.Nm
|
||||
will find the number of iterations which is equal to 2 seconds of crypto work.
|
||||
If 0 is given, PKCS#5v2 will not be used.
|
||||
.It Fl J Ar newpassfile
|
||||
Specifies a file which contains the passphrase or its part.
|
||||
If
|
||||
.Ar newpassfile
|
||||
is given as -, standard input will be used.
|
||||
Only the first line (excluding new-line character) is taken from the given file.
|
||||
This argument can be specified multiple times.
|
||||
.It Fl K Ar newkeyfile
|
||||
Specifies a file which contains part of the key.
|
||||
If
|
||||
.Ar newkeyfile
|
||||
is given as -, standard input will be used.
|
||||
Here is how more than one file with a key component can be used:
|
||||
.Bd -literal -offset indent
|
||||
# cat key1 key2 key3 | geli init -K - /dev/da0
|
||||
.Ed
|
||||
This argument can be specified multiple times.
|
||||
.It Fl l Ar keylen
|
||||
Key length to use with the given cryptographic algorithm.
|
||||
If not given, the default key length for the given algorithm is used, which is:
|
||||
@ -309,7 +317,7 @@ provider's name with an
|
||||
suffix.
|
||||
.Pp
|
||||
Additional options include:
|
||||
.Bl -tag -width ".Fl a Ar keyfile"
|
||||
.Bl -tag -width ".Fl j Ar passfile"
|
||||
.It Fl d
|
||||
If specified, a decrypted provider will be detached automatically on last close.
|
||||
This can help with short memory - user does not have to remember to detach the
|
||||
@ -321,6 +329,13 @@ Probably a better choice is the
|
||||
option for the
|
||||
.Cm detach
|
||||
subcommand.
|
||||
.It Fl j Ar passfile
|
||||
Specifies a file which contains the passphrase or its part.
|
||||
For more information see the description of the
|
||||
.Fl J
|
||||
option for the
|
||||
.Cm init
|
||||
subcommand.
|
||||
.It Fl k Ar keyfile
|
||||
Specifies a file which contains part of the key.
|
||||
For more information see the description of the
|
||||
@ -409,13 +424,17 @@ When a provider is attached, the user does not have to provide
|
||||
an old passphrase/keyfile.
|
||||
.Pp
|
||||
Additional options include:
|
||||
.Bl -tag -width ".Fl a Ar iterations"
|
||||
.Bl -tag -width ".Fl J Ar newpassfile"
|
||||
.It Fl i Ar iterations
|
||||
Number of iterations to use with PKCS#5v2.
|
||||
If 0 is given, PKCS#5v2 will not be used.
|
||||
To be able to use this option with
|
||||
.Cm setkey
|
||||
subcommand, only one key have to be defined and this key has to be changed.
|
||||
.It Fl j Ar passfile
|
||||
Specifies a file which contains the old passphrase or its part.
|
||||
.It Fl J Ar newpassfile
|
||||
Specifies a file which contains the new passphrase or its part.
|
||||
.It Fl k Ar keyfile
|
||||
Specifies a file which contains part of the old key.
|
||||
.It Fl K Ar newkeyfile
|
||||
@ -638,7 +657,7 @@ keyfile:
|
||||
# dd if=/dev/random of=/boot/keys/da0.key0 bs=32k count=1
|
||||
# dd if=/dev/random of=/boot/keys/da0.key1 bs=32k count=1
|
||||
# dd if=/dev/random of=/boot/keys/da0.key2 bs=32k count=1
|
||||
# cat /boot/keys/da0.key0 /boot/keys/da0.key1 /boot/keys/da0.key2 | geli init -b -K - da0
|
||||
# geli init -b -K /boot/keys/da0.key0 -K /boot/keys/da0.key1 -K /boot/keys/da0.key2 da0
|
||||
Enter new passphrase:
|
||||
Reenter new passphrase:
|
||||
# dd if=/dev/random of=/dev/da1s3a bs=1m
|
||||
@ -711,6 +730,22 @@ update the metadata:
|
||||
# geli resize -s 1g ada0p1
|
||||
# geli attach -k keyfile -p ada0p1
|
||||
.Ed
|
||||
.Pp
|
||||
Initialize provider with passphrase split into two files.
|
||||
The provider can be attached by giving those two files or by giving
|
||||
.Dq foobar
|
||||
passphrase on
|
||||
.Nm
|
||||
prompt:
|
||||
.Bd -literal -offset indent
|
||||
# echo foo > da0.pass0
|
||||
# echo bar > da0.pass1
|
||||
# geli init -J da0.pass0 -J da0.pass1 da0
|
||||
# geli attach -j da0.pass0 -j da0.pass1 da0
|
||||
# geli detach da0
|
||||
# geli attach da0
|
||||
Enter passphrase: foobar
|
||||
.Ed
|
||||
.Sh ENCRYPTION MODES
|
||||
.Nm
|
||||
supports two encryption modes:
|
||||
|
@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -79,14 +80,14 @@ 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] [-K newkeyfile] prov
|
||||
* init [-bhPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] prov
|
||||
* label - alias for 'init'
|
||||
* attach [-dprv] [-k keyfile] prov
|
||||
* attach [-dprv] [-j passfile] [-k keyfile] prov
|
||||
* detach [-fl] prov ...
|
||||
* stop - alias for 'detach'
|
||||
* onetime [-d] [-a aalgo] [-e ealgo] [-l keylen] prov
|
||||
* configure [-bB] prov ...
|
||||
* setkey [-pPv] [-n keyno] [-k keyfile] [-K newkeyfile] prov
|
||||
* setkey [-pPv] [-n keyno] [-j passfile] [-J newpassfile] [-k keyfile] [-K newkeyfile] prov
|
||||
* delkey [-afv] [-n keyno] prov
|
||||
* kill [-av] [prov ...]
|
||||
* backup [-v] prov file
|
||||
@ -103,13 +104,14 @@ struct g_command class_commands[] = {
|
||||
{ 'B', "backupfile", "", G_TYPE_STRING },
|
||||
{ 'e', "ealgo", GELI_ENC_ALGO, G_TYPE_STRING },
|
||||
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
|
||||
{ 'K', "newkeyfile", "", G_TYPE_STRING },
|
||||
{ '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 },
|
||||
G_OPT_SENTINEL
|
||||
},
|
||||
"[-bPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-K newkeyfile] [-s sectorsize] prov"
|
||||
"[-bPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] prov"
|
||||
},
|
||||
{ "label", G_FLAG_VERBOSE, eli_main,
|
||||
{
|
||||
@ -118,7 +120,8 @@ struct g_command class_commands[] = {
|
||||
{ 'B', "backupfile", "", G_TYPE_STRING },
|
||||
{ 'e', "ealgo", GELI_ENC_ALGO, G_TYPE_STRING },
|
||||
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
|
||||
{ 'K', "newkeyfile", "", G_TYPE_STRING },
|
||||
{ '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 },
|
||||
@ -129,12 +132,13 @@ struct g_command class_commands[] = {
|
||||
{ "attach", G_FLAG_VERBOSE | G_FLAG_LOADKLD, eli_main,
|
||||
{
|
||||
{ 'd', "detach", NULL, G_TYPE_BOOL },
|
||||
{ 'k', "keyfile", "", G_TYPE_STRING },
|
||||
{ 'j', "passfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
|
||||
{ 'k', "keyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
|
||||
{ 'p', "nopassphrase", NULL, G_TYPE_BOOL },
|
||||
{ 'r', "readonly", NULL, G_TYPE_BOOL },
|
||||
G_OPT_SENTINEL
|
||||
},
|
||||
"[-dprv] [-k keyfile] prov"
|
||||
"[-dprv] [-j passfile] [-k keyfile] prov"
|
||||
},
|
||||
{ "detach", 0, NULL,
|
||||
{
|
||||
@ -174,14 +178,16 @@ struct g_command class_commands[] = {
|
||||
{ "setkey", G_FLAG_VERBOSE, eli_main,
|
||||
{
|
||||
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
|
||||
{ 'k', "keyfile", "", G_TYPE_STRING },
|
||||
{ 'K', "newkeyfile", "", G_TYPE_STRING },
|
||||
{ 'j', "passfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
|
||||
{ 'J', "newpassfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
|
||||
{ 'k', "keyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
|
||||
{ 'K', "newkeyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
|
||||
{ 'n', "keyno", "-1", G_TYPE_NUMBER },
|
||||
{ 'p', "nopassphrase", NULL, G_TYPE_BOOL },
|
||||
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
|
||||
G_OPT_SENTINEL
|
||||
},
|
||||
"[-pPv] [-n keyno] [-i iterations] [-k keyfile] [-K newkeyfile] prov"
|
||||
"[-pPv] [-n keyno] [-i iterations] [-j passfile] [-J newpassfile] [-k keyfile] [-K newkeyfile] prov"
|
||||
},
|
||||
{ "delkey", G_FLAG_VERBOSE, eli_main,
|
||||
{
|
||||
@ -249,7 +255,7 @@ eli_protect(struct gctl_req *req)
|
||||
}
|
||||
|
||||
static void
|
||||
eli_main(struct gctl_req *req, unsigned flags)
|
||||
eli_main(struct gctl_req *req, unsigned int flags)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
@ -295,7 +301,7 @@ arc4rand(unsigned char *buf, size_t size)
|
||||
{
|
||||
uint32_t *buf4;
|
||||
size_t size4;
|
||||
unsigned i;
|
||||
unsigned int i;
|
||||
|
||||
buf4 = (uint32_t *)buf;
|
||||
size4 = size / 4;
|
||||
@ -324,89 +330,154 @@ eli_is_attached(const char *prov)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
eli_genkey(struct gctl_req *req, struct g_eli_metadata *md, unsigned char *key,
|
||||
int new)
|
||||
static int
|
||||
eli_genkey_files(struct gctl_req *req, bool new, const char *type,
|
||||
struct hmac_ctx *ctxp, char *passbuf, size_t passbufsize)
|
||||
{
|
||||
struct hmac_ctx ctx;
|
||||
const char *str;
|
||||
int error, nopassphrase;
|
||||
|
||||
nopassphrase =
|
||||
gctl_get_int(req, new ? "nonewpassphrase" : "nopassphrase");
|
||||
|
||||
g_eli_crypto_hmac_init(&ctx, NULL, 0);
|
||||
|
||||
str = gctl_get_ascii(req, new ? "newkeyfile" : "keyfile");
|
||||
if (str[0] == '\0' && nopassphrase) {
|
||||
gctl_error(req, "No key components given.");
|
||||
return (NULL);
|
||||
} else if (str[0] != '\0') {
|
||||
char buf[MAXPHYS];
|
||||
char *p, buf[MAXPHYS], argname[16];
|
||||
const char *file;
|
||||
int error, fd, i;
|
||||
ssize_t done;
|
||||
int fd;
|
||||
|
||||
if (strcmp(str, "-") == 0)
|
||||
assert((strcmp(type, "keyfile") == 0 && ctxp != NULL &&
|
||||
passbuf == NULL && passbufsize == 0) ||
|
||||
(strcmp(type, "passfile") == 0 && ctxp == NULL &&
|
||||
passbuf != NULL && passbufsize > 0));
|
||||
assert(strcmp(type, "keyfile") == 0 || passbuf[0] == '\0');
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
snprintf(argname, sizeof(argname), "%s%s%d",
|
||||
new ? "new" : "", type, i);
|
||||
|
||||
/* No more {key,pass}files? */
|
||||
if (!gctl_has_param(req, argname))
|
||||
return (i);
|
||||
|
||||
file = gctl_get_ascii(req, argname);
|
||||
assert(file != NULL);
|
||||
|
||||
if (strcmp(file, "-") == 0)
|
||||
fd = STDIN_FILENO;
|
||||
else {
|
||||
fd = open(str, O_RDONLY);
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
gctl_error(req, "Cannot open keyfile %s: %s.",
|
||||
str, strerror(errno));
|
||||
return (NULL);
|
||||
gctl_error(req, "Cannot open %s %s: %s.",
|
||||
type, file, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (strcmp(type, "keyfile") == 0) {
|
||||
while ((done = read(fd, buf, sizeof(buf))) > 0)
|
||||
g_eli_crypto_hmac_update(&ctx, buf, done);
|
||||
g_eli_crypto_hmac_update(ctxp, buf, done);
|
||||
} else /* if (strcmp(type, "passfile") == 0) */ {
|
||||
while ((done = read(fd, buf, sizeof(buf) - 1)) > 0) {
|
||||
buf[done] = '\0';
|
||||
p = strchr(buf, '\n');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
done = p - buf;
|
||||
}
|
||||
if (strlcat(passbuf, buf, passbufsize) >=
|
||||
passbufsize) {
|
||||
gctl_error(req,
|
||||
"Passphrase in %s too long.", file);
|
||||
bzero(buf, sizeof(buf));
|
||||
return (-1);
|
||||
}
|
||||
if (p != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
error = errno;
|
||||
if (strcmp(str, "-") != 0)
|
||||
if (strcmp(file, "-") != 0)
|
||||
close(fd);
|
||||
bzero(buf, sizeof(buf));
|
||||
if (done == -1) {
|
||||
gctl_error(req, "Cannot read keyfile %s: %s.", str,
|
||||
strerror(error));
|
||||
return (NULL);
|
||||
gctl_error(req, "Cannot read %s %s: %s.",
|
||||
type, file, strerror(error));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (!nopassphrase) {
|
||||
char buf1[BUFSIZ], buf2[BUFSIZ], *p;
|
||||
static int
|
||||
eli_genkey_passphrase_prompt(struct gctl_req *req, bool new, char *passbuf,
|
||||
size_t passbufsize)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!new && md->md_iterations == -1) {
|
||||
gctl_error(req, "Missing -p flag.");
|
||||
return (NULL);
|
||||
}
|
||||
for (;;) {
|
||||
p = readpassphrase(
|
||||
new ? "Enter new passphrase:" : "Enter passphrase:",
|
||||
buf1, sizeof(buf1), RPP_ECHO_OFF | RPP_REQUIRE_TTY);
|
||||
passbuf, passbufsize, RPP_ECHO_OFF | RPP_REQUIRE_TTY);
|
||||
if (p == NULL) {
|
||||
bzero(buf1, sizeof(buf1));
|
||||
bzero(passbuf, passbufsize);
|
||||
gctl_error(req, "Cannot read passphrase: %s.",
|
||||
strerror(errno));
|
||||
return (NULL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (new) {
|
||||
char tmpbuf[BUFSIZ];
|
||||
|
||||
p = readpassphrase("Reenter new passphrase: ",
|
||||
buf2, sizeof(buf2),
|
||||
tmpbuf, sizeof(tmpbuf),
|
||||
RPP_ECHO_OFF | RPP_REQUIRE_TTY);
|
||||
if (p == NULL) {
|
||||
bzero(buf1, sizeof(buf1));
|
||||
bzero(passbuf, passbufsize);
|
||||
gctl_error(req,
|
||||
"Cannot read passphrase: %s.",
|
||||
strerror(errno));
|
||||
return (NULL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (strcmp(buf1, buf2) != 0) {
|
||||
bzero(buf2, sizeof(buf2));
|
||||
if (strcmp(passbuf, tmpbuf) != 0) {
|
||||
bzero(passbuf, passbufsize);
|
||||
fprintf(stderr, "They didn't match.\n");
|
||||
continue;
|
||||
}
|
||||
bzero(buf2, sizeof(buf2));
|
||||
bzero(tmpbuf, sizeof(tmpbuf));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int
|
||||
eli_genkey_passphrase(struct gctl_req *req, struct g_eli_metadata *md, bool new,
|
||||
struct hmac_ctx *ctxp)
|
||||
{
|
||||
char passbuf[MAXPHYS];
|
||||
bool nopassphrase;
|
||||
int nfiles;
|
||||
|
||||
nopassphrase =
|
||||
gctl_get_int(req, new ? "nonewpassphrase" : "nopassphrase");
|
||||
if (nopassphrase) {
|
||||
if (gctl_has_param(req, new ? "newpassfile0" : "passfile0")) {
|
||||
gctl_error(req,
|
||||
"Options -%c and -%c are mutually exclusive.",
|
||||
new ? 'J' : 'j', new ? 'P' : 'p');
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!new && md->md_iterations == -1) {
|
||||
gctl_error(req, "Missing -p flag.");
|
||||
return (-1);
|
||||
}
|
||||
passbuf[0] = '\0';
|
||||
nfiles = eli_genkey_files(req, new, "passfile", NULL, passbuf,
|
||||
sizeof(passbuf));
|
||||
if (nfiles == -1)
|
||||
return (-1);
|
||||
else if (nfiles == 0) {
|
||||
if (eli_genkey_passphrase_prompt(req, new, passbuf,
|
||||
sizeof(passbuf)) == -1) {
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Field md_iterations equal to -1 means "choose some sane
|
||||
@ -424,23 +495,51 @@ eli_genkey(struct gctl_req *req, struct g_eli_metadata *md, unsigned char *key,
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If md_iterations is equal to 0, user don't want PKCS#5v2.
|
||||
* If md_iterations is equal to 0, user doesn't want PKCS#5v2.
|
||||
*/
|
||||
if (md->md_iterations == 0) {
|
||||
g_eli_crypto_hmac_update(&ctx, md->md_salt,
|
||||
g_eli_crypto_hmac_update(ctxp, md->md_salt,
|
||||
sizeof(md->md_salt));
|
||||
g_eli_crypto_hmac_update(&ctx, buf1, strlen(buf1));
|
||||
g_eli_crypto_hmac_update(ctxp, passbuf, strlen(passbuf));
|
||||
} else /* if (md->md_iterations > 0) */ {
|
||||
unsigned char dkey[G_ELI_USERKEYLEN];
|
||||
|
||||
pkcs5v2_genkey(dkey, sizeof(dkey), md->md_salt,
|
||||
sizeof(md->md_salt), buf1, md->md_iterations);
|
||||
g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
|
||||
sizeof(md->md_salt), passbuf, md->md_iterations);
|
||||
g_eli_crypto_hmac_update(ctxp, dkey, sizeof(dkey));
|
||||
bzero(dkey, sizeof(dkey));
|
||||
}
|
||||
bzero(buf1, sizeof(buf1));
|
||||
bzero(passbuf, sizeof(passbuf));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
eli_genkey(struct gctl_req *req, struct g_eli_metadata *md, unsigned char *key,
|
||||
bool new)
|
||||
{
|
||||
struct hmac_ctx ctx;
|
||||
bool nopassphrase;
|
||||
int nfiles;
|
||||
|
||||
nopassphrase =
|
||||
gctl_get_int(req, new ? "nonewpassphrase" : "nopassphrase");
|
||||
|
||||
g_eli_crypto_hmac_init(&ctx, NULL, 0);
|
||||
|
||||
nfiles = eli_genkey_files(req, new, "keyfile", &ctx, NULL, 0);
|
||||
if (nfiles == -1)
|
||||
return (NULL);
|
||||
else if (nfiles == 0 && nopassphrase) {
|
||||
gctl_error(req, "No key components given.");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (eli_genkey_passphrase(req, md, new, &ctx) == -1)
|
||||
return (NULL);
|
||||
|
||||
g_eli_crypto_hmac_final(&ctx, key, 0);
|
||||
|
||||
return (key);
|
||||
}
|
||||
|
||||
@ -640,7 +739,7 @@ eli_init(struct gctl_req *req)
|
||||
arc4rand(md.md_mkeys, sizeof(md.md_mkeys));
|
||||
|
||||
/* Generate user key. */
|
||||
if (eli_genkey(req, &md, key, 1) == NULL) {
|
||||
if (eli_genkey(req, &md, key, true) == NULL) {
|
||||
bzero(key, sizeof(key));
|
||||
bzero(&md, sizeof(md));
|
||||
return;
|
||||
@ -720,7 +819,7 @@ eli_attach(struct gctl_req *req)
|
||||
return;
|
||||
}
|
||||
|
||||
if (eli_genkey(req, &md, key, 0) == NULL) {
|
||||
if (eli_genkey(req, &md, key, false) == NULL) {
|
||||
bzero(key, sizeof(key));
|
||||
return;
|
||||
}
|
||||
@ -734,7 +833,7 @@ eli_attach(struct gctl_req *req)
|
||||
}
|
||||
|
||||
static void
|
||||
eli_configure_detached(struct gctl_req *req, const char *prov, int boot)
|
||||
eli_configure_detached(struct gctl_req *req, const char *prov, bool boot)
|
||||
{
|
||||
struct g_eli_metadata md;
|
||||
|
||||
@ -761,7 +860,8 @@ static void
|
||||
eli_configure(struct gctl_req *req)
|
||||
{
|
||||
const char *prov;
|
||||
int i, nargs, boot, noboot;
|
||||
bool boot, noboot;
|
||||
int i, nargs;
|
||||
|
||||
nargs = gctl_get_int(req, "nargs");
|
||||
if (nargs == 0) {
|
||||
@ -806,7 +906,7 @@ eli_setkey_attached(struct gctl_req *req, struct g_eli_metadata *md)
|
||||
old = md->md_iterations;
|
||||
|
||||
/* Generate key for Master Key encryption. */
|
||||
if (eli_genkey(req, md, key, 1) == NULL) {
|
||||
if (eli_genkey(req, md, key, true) == NULL) {
|
||||
bzero(key, sizeof(key));
|
||||
return;
|
||||
}
|
||||
@ -831,8 +931,8 @@ eli_setkey_detached(struct gctl_req *req, const char *prov,
|
||||
{
|
||||
unsigned char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN];
|
||||
unsigned char *mkeydst;
|
||||
unsigned int nkey;
|
||||
intmax_t val;
|
||||
unsigned nkey;
|
||||
int error;
|
||||
|
||||
if (md->md_keys == 0) {
|
||||
@ -841,7 +941,7 @@ eli_setkey_detached(struct gctl_req *req, const char *prov,
|
||||
}
|
||||
|
||||
/* Generate key for Master Key decryption. */
|
||||
if (eli_genkey(req, md, key, 0) == NULL) {
|
||||
if (eli_genkey(req, md, key, false) == NULL) {
|
||||
bzero(key, sizeof(key));
|
||||
return;
|
||||
}
|
||||
@ -897,7 +997,7 @@ eli_setkey_detached(struct gctl_req *req, const char *prov,
|
||||
bzero(mkey, sizeof(mkey));
|
||||
|
||||
/* Generate key for Master Key encryption. */
|
||||
if (eli_genkey(req, md, key, 1) == NULL) {
|
||||
if (eli_genkey(req, md, key, true) == NULL) {
|
||||
bzero(key, sizeof(key));
|
||||
bzero(md, sizeof(*md));
|
||||
return;
|
||||
@ -959,9 +1059,9 @@ eli_delkey_detached(struct gctl_req *req, const char *prov)
|
||||
{
|
||||
struct g_eli_metadata md;
|
||||
unsigned char *mkeydst;
|
||||
unsigned int nkey;
|
||||
intmax_t val;
|
||||
unsigned nkey;
|
||||
int all, force;
|
||||
bool all, force;
|
||||
|
||||
if (eli_metadata_read(req, prov, &md) == -1)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user