Home | History | Annotate | Line # | Download | only in cgdconfig
      1 /* $NetBSD: params.c,v 1.35 2024/05/12 18:02:16 christos Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Roland C. Dowdeswell.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 __RCSID("$NetBSD: params.c,v 1.35 2024/05/12 18:02:16 christos Exp $");
     35 #endif
     36 
     37 #include <sys/types.h>
     38 #include <sys/param.h>
     39 
     40 #include <sys/sha2.h>
     41 #include <sys/stat.h>
     42 
     43 #include <err.h>
     44 #include <errno.h>
     45 #include <stdio.h>
     46 #include <stdlib.h>
     47 #include <string.h>
     48 #include <util.h>
     49 #include <uuid.h>
     50 
     51 #ifdef HAVE_ARGON2
     52 #include <argon2.h>
     53 #include "argon2_utils.h"
     54 #endif
     55 
     56 #include "params.h"
     57 #include "pkcs5_pbkdf2.h"
     58 #include "utils.h"
     59 #include "cgdconfig.h"
     60 #include "extern.h"
     61 
     62 static void	params_init(struct params *);
     63 
     64 static void	print_kvpair_cstr(FILE *, int, const char *, const char *);
     65 static void	print_kvpair_string(FILE *, int, const char *, const string_t *);
     66 static void	print_kvpair_int(FILE *, int, const char *, size_t);
     67 static void	print_kvpair_b64(FILE *, int, int, const char *, bits_t *);
     68 
     69 static void	spaces(FILE *, int);
     70 
     71 /* keygen defaults */
     72 #define DEFAULT_SALTLEN		128
     73 #define DEFAULT_ITERATION_TIME	2000000		/* 1 second in microseconds */
     74 
     75 /* crypto defaults functions */
     76 static struct crypto_defaults {
     77 	char	alg[32];
     78 	int	keylen;
     79 } crypto_defaults[] = {
     80 	{ "adiantum",		256 },
     81 	{ "aes-cbc",		128 },
     82 	{ "aes-xts",		256 },
     83 	{ "3des-cbc",		192 },
     84 	{ "blowfish-cbc",	128 }
     85 };
     86 
     87 static int	crypt_defaults_lookup(const char *);
     88 
     89 struct params *
     90 params_new(void)
     91 {
     92 	struct params	*p;
     93 
     94 	p = emalloc(sizeof(*p));
     95 	params_init(p);
     96 	return p;
     97 }
     98 
     99 static void
    100 params_init(struct params *p)
    101 {
    102 
    103 	p->algorithm = NULL;
    104 	p->ivmeth = NULL;
    105 	p->key = NULL;
    106 	p->keylen = (size_t)-1;
    107 	p->bsize = (size_t)-1;
    108 	p->verify_method = VERIFY_UNKNOWN;
    109 	p->dep_keygen = NULL;
    110 	p->keygen = NULL;
    111 }
    112 
    113 void
    114 params_free(struct params *p)
    115 {
    116 
    117 	if (!p)
    118 		return;
    119 	string_free(p->algorithm);
    120 	string_free(p->ivmeth);
    121 	keygen_free(p->dep_keygen);
    122 	keygen_free(p->keygen);
    123 }
    124 
    125 struct params *
    126 params_combine(struct params *p1, struct params *p2)
    127 {
    128 	struct params *p;
    129 
    130 	if (p1)
    131 		p = p1;
    132 	else
    133 		p = params_new();
    134 
    135 	if (!p2)
    136 		return p;
    137 
    138 	if (p2->algorithm)
    139 		string_assign(&p->algorithm, p2->algorithm);
    140 	if (p2->ivmeth)
    141 		string_assign(&p->ivmeth, p2->ivmeth);
    142 	if (p2->keylen != (size_t)-1)
    143 		p->keylen = p2->keylen;
    144 	if (p2->bsize != (size_t)-1)
    145 		p->bsize = p2->bsize;
    146 	if (p2->verify_method != VERIFY_UNKNOWN)
    147 		p->verify_method = p2->verify_method;
    148 
    149 	p->dep_keygen = keygen_combine(p->dep_keygen, p2->dep_keygen);
    150 	keygen_addlist(&p->keygen, p2->keygen);
    151 
    152 	/*
    153 	 * at this point we should have moved all allocated data
    154 	 * in p2 into p, so we can free it.
    155 	 */
    156 	free(p2);
    157 	return p;
    158 }
    159 
    160 int
    161 params_filldefaults(struct params *p)
    162 {
    163 	size_t	i;
    164 
    165 	if (p->verify_method == VERIFY_UNKNOWN)
    166 		p->verify_method = VERIFY_NONE;
    167 	if (!p->ivmeth)
    168 		p->ivmeth = string_fromcharstar("encblkno1");
    169 	if (p->keylen == (size_t)-1) {
    170 		if (p->algorithm == NULL)
    171 			return -1;
    172 		i = crypt_defaults_lookup(string_tocharstar(p->algorithm));
    173 		if (i != (size_t)-1) {
    174 			p->keylen = crypto_defaults[i].keylen;
    175 		} else {
    176 			warnx("could not determine key length for unknown "
    177 			    "algorithm \"%s\"",
    178 			    string_tocharstar(p->algorithm));
    179 			return -1;
    180 		}
    181 	}
    182 	return 0;
    183 }
    184 
    185 /*
    186  * params_verify traverses the parameters and all of the keygen methods
    187  * looking for inconsistencies.  It outputs warnings on non-fatal errors
    188  * such as unknown encryption methods, but returns failure on fatal
    189  * conditions such as a PKCS5_PBKDF2 keygen without a salt.  It is intended
    190  * to run before key generation.
    191  */
    192 
    193 int
    194 params_verify(const struct params *p)
    195 {
    196 	static const char *encblkno[] = {
    197 	    "encblkno", "encblkno1", "encblkno8"
    198 	};
    199 	static size_t i;
    200 	const char *meth;
    201 
    202 	if (!p->algorithm) {
    203 		warnx("unspecified algorithm");
    204 		return 0;
    205 	}
    206 	/*
    207 	 * we only warn for the encryption method so that it is possible
    208 	 * to use an older cgdconfig(8) with a new kernel that supports
    209 	 * additional crypto algorithms.
    210 	 */
    211 	if (crypt_defaults_lookup(string_tocharstar(p->algorithm)) == -1)
    212 		warnx("unknown algorithm \"%s\"(warning)",
    213 		    string_tocharstar(p->algorithm));
    214 	/* same rationale with IV methods. */
    215 	if (!p->ivmeth) {
    216 		warnx("unspecified IV method");
    217 		return 0;
    218 	}
    219 
    220 	meth = string_tocharstar(p->ivmeth);
    221 	for (i = 0; i < __arraycount(encblkno); i++)
    222 		if (strcmp(encblkno[i], meth) == 0)
    223 			break;
    224 
    225 	if (i == __arraycount(encblkno))
    226 		warnx("unknown IV method \"%s\" (warning)", meth);
    227 
    228 	if (p->keylen == (size_t)-1) {
    229 		warnx("unspecified key length");
    230 		return 0;
    231 	}
    232 
    233 	return keygen_verify(p->keygen);
    234 }
    235 
    236 struct params *
    237 params_algorithm(string_t *in)
    238 {
    239 	struct params *p = params_new();
    240 
    241 	p->algorithm = in;
    242 	return p;
    243 }
    244 
    245 struct params *
    246 params_ivmeth(string_t *in)
    247 {
    248 	struct params *p = params_new();
    249 
    250 	p->ivmeth = in;
    251 	return p;
    252 }
    253 
    254 struct params *
    255 params_keylen(size_t in)
    256 {
    257 	struct params *p = params_new();
    258 
    259 	p->keylen = in;
    260 	return p;
    261 }
    262 
    263 struct params *
    264 params_bsize(size_t in)
    265 {
    266 	struct params *p = params_new();
    267 
    268 	p->bsize = in;
    269 	return p;
    270 }
    271 
    272 struct params *
    273 params_verify_method(string_t *in)
    274 {
    275 	struct params *p = params_new();
    276 	const char *vm = string_tocharstar(in);
    277 
    278 	if (!strcmp("none", vm))
    279 		p->verify_method = VERIFY_NONE;
    280 	if (!strcmp("disklabel", vm))
    281 		p->verify_method = VERIFY_DISKLABEL;
    282 	if (!strcmp("ffs", vm))
    283 		p->verify_method = VERIFY_FFS;
    284 	if (!strcmp("re-enter", vm))
    285 		p->verify_method = VERIFY_REENTER;
    286 	if (!strcmp("mbr", vm))
    287 		p->verify_method = VERIFY_MBR;
    288 	if (!strcmp("gpt", vm))
    289 		p->verify_method = VERIFY_GPT;
    290 #ifdef HAVE_ZFS
    291 	if (!strcmp("zfs", vm))
    292 		p->verify_method = VERIFY_ZFS;
    293 #endif
    294 
    295 	string_free(in);
    296 
    297 	if (p->verify_method == VERIFY_UNKNOWN)
    298 		warnx("params_setverify_method: unrecognized "
    299 		    "verify method \"%s\"", vm);
    300 	return p;
    301 }
    302 
    303 struct params *
    304 params_keygen(struct keygen *in)
    305 {
    306 	struct params *p = params_new();
    307 
    308 	p->keygen = in;
    309 	return p;
    310 }
    311 
    312 struct params *
    313 params_dep_keygen(struct keygen *in)
    314 {
    315 	struct params *p = params_new();
    316 
    317 	p->dep_keygen = in;
    318 	return p;
    319 }
    320 
    321 struct keygen *
    322 keygen_new(void)
    323 {
    324 	struct keygen *kg;
    325 
    326 	kg = emalloc(sizeof(*kg));
    327 	kg->kg_method = KEYGEN_UNKNOWN;
    328 	kg->kg_iterations = (size_t)-1;
    329 	kg->kg_memory = (size_t)-1;
    330 	kg->kg_parallelism = (size_t)-1;
    331 	kg->kg_version = (size_t)-1;
    332 	kg->kg_salt = NULL;
    333 	kg->kg_key = NULL;
    334 	kg->kg_cmd = NULL;
    335 	kg->kg_sharedid = NULL;
    336 	kg->kg_sharedalg = SHARED_ALG_UNKNOWN;
    337 	kg->kg_sharedlen = (size_t)-1;
    338 	kg->kg_sharedinfo = NULL;
    339 	kg->next = NULL;
    340 	return kg;
    341 }
    342 
    343 void
    344 keygen_free(struct keygen *kg)
    345 {
    346 
    347 	if (!kg)
    348 		return;
    349 	bits_free(kg->kg_salt);
    350 	bits_free(kg->kg_key);
    351 	string_free(kg->kg_cmd);
    352 	string_free(kg->kg_sharedid);
    353 	bits_free(kg->kg_sharedinfo);
    354 	keygen_free(kg->next);
    355 	free(kg);
    356 }
    357 
    358 /*
    359  * keygen_verify traverses the keygen structures and ensures
    360  * that the appropriate information is available.
    361  */
    362 
    363 int
    364 keygen_verify(const struct keygen *kg)
    365 {
    366 
    367 	if (!kg)
    368 		return 1;
    369 	switch (kg->kg_method) {
    370 #ifdef HAVE_ARGON2
    371 	case KEYGEN_ARGON2ID:
    372 		if (kg->kg_iterations == (size_t)-1) {
    373 			warnx("keygen argon2id must provide `iterations'");
    374 			return 0;
    375 		}
    376 		if (kg->kg_memory == (size_t)-1) {
    377 			warnx("keygen argon2id must provide `memory'");
    378 			return 0;
    379 		}
    380 		if (kg->kg_parallelism == (size_t)-1) {
    381 			warnx("keygen argon2id must provide `parallelism'");
    382 			return 0;
    383 		}
    384 		if (kg->kg_version == (size_t)-1) {
    385 			warnx("keygen argon2id must provide `version'");
    386 			return 0;
    387 		}
    388 		if (kg->kg_cmd)
    389 			warnx("keygen argon2id does not need a `cmd'");
    390 		if (kg->kg_key)
    391 			warnx("keygen argon2id does not need a `key'");
    392 		if (!kg->kg_salt) {
    393 			warnx("keygen argon2id must provide a salt");
    394 			return 0;
    395 		}
    396 		break;
    397 #endif
    398 	case KEYGEN_PKCS5_PBKDF2_OLD:
    399 		if (kg->kg_iterations == (size_t)-1) {
    400 			warnx("keygen pkcs5_pbkdf2 must provide `iterations'");
    401 			return 0;
    402 		}
    403 		if (kg->kg_key)
    404 			warnx("keygen pkcs5_pbkdf2 does not need a `key'");
    405 		if (!kg->kg_salt) {
    406 			warnx("keygen pkcs5_pbkdf2 must provide a salt");
    407 			return 0;
    408 		}
    409 		if (kg->kg_cmd)
    410 			warnx("keygen pkcs5_pbkdf2 does not need a `cmd'");
    411 		break;
    412 	case KEYGEN_PKCS5_PBKDF2_SHA1:
    413 		if (kg->kg_iterations == (size_t)-1) {
    414 			warnx("keygen pkcs5_pbkdf2/sha1 must provide `iterations'");
    415 			return 0;
    416 		}
    417 		if (kg->kg_key)
    418 			warnx("keygen pkcs5_pbkdf2/sha1 does not need a `key'");
    419 		if (!kg->kg_salt) {
    420 			warnx("keygen pkcs5_pbkdf2/sha1 must provide a salt");
    421 			return 0;
    422 		}
    423 		if (kg->kg_cmd)
    424 			warnx("keygen pkcs5_pbkdf2/sha1 does not need a `cmd'");
    425 		break;
    426 	case KEYGEN_STOREDKEY:
    427 		if (kg->kg_iterations != (size_t)-1)
    428 			warnx("keygen storedkey does not need `iterations'");
    429 		if (!kg->kg_key) {
    430 			warnx("keygen storedkey must provide a key");
    431 			return 0;
    432 		}
    433 		if (kg->kg_salt)
    434 			warnx("keygen storedkey does not need `salt'");
    435 		if (kg->kg_cmd)
    436 			warnx("keygen storedkey does not need `cmd'");
    437 		break;
    438 	case KEYGEN_RANDOMKEY:
    439 	case KEYGEN_URANDOMKEY:
    440 		if (kg->kg_iterations != (size_t)-1)
    441 			warnx("keygen [u]randomkey does not need `iterations'");
    442 		if (kg->kg_key)
    443 			warnx("keygen [u]randomkey does not need `key'");
    444 		if (kg->kg_salt)
    445 			warnx("keygen [u]randomkey does not need `salt'");
    446 		if (kg->kg_cmd)
    447 			warnx("keygen [u]randomkey does not need `cmd'");
    448 		if (kg->kg_sharedid)
    449 			warnx("keygen [u]randomkey makes no sense shared");
    450 		break;
    451 	case KEYGEN_SHELL_CMD:
    452 		if (kg->kg_iterations != (size_t)-1)
    453 			warnx("keygen shell_cmd does not need `iterations'");
    454 		if (kg->kg_key)
    455 			warnx("keygen shell_cmd does not need `key'");
    456 		if (kg->kg_salt)
    457 			warnx("keygen shell_cmd does not need `salt'");
    458 		if (!kg->kg_cmd) {
    459 			warnx("keygen shell_cmd must provide a `cmd'");
    460 			return 0;
    461 		}
    462 		break;
    463 	}
    464 	return keygen_verify(kg->next);
    465 }
    466 
    467 struct keygen *
    468 keygen_generate(int method)
    469 {
    470 	struct keygen *kg;
    471 
    472 	kg = keygen_new();
    473 	if (!kg)
    474 		return NULL;
    475 
    476 	kg->kg_method = method;
    477 	return kg;
    478 }
    479 
    480 /*
    481  * keygen_filldefaults walks the keygen list and fills in
    482  * default values.  The defaults may be either calibrated
    483  * or randomly generated so this function is designed to be
    484  * called when generating a new parameters file, not when
    485  * reading a parameters file.
    486  */
    487 
    488 int
    489 keygen_filldefaults(struct keygen *kg, size_t keylen)
    490 {
    491 
    492 	if (!kg)
    493 		return 0;
    494 	switch (kg->kg_method) {
    495 	case KEYGEN_RANDOMKEY:
    496 	case KEYGEN_URANDOMKEY:
    497 	case KEYGEN_SHELL_CMD:
    498 		break;
    499 #ifdef HAVE_ARGON2
    500 	case KEYGEN_ARGON2ID:
    501 		kg->kg_version = ARGON2_VERSION_NUMBER;
    502 		kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1);
    503 		argon2id_calibrate(BITS2BYTES(keylen), DEFAULT_SALTLEN,
    504 		    &kg->kg_iterations, &kg->kg_memory, &kg->kg_parallelism);
    505 		break;
    506 #endif
    507 	case KEYGEN_PKCS5_PBKDF2_OLD:
    508 	case KEYGEN_PKCS5_PBKDF2_SHA1:
    509 		kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1);
    510 		kg->kg_iterations = pkcs5_pbkdf2_calibrate(BITS2BYTES(keylen),
    511 		    DEFAULT_ITERATION_TIME);
    512 		if (kg->kg_iterations < 1) {
    513 			warnx("could not calibrate pkcs5_pbkdf2");
    514 			return -1;
    515 		}
    516 		break;
    517 	case KEYGEN_STOREDKEY:
    518 		/* Generate a random stored key */
    519 		kg->kg_key = bits_getrandombits(keylen, 1);
    520 		if (!kg->kg_key) {
    521 			warnx("can't generate random bits for storedkey");
    522 			return -1;
    523 		}
    524 		break;
    525 	default:
    526 		return -1;
    527 	}
    528 
    529 	return keygen_filldefaults(kg->next, keylen);
    530 }
    531 
    532 /*
    533  * Strip the storedkey entries in preparation for inserting a shared
    534  * clause with a newly generated info string to derive this key from
    535  * KDF.  The result is that the key generated here is independent of
    536  * whatever storedkeys were involved in the old one, so there is no
    537  * need to keep them around,
    538  */
    539 void
    540 keygen_stripstored(struct keygen **kgp)
    541 {
    542 	struct keygen *kg, *to_free = NULL;
    543 
    544 	while ((kg = *kgp) != NULL) {
    545 		if (kg->kg_method == KEYGEN_STOREDKEY) {
    546 			*kgp = kg->next;
    547 			kg->next = to_free;
    548 			to_free = kg;
    549 		} else {
    550 			kgp = &kg->next;
    551 		}
    552 	}
    553 	keygen_free(to_free);
    554 }
    555 
    556 int
    557 keygen_makeshared(struct keygen *kg0)
    558 {
    559 	struct keygen *kg;
    560 
    561 	for (kg = kg0; kg != NULL; kg = kg->next) {
    562 		switch (kg->kg_method) {
    563 		case KEYGEN_RANDOMKEY:
    564 		case KEYGEN_URANDOMKEY:
    565 			warnx("(u)randomkey keygen cannot be shared");
    566 			return -1;
    567 		case KEYGEN_SHELL_CMD:
    568 #ifdef HAVE_ARGON2
    569 		case KEYGEN_ARGON2ID:
    570 #endif
    571 		case KEYGEN_PKCS5_PBKDF2_OLD:
    572 		case KEYGEN_PKCS5_PBKDF2_SHA1:
    573 			break;
    574 		case KEYGEN_STOREDKEY:
    575 			warnx("storedkey does not make sense as shared");
    576 			return -1;
    577 		default:
    578 			return -1;
    579 		}
    580 		if (kg->kg_sharedid != NULL) {
    581 			warnx("keygen already shared");
    582 			return -1;
    583 		}
    584 	}
    585 	for (kg = kg0; kg != NULL; kg = kg->next) {
    586 		struct uuid id;
    587 		char *idstr;
    588 		uint32_t status;
    589 
    590 		if (uuidgen(&id, 1) == -1) {
    591 			warn("uuidgen");
    592 			return -1;
    593 		}
    594 		uuid_to_string(&id, &idstr, &status);
    595 		if (status != uuid_s_ok) {
    596 			warnx("uuid_to_string: %"PRIu32, status);
    597 			return -1;
    598 		}
    599 
    600 		kg->kg_sharedid = string_fromcharstar(idstr);
    601 		kg->kg_sharedalg = SHARED_ALG_HKDF_HMAC_SHA256;
    602 		kg->kg_sharedlen = 8*SHA256_DIGEST_LENGTH;
    603 		kg->kg_sharedinfo = bits_getrandombits(DEFAULT_SALTLEN, 0);
    604 
    605 		free(idstr);
    606 	}
    607 	return 0;
    608 }
    609 
    610 int
    611 keygen_tweakshared(struct keygen *kg0)
    612 {
    613 	struct keygen *kg;
    614 
    615 	for (kg = kg0; kg != NULL; kg = kg->next) {
    616 		switch (kg->kg_method) {
    617 		case KEYGEN_RANDOMKEY:
    618 		case KEYGEN_URANDOMKEY:
    619 			warnx("(u)randomkey keygen cannot be shared");
    620 			return -1;
    621 		case KEYGEN_SHELL_CMD:
    622 #ifdef HAVE_ARGON2
    623 		case KEYGEN_ARGON2ID:
    624 #endif
    625 		case KEYGEN_PKCS5_PBKDF2_OLD:
    626 		case KEYGEN_PKCS5_PBKDF2_SHA1:
    627 			break;
    628 		case KEYGEN_STOREDKEY:
    629 			warnx("storedkey does not make sense as shared");
    630 			return -1;
    631 		default:
    632 			return -1;
    633 		}
    634 		if (kg->kg_sharedid == NULL) {
    635 			warnx("keygen not shared");
    636 			return -1;
    637 		}
    638 	}
    639 	for (kg = kg0; kg != NULL; kg = kg->next) {
    640 		if (kg->kg_method == KEYGEN_STOREDKEY)
    641 			continue;
    642 		bits_free(kg->kg_sharedinfo);
    643 		kg->kg_sharedinfo = bits_getrandombits(DEFAULT_SALTLEN, 0);
    644 	}
    645 	return 0;
    646 }
    647 
    648 struct keygen *
    649 keygen_combine(struct keygen *kg1, struct keygen *kg2)
    650 {
    651 	if (!kg1 && !kg2)
    652 		return NULL;
    653 
    654 	if (!kg1)
    655 		kg1 = keygen_new();
    656 
    657 	if (!kg2)
    658 		return kg1;
    659 
    660 	if (kg2->kg_method != KEYGEN_UNKNOWN)
    661 		kg1->kg_method = kg2->kg_method;
    662 
    663 	if (kg2->kg_iterations != (size_t)-1 && kg2->kg_iterations > 0)
    664 		kg1->kg_iterations = kg2->kg_iterations;
    665 
    666 	if (kg2->kg_memory != (size_t)-1 && kg2->kg_memory > 0)
    667 		kg1->kg_memory = kg2->kg_memory;
    668 
    669 	if (kg2->kg_parallelism != (size_t)-1 && kg2->kg_parallelism > 0)
    670 		kg1->kg_parallelism = kg2->kg_parallelism;
    671 
    672 	if (kg2->kg_version != (size_t)-1 && kg2->kg_version > 0)
    673 		kg1->kg_version = kg2->kg_version;
    674 
    675 	if (kg2->kg_salt)
    676 		bits_assign(&kg1->kg_salt, kg2->kg_salt);
    677 
    678 	if (kg2->kg_key)
    679 		bits_assign(&kg1->kg_key, kg2->kg_key);
    680 
    681 	if (kg2->kg_cmd)
    682 		string_assign(&kg1->kg_cmd, kg2->kg_cmd);
    683 
    684 	if (kg2->kg_sharedid)
    685 		string_assign(&kg1->kg_sharedid, kg2->kg_sharedid);
    686 	if (kg2->kg_sharedalg != SHARED_ALG_UNKNOWN) {
    687 		kg1->kg_sharedalg = kg2->kg_sharedalg;
    688 		kg1->kg_sharedlen = kg2->kg_sharedlen;
    689 	}
    690 	if (kg2->kg_sharedinfo)
    691 		bits_assign(&kg1->kg_sharedinfo, kg2->kg_sharedinfo);
    692 
    693 	return kg1;
    694 }
    695 
    696 struct keygen *
    697 keygen_method(string_t *in)
    698 {
    699 	struct keygen *kg = keygen_new();
    700 	const char *kgm = string_tocharstar(in);
    701 
    702 #ifdef HAVE_ARGON2
    703 	if (!strcmp("argon2id", kgm))
    704 		kg->kg_method = KEYGEN_ARGON2ID;
    705 #endif
    706 	if (!strcmp("pkcs5_pbkdf2", kgm))
    707 		kg->kg_method = KEYGEN_PKCS5_PBKDF2_OLD;
    708 	if (!strcmp("pkcs5_pbkdf2/sha1", kgm))
    709 		kg->kg_method = KEYGEN_PKCS5_PBKDF2_SHA1;
    710 	if (!strcmp("randomkey", kgm))
    711 		kg->kg_method = KEYGEN_RANDOMKEY;
    712 	if (!strcmp("storedkey", kgm))
    713 		kg->kg_method = KEYGEN_STOREDKEY;
    714 	if (!strcmp("urandomkey", kgm))
    715 		kg->kg_method = KEYGEN_URANDOMKEY;
    716 	if (!strcmp("shell_cmd", kgm))
    717 		kg->kg_method = KEYGEN_SHELL_CMD;
    718 
    719 	string_free(in);
    720 
    721 	if (kg->kg_method == KEYGEN_UNKNOWN)
    722 		warnx("unrecognized key generation method \"%s\"", kgm);
    723 	return kg;
    724 }
    725 
    726 struct keygen *
    727 keygen_set_method(struct keygen *kg, string_t *in)
    728 {
    729 
    730 	return keygen_combine(kg, keygen_method(in));
    731 }
    732 
    733 struct keygen *
    734 keygen_salt(bits_t *in)
    735 {
    736 	struct keygen *kg = keygen_new();
    737 
    738 	kg->kg_salt = in;
    739 	return kg;
    740 }
    741 
    742 struct keygen *
    743 keygen_iterations(size_t in)
    744 {
    745 	struct keygen *kg = keygen_new();
    746 
    747 	kg->kg_iterations = in;
    748 	return kg;
    749 }
    750 
    751 struct keygen *
    752 keygen_memory(size_t in)
    753 {
    754 	struct keygen *kg = keygen_new();
    755 
    756 	kg->kg_memory = in;
    757 	return kg;
    758 }
    759 
    760 struct keygen *
    761 keygen_parallelism(size_t in)
    762 {
    763 	struct keygen *kg = keygen_new();
    764 
    765 	kg->kg_parallelism = in;
    766 	return kg;
    767 }
    768 
    769 struct keygen *
    770 keygen_version(size_t in)
    771 {
    772 	struct keygen *kg = keygen_new();
    773 
    774 	kg->kg_version = in;
    775 	return kg;
    776 }
    777 
    778 void
    779 keygen_addlist(struct keygen **l, struct keygen *e)
    780 {
    781 	struct keygen *t;
    782 
    783 	if (*l) {
    784 		t = *l;
    785 		for (;t->next; t = t->next)
    786 			;
    787 		t->next = e;
    788 	} else {
    789 		*l = e;
    790 	}
    791 }
    792 
    793 struct keygen *
    794 keygen_key(bits_t *in)
    795 {
    796 	struct keygen *kg = keygen_new();
    797 
    798 	kg->kg_key = in;
    799 	return kg;
    800 }
    801 
    802 struct keygen *
    803 keygen_cmd(string_t *in)
    804 {
    805 	struct keygen *kg = keygen_new();
    806 
    807 	kg->kg_cmd = in;
    808 	return kg;
    809 }
    810 
    811 struct keygen *
    812 keygen_shared(string_t *id, string_t *alg, bits_t *info)
    813 {
    814 	struct keygen *kg = keygen_new();
    815 	const char *algname = string_tocharstar(alg);
    816 
    817 	if (!strcmp("hkdf-hmac-sha256", algname)) {
    818 		kg->kg_sharedalg = SHARED_ALG_HKDF_HMAC_SHA256;
    819 		kg->kg_sharedlen = 8*SHA256_DIGEST_LENGTH;
    820 	}
    821 
    822 	if (kg->kg_sharedalg == SHARED_ALG_UNKNOWN) {
    823 		warnx("unrecognized shared key derivation algorithm \"%s\"",
    824 		    algname);
    825 	}
    826 
    827 	kg->kg_sharedid = id;
    828 	kg->kg_sharedinfo = info;
    829 	return kg;
    830 }
    831 
    832 struct params *
    833 params_fget(FILE *f)
    834 {
    835 	struct params *p;
    836 
    837 	p = cgdparsefile(f);
    838 
    839 	if (!p)
    840 		return NULL;
    841 
    842 	/*
    843 	 * We deal with the deprecated keygen structure by prepending it
    844 	 * to the list of keygens, so that the rest of the code does not
    845 	 * have to deal with this backwards compat issue.  The deprecated
    846 	 * ``xor_key'' field may be stored in p->dep_keygen->kg_key.  If
    847 	 * it exists, we construct a storedkey keygen struct as well.  Also,
    848 	 * default the iteration count to 128 as the old code did.
    849 	 */
    850 
    851 	if (p->dep_keygen) {
    852 		if (p->dep_keygen->kg_iterations == (size_t)-1)
    853 			p->dep_keygen->kg_iterations = 128;
    854 		p->dep_keygen->next = p->keygen;
    855 		if (p->dep_keygen->kg_key) {
    856 			p->keygen = keygen_generate(KEYGEN_STOREDKEY);
    857 			p->keygen->kg_key = p->dep_keygen->kg_key;
    858 			p->dep_keygen->kg_key = NULL;
    859 			p->keygen->next = p->dep_keygen;
    860 		} else {
    861 			p->keygen = p->dep_keygen;
    862 		}
    863 		p->dep_keygen = NULL;
    864 	}
    865 	return p;
    866 }
    867 
    868 struct params *
    869 params_cget(const char *fn)
    870 {
    871 	struct params	*p;
    872 	FILE		*f;
    873 	char		filename[MAXPATHLEN];
    874 
    875 	if ((f = fopen(fn, "r")) == NULL && fn[0] != '/') {
    876 		snprintf(filename, sizeof(filename), "%s/%s",
    877 		    CGDCONFIG_DIR, fn);
    878 		fn = filename;
    879 		f = fopen(fn, "r");
    880 	}
    881 
    882 	if (f == NULL) {
    883 		warn("failed to open params file \"%s\"", fn);
    884 		return NULL;
    885 	}
    886 	p = params_fget(f);
    887 	(void)fclose(f);
    888 	return p;
    889 }
    890 
    891 #define WRAP_COL	50
    892 #define TAB_COL		8
    893 
    894 static void
    895 spaces(FILE *f, int len)
    896 {
    897 
    898 	while (len-- > 0)
    899 		(void)fputc(' ', f);
    900 }
    901 
    902 static void
    903 print_kvpair_cstr(FILE *f, int ts, const char *key, const char *val)
    904 {
    905 
    906 	spaces(f, ts);
    907 	(void)fprintf(f, "%s %s;\n", key, val);
    908 }
    909 
    910 static void
    911 print_kvpair_string(FILE *f, int ts, const char *key, const string_t *val)
    912 {
    913 
    914 	print_kvpair_cstr(f, ts, key, string_tocharstar(val));
    915 }
    916 
    917 static void
    918 print_kvpair_int(FILE *f, int ts, const char *key, size_t val)
    919 {
    920 	char	*tmp;
    921 
    922 	if (!key || val == (size_t)-1)
    923 		return;
    924 
    925 	if (asprintf(&tmp, "%zu", val) == -1)
    926 		err(1, NULL);
    927 	print_kvpair_cstr(f, ts, key, tmp);
    928 	free(tmp);
    929 }
    930 
    931 /*
    932  * prints out a base64 encoded k-v pair to f.  It encodes the length
    933  * of the bitstream as a 32bit unsigned integer in network byte order
    934  * up front.
    935  */
    936 
    937 static void
    938 print_kvpair_b64(FILE *f, int curpos, int ts, const char *key, bits_t *val)
    939 {
    940 	string_t	*str;
    941 	int		 i;
    942 	int		 len;
    943 	int		 pos;
    944 	const char	*out;
    945 
    946 	if (!key || !val)
    947 		return;
    948 
    949 	str = bits_encode(val);
    950 	out = string_tocharstar(str);
    951 	len = strlen(out);
    952 
    953 	spaces(f, ts);
    954 	(void)fprintf(f, "%s ", key);
    955 	curpos += ts + strlen(key) + 1;
    956 	ts = curpos;
    957 
    958 	for (i=0, pos=curpos; i < len; i++, pos++) {
    959 		if (pos > WRAP_COL) {
    960 			(void)fprintf(f, " \\\n");
    961 			spaces(f, ts);
    962 			pos = ts;
    963 		}
    964 		(void)fputc(out[i], f);
    965 	}
    966 	(void)fprintf(f, ";\n");
    967 	string_free(str);
    968 }
    969 
    970 static void
    971 print_shared(FILE *f, int ts, struct keygen *kg)
    972 {
    973 	static const char *const sharedalgs[] = {
    974 		[SHARED_ALG_UNKNOWN] = "unknown",
    975 		[SHARED_ALG_HKDF_HMAC_SHA256] = "hkdf-hmac-sha256",
    976 	};
    977 
    978 	if (kg->kg_sharedid == NULL ||
    979 	    kg->kg_sharedalg < 0 ||
    980 	    (size_t)kg->kg_sharedalg >= __arraycount(sharedalgs))
    981 		return;
    982 	fprintf(f, "%*sshared \"%s\" \\\n", ts, "",
    983 	    string_tocharstar(kg->kg_sharedid));
    984 	ts += 4;
    985 	fprintf(f, "%*salgorithm %s \\\n", ts, "",
    986 	    sharedalgs[kg->kg_sharedalg]);
    987 	print_kvpair_b64(f, 0, ts, "subkey", kg->kg_sharedinfo);
    988 }
    989 
    990 int
    991 keygen_fput(struct keygen *kg, int ts, FILE *f)
    992 {
    993 	int	curpos = 0;
    994 
    995 	if (!kg)
    996 		return 0;
    997 	(void)fprintf(f, "keygen ");
    998 	curpos += strlen("keygen ");
    999 	switch (kg->kg_method) {
   1000 	case KEYGEN_STOREDKEY:
   1001 		(void)fprintf(f, "storedkey ");
   1002 		curpos += strlen("storedkey ");
   1003 		print_kvpair_b64(f, curpos, 0, "key", kg->kg_key);
   1004 		break;
   1005 	case KEYGEN_RANDOMKEY:
   1006 		(void)fprintf(f, "randomkey;\n");
   1007 		break;
   1008 	case KEYGEN_URANDOMKEY:
   1009 		(void)fprintf(f, "urandomkey;\n");
   1010 		break;
   1011 #ifdef HAVE_ARGON2
   1012 	case KEYGEN_ARGON2ID:
   1013 		(void)fprintf(f, "argon2id {\n");
   1014 		print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
   1015 		print_kvpair_int(f, ts, "memory", kg->kg_memory);
   1016 		print_kvpair_int(f, ts, "parallelism", kg->kg_parallelism);
   1017 		print_kvpair_int(f, ts, "version", kg->kg_version);
   1018 		print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt);
   1019 		print_shared(f, ts, kg);
   1020 		(void)fprintf(f, "};\n");
   1021 		break;
   1022 #endif
   1023 	case KEYGEN_PKCS5_PBKDF2_OLD:
   1024 		(void)fprintf(f, "pkcs5_pbkdf2 {\n");
   1025 		print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
   1026 		print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt);
   1027 		print_shared(f, ts, kg);
   1028 		(void)fprintf(f, "};\n");
   1029 		break;
   1030 	case KEYGEN_PKCS5_PBKDF2_SHA1:
   1031 		(void)fprintf(f, "pkcs5_pbkdf2/sha1 {\n");
   1032 		print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
   1033 		print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt);
   1034 		print_shared(f, ts, kg);
   1035 		(void)fprintf(f, "};\n");
   1036 		break;
   1037 	default:
   1038 		warnx("keygen_fput: %d not a valid method", kg->kg_method);
   1039 		break;
   1040 	}
   1041 	return keygen_fput(kg->next, ts, f);
   1042 }
   1043 
   1044 int
   1045 params_fput(struct params *p, FILE *f)
   1046 {
   1047 	int	ts = 0;		/* tabstop of 0 spaces */
   1048 
   1049 	print_kvpair_string(f, ts, "algorithm", p->algorithm);
   1050 	print_kvpair_string(f, ts, "iv-method", p->ivmeth);
   1051 	print_kvpair_int(f, ts, "keylength", p->keylen);
   1052 	print_kvpair_int(f, ts, "blocksize", p->bsize);
   1053 	switch (p->verify_method) {
   1054 	case VERIFY_NONE:
   1055 		print_kvpair_cstr(f, ts, "verify_method", "none");
   1056 		break;
   1057 	case VERIFY_DISKLABEL:
   1058 		print_kvpair_cstr(f, ts, "verify_method", "disklabel");
   1059 		break;
   1060 	case VERIFY_FFS:
   1061 		print_kvpair_cstr(f, ts, "verify_method", "ffs");
   1062 		break;
   1063 	case VERIFY_REENTER:
   1064 		print_kvpair_cstr(f, ts, "verify_method", "re-enter");
   1065 		break;
   1066 	case VERIFY_MBR:
   1067 		print_kvpair_cstr(f, ts, "verify_method", "mbr");
   1068 		break;
   1069 	case VERIFY_GPT:
   1070 		print_kvpair_cstr(f, ts, "verify_method", "gpt");
   1071 		break;
   1072 #ifdef HAVE_ZFS
   1073 	case VERIFY_ZFS:
   1074 		print_kvpair_cstr(f, ts, "verify_method", "zfs");
   1075 		break;
   1076 #endif
   1077 	default:
   1078 		warnx("unsupported verify_method (%d)", p->verify_method);
   1079 		return -1;
   1080 	}
   1081 	return keygen_fput(p->keygen, TAB_COL, f);
   1082 }
   1083 
   1084 int
   1085 params_cput(struct params *p, const char *fn)
   1086 {
   1087 	FILE	*f;
   1088 
   1089 	if (fn && *fn) {
   1090 		if ((f = fopen(fn, "w")) == NULL) {
   1091 			warn("could not open outfile \"%s\"", fn);
   1092 			return -1;
   1093 		}
   1094 	} else {
   1095 		f = stdout;
   1096 	}
   1097 	return params_fput(p, f);
   1098 }
   1099 
   1100 static int
   1101 crypt_defaults_lookup(const char *alg)
   1102 {
   1103 	unsigned	i;
   1104 
   1105 	for (i=0; i < (sizeof(crypto_defaults) / sizeof(crypto_defaults[0])); i++)
   1106 		if (!strcmp(alg, crypto_defaults[i].alg))
   1107 			return i;
   1108 
   1109 	return -1;
   1110 }
   1111