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 *
params_new(void)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
params_init(struct params * p)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
params_free(struct params * p)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 *
params_combine(struct params * p1,struct params * p2)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
params_filldefaults(struct params * p)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
params_verify(const struct params * p)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 *
params_algorithm(string_t * in)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 *
params_ivmeth(string_t * in)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 *
params_keylen(size_t in)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 *
params_bsize(size_t in)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 *
params_verify_method(string_t * in)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 *
params_keygen(struct keygen * in)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 *
params_dep_keygen(struct keygen * in)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 *
keygen_new(void)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
keygen_free(struct keygen * kg)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
keygen_verify(const struct keygen * kg)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 *
keygen_generate(int method)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
keygen_filldefaults(struct keygen * kg,size_t keylen)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
keygen_stripstored(struct keygen ** kgp)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
keygen_makeshared(struct keygen * kg0)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
keygen_tweakshared(struct keygen * kg0)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 *
keygen_combine(struct keygen * kg1,struct keygen * kg2)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 *
keygen_method(string_t * in)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 *
keygen_set_method(struct keygen * kg,string_t * in)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 *
keygen_salt(bits_t * in)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 *
keygen_iterations(size_t in)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 *
keygen_memory(size_t in)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 *
keygen_parallelism(size_t in)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 *
keygen_version(size_t in)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
keygen_addlist(struct keygen ** l,struct keygen * e)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 *
keygen_key(bits_t * in)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 *
keygen_cmd(string_t * in)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 *
keygen_shared(string_t * id,string_t * alg,bits_t * info)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 *
params_fget(FILE * f)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 *
params_cget(const char * fn)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
spaces(FILE * f,int len)895 spaces(FILE *f, int len)
896 {
897
898 while (len-- > 0)
899 (void)fputc(' ', f);
900 }
901
902 static void
print_kvpair_cstr(FILE * f,int ts,const char * key,const char * val)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
print_kvpair_string(FILE * f,int ts,const char * key,const string_t * val)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
print_kvpair_int(FILE * f,int ts,const char * key,size_t val)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
print_kvpair_b64(FILE * f,int curpos,int ts,const char * key,bits_t * val)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
print_shared(FILE * f,int ts,struct keygen * kg)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
keygen_fput(struct keygen * kg,int ts,FILE * f)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
params_fput(struct params * p,FILE * f)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
params_cput(struct params * p,const char * fn)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
crypt_defaults_lookup(const char * alg)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