1 /* $NetBSD: params.c,v 1.34 2022/08/12 10:49:35 riastradh 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.34 2022/08/12 10:49:35 riastradh 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 291 string_free(in); 292 293 if (p->verify_method == VERIFY_UNKNOWN) 294 warnx("params_setverify_method: unrecognized " 295 "verify method \"%s\"", vm); 296 return p; 297 } 298 299 struct params * 300 params_keygen(struct keygen *in) 301 { 302 struct params *p = params_new(); 303 304 p->keygen = in; 305 return p; 306 } 307 308 struct params * 309 params_dep_keygen(struct keygen *in) 310 { 311 struct params *p = params_new(); 312 313 p->dep_keygen = in; 314 return p; 315 } 316 317 struct keygen * 318 keygen_new(void) 319 { 320 struct keygen *kg; 321 322 kg = emalloc(sizeof(*kg)); 323 kg->kg_method = KEYGEN_UNKNOWN; 324 kg->kg_iterations = (size_t)-1; 325 kg->kg_memory = (size_t)-1; 326 kg->kg_parallelism = (size_t)-1; 327 kg->kg_version = (size_t)-1; 328 kg->kg_salt = NULL; 329 kg->kg_key = NULL; 330 kg->kg_cmd = NULL; 331 kg->kg_sharedid = NULL; 332 kg->kg_sharedalg = SHARED_ALG_UNKNOWN; 333 kg->kg_sharedlen = (size_t)-1; 334 kg->kg_sharedinfo = NULL; 335 kg->next = NULL; 336 return kg; 337 } 338 339 void 340 keygen_free(struct keygen *kg) 341 { 342 343 if (!kg) 344 return; 345 bits_free(kg->kg_salt); 346 bits_free(kg->kg_key); 347 string_free(kg->kg_cmd); 348 string_free(kg->kg_sharedid); 349 bits_free(kg->kg_sharedinfo); 350 keygen_free(kg->next); 351 free(kg); 352 } 353 354 /* 355 * keygen_verify traverses the keygen structures and ensures 356 * that the appropriate information is available. 357 */ 358 359 int 360 keygen_verify(const struct keygen *kg) 361 { 362 363 if (!kg) 364 return 1; 365 switch (kg->kg_method) { 366 #ifdef HAVE_ARGON2 367 case KEYGEN_ARGON2ID: 368 if (kg->kg_iterations == (size_t)-1) { 369 warnx("keygen argon2id must provide `iterations'"); 370 return 0; 371 } 372 if (kg->kg_memory == (size_t)-1) { 373 warnx("keygen argon2id must provide `memory'"); 374 return 0; 375 } 376 if (kg->kg_parallelism == (size_t)-1) { 377 warnx("keygen argon2id must provide `parallelism'"); 378 return 0; 379 } 380 if (kg->kg_version == (size_t)-1) { 381 warnx("keygen argon2id must provide `version'"); 382 return 0; 383 } 384 if (kg->kg_cmd) 385 warnx("keygen argon2id does not need a `cmd'"); 386 if (kg->kg_key) 387 warnx("keygen argon2id does not need a `key'"); 388 if (!kg->kg_salt) { 389 warnx("keygen argon2id must provide a salt"); 390 return 0; 391 } 392 break; 393 #endif 394 case KEYGEN_PKCS5_PBKDF2_OLD: 395 if (kg->kg_iterations == (size_t)-1) { 396 warnx("keygen pkcs5_pbkdf2 must provide `iterations'"); 397 return 0; 398 } 399 if (kg->kg_key) 400 warnx("keygen pkcs5_pbkdf2 does not need a `key'"); 401 if (!kg->kg_salt) { 402 warnx("keygen pkcs5_pbkdf2 must provide a salt"); 403 return 0; 404 } 405 if (kg->kg_cmd) 406 warnx("keygen pkcs5_pbkdf2 does not need a `cmd'"); 407 break; 408 case KEYGEN_PKCS5_PBKDF2_SHA1: 409 if (kg->kg_iterations == (size_t)-1) { 410 warnx("keygen pkcs5_pbkdf2/sha1 must provide `iterations'"); 411 return 0; 412 } 413 if (kg->kg_key) 414 warnx("keygen pkcs5_pbkdf2/sha1 does not need a `key'"); 415 if (!kg->kg_salt) { 416 warnx("keygen pkcs5_pbkdf2/sha1 must provide a salt"); 417 return 0; 418 } 419 if (kg->kg_cmd) 420 warnx("keygen pkcs5_pbkdf2/sha1 does not need a `cmd'"); 421 break; 422 case KEYGEN_STOREDKEY: 423 if (kg->kg_iterations != (size_t)-1) 424 warnx("keygen storedkey does not need `iterations'"); 425 if (!kg->kg_key) { 426 warnx("keygen storedkey must provide a key"); 427 return 0; 428 } 429 if (kg->kg_salt) 430 warnx("keygen storedkey does not need `salt'"); 431 if (kg->kg_cmd) 432 warnx("keygen storedkey does not need `cmd'"); 433 break; 434 case KEYGEN_RANDOMKEY: 435 case KEYGEN_URANDOMKEY: 436 if (kg->kg_iterations != (size_t)-1) 437 warnx("keygen [u]randomkey does not need `iterations'"); 438 if (kg->kg_key) 439 warnx("keygen [u]randomkey does not need `key'"); 440 if (kg->kg_salt) 441 warnx("keygen [u]randomkey does not need `salt'"); 442 if (kg->kg_cmd) 443 warnx("keygen [u]randomkey does not need `cmd'"); 444 if (kg->kg_sharedid) 445 warnx("keygen [u]randomkey makes no sense shared"); 446 break; 447 case KEYGEN_SHELL_CMD: 448 if (kg->kg_iterations != (size_t)-1) 449 warnx("keygen shell_cmd does not need `iterations'"); 450 if (kg->kg_key) 451 warnx("keygen shell_cmd does not need `key'"); 452 if (kg->kg_salt) 453 warnx("keygen shell_cmd does not need `salt'"); 454 if (!kg->kg_cmd) { 455 warnx("keygen shell_cmd must provide a `cmd'"); 456 return 0; 457 } 458 break; 459 } 460 return keygen_verify(kg->next); 461 } 462 463 struct keygen * 464 keygen_generate(int method) 465 { 466 struct keygen *kg; 467 468 kg = keygen_new(); 469 if (!kg) 470 return NULL; 471 472 kg->kg_method = method; 473 return kg; 474 } 475 476 /* 477 * keygen_filldefaults walks the keygen list and fills in 478 * default values. The defaults may be either calibrated 479 * or randomly generated so this function is designed to be 480 * called when generating a new parameters file, not when 481 * reading a parameters file. 482 */ 483 484 int 485 keygen_filldefaults(struct keygen *kg, size_t keylen) 486 { 487 488 if (!kg) 489 return 0; 490 switch (kg->kg_method) { 491 case KEYGEN_RANDOMKEY: 492 case KEYGEN_URANDOMKEY: 493 case KEYGEN_SHELL_CMD: 494 break; 495 #ifdef HAVE_ARGON2 496 case KEYGEN_ARGON2ID: 497 kg->kg_version = ARGON2_VERSION_NUMBER; 498 kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1); 499 argon2id_calibrate(BITS2BYTES(keylen), DEFAULT_SALTLEN, 500 &kg->kg_iterations, &kg->kg_memory, &kg->kg_parallelism); 501 break; 502 #endif 503 case KEYGEN_PKCS5_PBKDF2_OLD: 504 case KEYGEN_PKCS5_PBKDF2_SHA1: 505 kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1); 506 kg->kg_iterations = pkcs5_pbkdf2_calibrate(BITS2BYTES(keylen), 507 DEFAULT_ITERATION_TIME); 508 if (kg->kg_iterations < 1) { 509 warnx("could not calibrate pkcs5_pbkdf2"); 510 return -1; 511 } 512 break; 513 case KEYGEN_STOREDKEY: 514 /* Generate a random stored key */ 515 kg->kg_key = bits_getrandombits(keylen, 1); 516 if (!kg->kg_key) { 517 warnx("can't generate random bits for storedkey"); 518 return -1; 519 } 520 break; 521 default: 522 return -1; 523 } 524 525 return keygen_filldefaults(kg->next, keylen); 526 } 527 528 /* 529 * Strip the storedkey entries in preparation for inserting a shared 530 * clause with a newly generated info string to derive this key from 531 * KDF. The result is that the key generated here is independent of 532 * whatever storedkeys were involved in the old one, so there is no 533 * need to keep them around, 534 */ 535 void 536 keygen_stripstored(struct keygen **kgp) 537 { 538 struct keygen *kg, *to_free = NULL; 539 540 while ((kg = *kgp) != NULL) { 541 if (kg->kg_method == KEYGEN_STOREDKEY) { 542 *kgp = kg->next; 543 kg->next = to_free; 544 to_free = kg; 545 } else { 546 kgp = &kg->next; 547 } 548 } 549 keygen_free(to_free); 550 } 551 552 int 553 keygen_makeshared(struct keygen *kg0) 554 { 555 struct keygen *kg; 556 557 for (kg = kg0; kg != NULL; kg = kg->next) { 558 switch (kg->kg_method) { 559 case KEYGEN_RANDOMKEY: 560 case KEYGEN_URANDOMKEY: 561 warnx("(u)randomkey keygen cannot be shared"); 562 return -1; 563 case KEYGEN_SHELL_CMD: 564 #ifdef HAVE_ARGON2 565 case KEYGEN_ARGON2ID: 566 #endif 567 case KEYGEN_PKCS5_PBKDF2_OLD: 568 case KEYGEN_PKCS5_PBKDF2_SHA1: 569 break; 570 case KEYGEN_STOREDKEY: 571 warnx("storedkey does not make sense as shared"); 572 return -1; 573 default: 574 return -1; 575 } 576 if (kg->kg_sharedid != NULL) { 577 warnx("keygen already shared"); 578 return -1; 579 } 580 } 581 for (kg = kg0; kg != NULL; kg = kg->next) { 582 struct uuid id; 583 char *idstr; 584 uint32_t status; 585 586 if (uuidgen(&id, 1) == -1) { 587 warn("uuidgen"); 588 return -1; 589 } 590 uuid_to_string(&id, &idstr, &status); 591 if (status != uuid_s_ok) { 592 warnx("uuid_to_string: %"PRIu32, status); 593 return -1; 594 } 595 596 kg->kg_sharedid = string_fromcharstar(idstr); 597 kg->kg_sharedalg = SHARED_ALG_HKDF_HMAC_SHA256; 598 kg->kg_sharedlen = 8*SHA256_DIGEST_LENGTH; 599 kg->kg_sharedinfo = bits_getrandombits(DEFAULT_SALTLEN, 0); 600 601 free(idstr); 602 } 603 return 0; 604 } 605 606 int 607 keygen_tweakshared(struct keygen *kg0) 608 { 609 struct keygen *kg; 610 611 for (kg = kg0; kg != NULL; kg = kg->next) { 612 switch (kg->kg_method) { 613 case KEYGEN_RANDOMKEY: 614 case KEYGEN_URANDOMKEY: 615 warnx("(u)randomkey keygen cannot be shared"); 616 return -1; 617 case KEYGEN_SHELL_CMD: 618 #ifdef HAVE_ARGON2 619 case KEYGEN_ARGON2ID: 620 #endif 621 case KEYGEN_PKCS5_PBKDF2_OLD: 622 case KEYGEN_PKCS5_PBKDF2_SHA1: 623 break; 624 case KEYGEN_STOREDKEY: 625 warnx("storedkey does not make sense as shared"); 626 return -1; 627 default: 628 return -1; 629 } 630 if (kg->kg_sharedid == NULL) { 631 warnx("keygen not shared"); 632 return -1; 633 } 634 } 635 for (kg = kg0; kg != NULL; kg = kg->next) { 636 if (kg->kg_method == KEYGEN_STOREDKEY) 637 continue; 638 bits_free(kg->kg_sharedinfo); 639 kg->kg_sharedinfo = bits_getrandombits(DEFAULT_SALTLEN, 0); 640 } 641 return 0; 642 } 643 644 struct keygen * 645 keygen_combine(struct keygen *kg1, struct keygen *kg2) 646 { 647 if (!kg1 && !kg2) 648 return NULL; 649 650 if (!kg1) 651 kg1 = keygen_new(); 652 653 if (!kg2) 654 return kg1; 655 656 if (kg2->kg_method != KEYGEN_UNKNOWN) 657 kg1->kg_method = kg2->kg_method; 658 659 if (kg2->kg_iterations != (size_t)-1 && kg2->kg_iterations > 0) 660 kg1->kg_iterations = kg2->kg_iterations; 661 662 if (kg2->kg_memory != (size_t)-1 && kg2->kg_memory > 0) 663 kg1->kg_memory = kg2->kg_memory; 664 665 if (kg2->kg_parallelism != (size_t)-1 && kg2->kg_parallelism > 0) 666 kg1->kg_parallelism = kg2->kg_parallelism; 667 668 if (kg2->kg_version != (size_t)-1 && kg2->kg_version > 0) 669 kg1->kg_version = kg2->kg_version; 670 671 if (kg2->kg_salt) 672 bits_assign(&kg1->kg_salt, kg2->kg_salt); 673 674 if (kg2->kg_key) 675 bits_assign(&kg1->kg_key, kg2->kg_key); 676 677 if (kg2->kg_cmd) 678 string_assign(&kg1->kg_cmd, kg2->kg_cmd); 679 680 if (kg2->kg_sharedid) 681 string_assign(&kg1->kg_sharedid, kg2->kg_sharedid); 682 if (kg2->kg_sharedalg != SHARED_ALG_UNKNOWN) { 683 kg1->kg_sharedalg = kg2->kg_sharedalg; 684 kg1->kg_sharedlen = kg2->kg_sharedlen; 685 } 686 if (kg2->kg_sharedinfo) 687 bits_assign(&kg1->kg_sharedinfo, kg2->kg_sharedinfo); 688 689 return kg1; 690 } 691 692 struct keygen * 693 keygen_method(string_t *in) 694 { 695 struct keygen *kg = keygen_new(); 696 const char *kgm = string_tocharstar(in); 697 698 #ifdef HAVE_ARGON2 699 if (!strcmp("argon2id", kgm)) 700 kg->kg_method = KEYGEN_ARGON2ID; 701 #endif 702 if (!strcmp("pkcs5_pbkdf2", kgm)) 703 kg->kg_method = KEYGEN_PKCS5_PBKDF2_OLD; 704 if (!strcmp("pkcs5_pbkdf2/sha1", kgm)) 705 kg->kg_method = KEYGEN_PKCS5_PBKDF2_SHA1; 706 if (!strcmp("randomkey", kgm)) 707 kg->kg_method = KEYGEN_RANDOMKEY; 708 if (!strcmp("storedkey", kgm)) 709 kg->kg_method = KEYGEN_STOREDKEY; 710 if (!strcmp("urandomkey", kgm)) 711 kg->kg_method = KEYGEN_URANDOMKEY; 712 if (!strcmp("shell_cmd", kgm)) 713 kg->kg_method = KEYGEN_SHELL_CMD; 714 715 string_free(in); 716 717 if (kg->kg_method == KEYGEN_UNKNOWN) 718 warnx("unrecognized key generation method \"%s\"", kgm); 719 return kg; 720 } 721 722 struct keygen * 723 keygen_set_method(struct keygen *kg, string_t *in) 724 { 725 726 return keygen_combine(kg, keygen_method(in)); 727 } 728 729 struct keygen * 730 keygen_salt(bits_t *in) 731 { 732 struct keygen *kg = keygen_new(); 733 734 kg->kg_salt = in; 735 return kg; 736 } 737 738 struct keygen * 739 keygen_iterations(size_t in) 740 { 741 struct keygen *kg = keygen_new(); 742 743 kg->kg_iterations = in; 744 return kg; 745 } 746 747 struct keygen * 748 keygen_memory(size_t in) 749 { 750 struct keygen *kg = keygen_new(); 751 752 kg->kg_memory = in; 753 return kg; 754 } 755 756 struct keygen * 757 keygen_parallelism(size_t in) 758 { 759 struct keygen *kg = keygen_new(); 760 761 kg->kg_parallelism = in; 762 return kg; 763 } 764 765 struct keygen * 766 keygen_version(size_t in) 767 { 768 struct keygen *kg = keygen_new(); 769 770 kg->kg_version = in; 771 return kg; 772 } 773 774 void 775 keygen_addlist(struct keygen **l, struct keygen *e) 776 { 777 struct keygen *t; 778 779 if (*l) { 780 t = *l; 781 for (;t->next; t = t->next) 782 ; 783 t->next = e; 784 } else { 785 *l = e; 786 } 787 } 788 789 struct keygen * 790 keygen_key(bits_t *in) 791 { 792 struct keygen *kg = keygen_new(); 793 794 kg->kg_key = in; 795 return kg; 796 } 797 798 struct keygen * 799 keygen_cmd(string_t *in) 800 { 801 struct keygen *kg = keygen_new(); 802 803 kg->kg_cmd = in; 804 return kg; 805 } 806 807 struct keygen * 808 keygen_shared(string_t *id, string_t *alg, bits_t *info) 809 { 810 struct keygen *kg = keygen_new(); 811 const char *algname = string_tocharstar(alg); 812 813 if (!strcmp("hkdf-hmac-sha256", algname)) { 814 kg->kg_sharedalg = SHARED_ALG_HKDF_HMAC_SHA256; 815 kg->kg_sharedlen = 8*SHA256_DIGEST_LENGTH; 816 } 817 818 if (kg->kg_sharedalg == SHARED_ALG_UNKNOWN) { 819 warnx("unrecognized shared key derivation algorithm \"%s\"", 820 algname); 821 } 822 823 kg->kg_sharedid = id; 824 kg->kg_sharedinfo = info; 825 return kg; 826 } 827 828 struct params * 829 params_fget(FILE *f) 830 { 831 struct params *p; 832 833 p = cgdparsefile(f); 834 835 if (!p) 836 return NULL; 837 838 /* 839 * We deal with the deprecated keygen structure by prepending it 840 * to the list of keygens, so that the rest of the code does not 841 * have to deal with this backwards compat issue. The deprecated 842 * ``xor_key'' field may be stored in p->dep_keygen->kg_key. If 843 * it exists, we construct a storedkey keygen struct as well. Also, 844 * default the iteration count to 128 as the old code did. 845 */ 846 847 if (p->dep_keygen) { 848 if (p->dep_keygen->kg_iterations == (size_t)-1) 849 p->dep_keygen->kg_iterations = 128; 850 p->dep_keygen->next = p->keygen; 851 if (p->dep_keygen->kg_key) { 852 p->keygen = keygen_generate(KEYGEN_STOREDKEY); 853 p->keygen->kg_key = p->dep_keygen->kg_key; 854 p->dep_keygen->kg_key = NULL; 855 p->keygen->next = p->dep_keygen; 856 } else { 857 p->keygen = p->dep_keygen; 858 } 859 p->dep_keygen = NULL; 860 } 861 return p; 862 } 863 864 struct params * 865 params_cget(const char *fn) 866 { 867 struct params *p; 868 FILE *f; 869 char filename[MAXPATHLEN]; 870 871 if ((f = fopen(fn, "r")) == NULL && fn[0] != '/') { 872 snprintf(filename, sizeof(filename), "%s/%s", 873 CGDCONFIG_DIR, fn); 874 fn = filename; 875 f = fopen(fn, "r"); 876 } 877 878 if (f == NULL) { 879 warn("failed to open params file \"%s\"", fn); 880 return NULL; 881 } 882 p = params_fget(f); 883 (void)fclose(f); 884 return p; 885 } 886 887 #define WRAP_COL 50 888 #define TAB_COL 8 889 890 static void 891 spaces(FILE *f, int len) 892 { 893 894 while (len-- > 0) 895 (void)fputc(' ', f); 896 } 897 898 static void 899 print_kvpair_cstr(FILE *f, int ts, const char *key, const char *val) 900 { 901 902 spaces(f, ts); 903 (void)fprintf(f, "%s %s;\n", key, val); 904 } 905 906 static void 907 print_kvpair_string(FILE *f, int ts, const char *key, const string_t *val) 908 { 909 910 print_kvpair_cstr(f, ts, key, string_tocharstar(val)); 911 } 912 913 static void 914 print_kvpair_int(FILE *f, int ts, const char *key, size_t val) 915 { 916 char *tmp; 917 918 if (!key || val == (size_t)-1) 919 return; 920 921 if (asprintf(&tmp, "%zu", val) == -1) 922 err(1, NULL); 923 print_kvpair_cstr(f, ts, key, tmp); 924 free(tmp); 925 } 926 927 /* 928 * prints out a base64 encoded k-v pair to f. It encodes the length 929 * of the bitstream as a 32bit unsigned integer in network byte order 930 * up front. 931 */ 932 933 static void 934 print_kvpair_b64(FILE *f, int curpos, int ts, const char *key, bits_t *val) 935 { 936 string_t *str; 937 int i; 938 int len; 939 int pos; 940 const char *out; 941 942 if (!key || !val) 943 return; 944 945 str = bits_encode(val); 946 out = string_tocharstar(str); 947 len = strlen(out); 948 949 spaces(f, ts); 950 (void)fprintf(f, "%s ", key); 951 curpos += ts + strlen(key) + 1; 952 ts = curpos; 953 954 for (i=0, pos=curpos; i < len; i++, pos++) { 955 if (pos > WRAP_COL) { 956 (void)fprintf(f, " \\\n"); 957 spaces(f, ts); 958 pos = ts; 959 } 960 (void)fputc(out[i], f); 961 } 962 (void)fprintf(f, ";\n"); 963 string_free(str); 964 } 965 966 static void 967 print_shared(FILE *f, int ts, struct keygen *kg) 968 { 969 static const char *const sharedalgs[] = { 970 [SHARED_ALG_UNKNOWN] = "unknown", 971 [SHARED_ALG_HKDF_HMAC_SHA256] = "hkdf-hmac-sha256", 972 }; 973 974 if (kg->kg_sharedid == NULL || 975 kg->kg_sharedalg < 0 || 976 (size_t)kg->kg_sharedalg >= __arraycount(sharedalgs)) 977 return; 978 fprintf(f, "%*sshared \"%s\" \\\n", ts, "", 979 string_tocharstar(kg->kg_sharedid)); 980 ts += 4; 981 fprintf(f, "%*salgorithm %s \\\n", ts, "", 982 sharedalgs[kg->kg_sharedalg]); 983 print_kvpair_b64(f, 0, ts, "subkey", kg->kg_sharedinfo); 984 } 985 986 int 987 keygen_fput(struct keygen *kg, int ts, FILE *f) 988 { 989 int curpos = 0; 990 991 if (!kg) 992 return 0; 993 (void)fprintf(f, "keygen "); 994 curpos += strlen("keygen "); 995 switch (kg->kg_method) { 996 case KEYGEN_STOREDKEY: 997 (void)fprintf(f, "storedkey "); 998 curpos += strlen("storedkey "); 999 print_kvpair_b64(f, curpos, 0, "key", kg->kg_key); 1000 break; 1001 case KEYGEN_RANDOMKEY: 1002 (void)fprintf(f, "randomkey;\n"); 1003 break; 1004 case KEYGEN_URANDOMKEY: 1005 (void)fprintf(f, "urandomkey;\n"); 1006 break; 1007 #ifdef HAVE_ARGON2 1008 case KEYGEN_ARGON2ID: 1009 (void)fprintf(f, "argon2id {\n"); 1010 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 1011 print_kvpair_int(f, ts, "memory", kg->kg_memory); 1012 print_kvpair_int(f, ts, "parallelism", kg->kg_parallelism); 1013 print_kvpair_int(f, ts, "version", kg->kg_version); 1014 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 1015 print_shared(f, ts, kg); 1016 (void)fprintf(f, "};\n"); 1017 break; 1018 #endif 1019 case KEYGEN_PKCS5_PBKDF2_OLD: 1020 (void)fprintf(f, "pkcs5_pbkdf2 {\n"); 1021 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 1022 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 1023 print_shared(f, ts, kg); 1024 (void)fprintf(f, "};\n"); 1025 break; 1026 case KEYGEN_PKCS5_PBKDF2_SHA1: 1027 (void)fprintf(f, "pkcs5_pbkdf2/sha1 {\n"); 1028 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 1029 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 1030 print_shared(f, ts, kg); 1031 (void)fprintf(f, "};\n"); 1032 break; 1033 default: 1034 warnx("keygen_fput: %d not a valid method", kg->kg_method); 1035 break; 1036 } 1037 return keygen_fput(kg->next, ts, f); 1038 } 1039 1040 int 1041 params_fput(struct params *p, FILE *f) 1042 { 1043 int ts = 0; /* tabstop of 0 spaces */ 1044 1045 print_kvpair_string(f, ts, "algorithm", p->algorithm); 1046 print_kvpair_string(f, ts, "iv-method", p->ivmeth); 1047 print_kvpair_int(f, ts, "keylength", p->keylen); 1048 print_kvpair_int(f, ts, "blocksize", p->bsize); 1049 switch (p->verify_method) { 1050 case VERIFY_NONE: 1051 print_kvpair_cstr(f, ts, "verify_method", "none"); 1052 break; 1053 case VERIFY_DISKLABEL: 1054 print_kvpair_cstr(f, ts, "verify_method", "disklabel"); 1055 break; 1056 case VERIFY_FFS: 1057 print_kvpair_cstr(f, ts, "verify_method", "ffs"); 1058 break; 1059 case VERIFY_REENTER: 1060 print_kvpair_cstr(f, ts, "verify_method", "re-enter"); 1061 break; 1062 case VERIFY_MBR: 1063 print_kvpair_cstr(f, ts, "verify_method", "mbr"); 1064 break; 1065 case VERIFY_GPT: 1066 print_kvpair_cstr(f, ts, "verify_method", "gpt"); 1067 break; 1068 default: 1069 warnx("unsupported verify_method (%d)", p->verify_method); 1070 return -1; 1071 } 1072 return keygen_fput(p->keygen, TAB_COL, f); 1073 } 1074 1075 int 1076 params_cput(struct params *p, const char *fn) 1077 { 1078 FILE *f; 1079 1080 if (fn && *fn) { 1081 if ((f = fopen(fn, "w")) == NULL) { 1082 warn("could not open outfile \"%s\"", fn); 1083 return -1; 1084 } 1085 } else { 1086 f = stdout; 1087 } 1088 return params_fput(p, f); 1089 } 1090 1091 static int 1092 crypt_defaults_lookup(const char *alg) 1093 { 1094 unsigned i; 1095 1096 for (i=0; i < (sizeof(crypto_defaults) / sizeof(crypto_defaults[0])); i++) 1097 if (!strcmp(alg, crypto_defaults[i].alg)) 1098 return i; 1099 1100 return -1; 1101 } 1102