1 /* $NetBSD: params.c,v 1.29 2016/12/11 00:34:39 alnsn 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.29 2016/12/11 00:34:39 alnsn Exp $"); 35 #endif 36 37 #include <sys/types.h> 38 #include <sys/param.h> 39 #include <sys/stat.h> 40 41 #include <err.h> 42 #include <errno.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <util.h> 47 48 #include "params.h" 49 #include "pkcs5_pbkdf2.h" 50 #include "utils.h" 51 #include "cgdconfig.h" 52 #include "extern.h" 53 54 static void params_init(struct params *); 55 56 static void print_kvpair_cstr(FILE *, int, const char *, const char *); 57 static void print_kvpair_string(FILE *, int, const char *, const string_t *); 58 static void print_kvpair_int(FILE *, int, const char *, size_t); 59 static void print_kvpair_b64(FILE *, int, int, const char *, bits_t *); 60 61 static void spaces(FILE *, int); 62 63 /* keygen defaults */ 64 #define DEFAULT_SALTLEN 128 65 #define DEFAULT_ITERATION_TIME 2000000 /* 1 second in microseconds */ 66 67 /* crypto defaults functions */ 68 static struct crypto_defaults { 69 char alg[32]; 70 int keylen; 71 } crypto_defaults[] = { 72 { "aes-cbc", 128 }, 73 { "aes-xts", 256 }, 74 { "3des-cbc", 192 }, 75 { "blowfish-cbc", 128 } 76 }; 77 78 static int crypt_defaults_lookup(const char *); 79 80 struct params * 81 params_new(void) 82 { 83 struct params *p; 84 85 p = emalloc(sizeof(*p)); 86 params_init(p); 87 return p; 88 } 89 90 static void 91 params_init(struct params *p) 92 { 93 94 p->algorithm = NULL; 95 p->ivmeth = NULL; 96 p->key = NULL; 97 p->keylen = (size_t)-1; 98 p->bsize = (size_t)-1; 99 p->verify_method = VERIFY_UNKNOWN; 100 p->dep_keygen = NULL; 101 p->keygen = NULL; 102 } 103 104 void 105 params_free(struct params *p) 106 { 107 108 if (!p) 109 return; 110 string_free(p->algorithm); 111 string_free(p->ivmeth); 112 keygen_free(p->dep_keygen); 113 keygen_free(p->keygen); 114 } 115 116 struct params * 117 params_combine(struct params *p1, struct params *p2) 118 { 119 struct params *p; 120 121 if (p1) 122 p = p1; 123 else 124 p = params_new(); 125 126 if (!p2) 127 return p; 128 129 if (p2->algorithm) 130 string_assign(&p->algorithm, p2->algorithm); 131 if (p2->ivmeth) 132 string_assign(&p->ivmeth, p2->ivmeth); 133 if (p2->keylen != (size_t)-1) 134 p->keylen = p2->keylen; 135 if (p2->bsize != (size_t)-1) 136 p->bsize = p2->bsize; 137 if (p2->verify_method != VERIFY_UNKNOWN) 138 p->verify_method = p2->verify_method; 139 140 p->dep_keygen = keygen_combine(p->dep_keygen, p2->dep_keygen); 141 keygen_addlist(&p->keygen, p2->keygen); 142 143 /* 144 * at this point we should have moved all allocated data 145 * in p2 into p, so we can free it. 146 */ 147 free(p2); 148 return p; 149 } 150 151 int 152 params_filldefaults(struct params *p) 153 { 154 size_t i; 155 156 if (p->verify_method == VERIFY_UNKNOWN) 157 p->verify_method = VERIFY_NONE; 158 if (!p->ivmeth) 159 p->ivmeth = string_fromcharstar("encblkno1"); 160 if (p->keylen == (size_t)-1) { 161 i = crypt_defaults_lookup(string_tocharstar(p->algorithm)); 162 if (i != (size_t)-1) { 163 p->keylen = crypto_defaults[i].keylen; 164 } else { 165 warnx("could not determine key length for unknown " 166 "algorithm \"%s\"", 167 string_tocharstar(p->algorithm)); 168 return -1; 169 } 170 } 171 return 0; 172 } 173 174 /* 175 * params_verify traverses the parameters and all of the keygen methods 176 * looking for inconsistencies. It outputs warnings on non-fatal errors 177 * such as unknown encryption methods, but returns failure on fatal 178 * conditions such as a PKCS5_PBKDF2 keygen without a salt. It is intended 179 * to run before key generation. 180 */ 181 182 int 183 params_verify(const struct params *p) 184 { 185 static const char *encblkno[] = { 186 "encblkno", "encblkno1", "encblkno8" 187 }; 188 static size_t i; 189 const char *meth; 190 191 if (!p->algorithm) { 192 warnx("unspecified algorithm"); 193 return 0; 194 } 195 /* 196 * we only warn for the encryption method so that it is possible 197 * to use an older cgdconfig(8) with a new kernel that supports 198 * additional crypto algorithms. 199 */ 200 if (crypt_defaults_lookup(string_tocharstar(p->algorithm)) == -1) 201 warnx("unknown algorithm \"%s\"(warning)", 202 string_tocharstar(p->algorithm)); 203 /* same rationale with IV methods. */ 204 if (!p->ivmeth) { 205 warnx("unspecified IV method"); 206 return 0; 207 } 208 209 meth = string_tocharstar(p->ivmeth); 210 for (i = 0; i < __arraycount(encblkno); i++) 211 if (strcmp(encblkno[i], meth) == 0) 212 break; 213 214 if (i == __arraycount(encblkno)) 215 warnx("unknown IV method \"%s\" (warning)", meth); 216 217 if (p->keylen == (size_t)-1) { 218 warnx("unspecified key length"); 219 return 0; 220 } 221 222 return keygen_verify(p->keygen); 223 } 224 225 struct params * 226 params_algorithm(string_t *in) 227 { 228 struct params *p = params_new(); 229 230 p->algorithm = in; 231 return p; 232 } 233 234 struct params * 235 params_ivmeth(string_t *in) 236 { 237 struct params *p = params_new(); 238 239 p->ivmeth = in; 240 return p; 241 } 242 243 struct params * 244 params_keylen(size_t in) 245 { 246 struct params *p = params_new(); 247 248 p->keylen = in; 249 return p; 250 } 251 252 struct params * 253 params_bsize(size_t in) 254 { 255 struct params *p = params_new(); 256 257 p->bsize = in; 258 return p; 259 } 260 261 struct params * 262 params_verify_method(string_t *in) 263 { 264 struct params *p = params_new(); 265 const char *vm = string_tocharstar(in); 266 267 if (!strcmp("none", vm)) 268 p->verify_method = VERIFY_NONE; 269 if (!strcmp("disklabel", vm)) 270 p->verify_method = VERIFY_DISKLABEL; 271 if (!strcmp("ffs", vm)) 272 p->verify_method = VERIFY_FFS; 273 if (!strcmp("re-enter", vm)) 274 p->verify_method = VERIFY_REENTER; 275 if (!strcmp("mbr", vm)) 276 p->verify_method = VERIFY_MBR; 277 if (!strcmp("gpt", vm)) 278 p->verify_method = VERIFY_GPT; 279 280 string_free(in); 281 282 if (p->verify_method == VERIFY_UNKNOWN) 283 warnx("params_setverify_method: unrecognized " 284 "verify method \"%s\"", vm); 285 return p; 286 } 287 288 struct params * 289 params_keygen(struct keygen *in) 290 { 291 struct params *p = params_new(); 292 293 p->keygen = in; 294 return p; 295 } 296 297 struct params * 298 params_dep_keygen(struct keygen *in) 299 { 300 struct params *p = params_new(); 301 302 p->dep_keygen = in; 303 return p; 304 } 305 306 struct keygen * 307 keygen_new(void) 308 { 309 struct keygen *kg; 310 311 kg = emalloc(sizeof(*kg)); 312 kg->kg_method = KEYGEN_UNKNOWN; 313 kg->kg_iterations = (size_t)-1; 314 kg->kg_salt = NULL; 315 kg->kg_key = NULL; 316 kg->kg_cmd = NULL; 317 kg->next = NULL; 318 return kg; 319 } 320 321 void 322 keygen_free(struct keygen *kg) 323 { 324 325 if (!kg) 326 return; 327 bits_free(kg->kg_salt); 328 bits_free(kg->kg_key); 329 string_free(kg->kg_cmd); 330 keygen_free(kg->next); 331 free(kg); 332 } 333 334 /* 335 * keygen_verify traverses the keygen structures and ensures 336 * that the appropriate information is available. 337 */ 338 339 int 340 keygen_verify(const struct keygen *kg) 341 { 342 343 if (!kg) 344 return 1; 345 switch (kg->kg_method) { 346 case KEYGEN_PKCS5_PBKDF2_OLD: 347 if (kg->kg_iterations == (size_t)-1) { 348 warnx("keygen pkcs5_pbkdf2 must provide `iterations'"); 349 return 0; 350 } 351 if (kg->kg_key) 352 warnx("keygen pkcs5_pbkdf2 does not need a `key'"); 353 if (!kg->kg_salt) { 354 warnx("keygen pkcs5_pbkdf2 must provide a salt"); 355 return 0; 356 } 357 if (kg->kg_cmd) 358 warnx("keygen pkcs5_pbkdf2 does not need a `cmd'"); 359 break; 360 case KEYGEN_PKCS5_PBKDF2_SHA1: 361 if (kg->kg_iterations == (size_t)-1) { 362 warnx("keygen pkcs5_pbkdf2/sha1 must provide `iterations'"); 363 return 0; 364 } 365 if (kg->kg_key) 366 warnx("keygen pkcs5_pbkdf2/sha1 does not need a `key'"); 367 if (!kg->kg_salt) { 368 warnx("keygen pkcs5_pbkdf2/sha1 must provide a salt"); 369 return 0; 370 } 371 if (kg->kg_cmd) 372 warnx("keygen pkcs5_pbkdf2/sha1 does not need a `cmd'"); 373 break; 374 case KEYGEN_STOREDKEY: 375 if (kg->kg_iterations != (size_t)-1) 376 warnx("keygen storedkey does not need `iterations'"); 377 if (!kg->kg_key) { 378 warnx("keygen storedkey must provide a key"); 379 return 0; 380 } 381 if (kg->kg_salt) 382 warnx("keygen storedkey does not need `salt'"); 383 if (kg->kg_cmd) 384 warnx("keygen storedkey does not need `cmd'"); 385 break; 386 case KEYGEN_RANDOMKEY: 387 case KEYGEN_URANDOMKEY: 388 if (kg->kg_iterations != (size_t)-1) 389 warnx("keygen [u]randomkey does not need `iterations'"); 390 if (kg->kg_key) 391 warnx("keygen [u]randomkey does not need `key'"); 392 if (kg->kg_salt) 393 warnx("keygen [u]randomkey does not need `salt'"); 394 if (kg->kg_cmd) 395 warnx("keygen [u]randomkey does not need `cmd'"); 396 break; 397 case KEYGEN_SHELL_CMD: 398 if (kg->kg_iterations != (size_t)-1) 399 warnx("keygen shell_cmd does not need `iterations'"); 400 if (kg->kg_key) 401 warnx("keygen shell_cmd does not need `key'"); 402 if (kg->kg_salt) 403 warnx("keygen shell_cmd does not need `salt'"); 404 if (!kg->kg_cmd) { 405 warnx("keygen shell_cmd must provide a `cmd'"); 406 return 0; 407 } 408 break; 409 } 410 return keygen_verify(kg->next); 411 } 412 413 struct keygen * 414 keygen_generate(int method) 415 { 416 struct keygen *kg; 417 418 kg = keygen_new(); 419 if (!kg) 420 return NULL; 421 422 kg->kg_method = method; 423 return kg; 424 } 425 426 /* 427 * keygen_filldefaults walks the keygen list and fills in 428 * default values. The defaults may be either calibrated 429 * or randomly generated so this function is designed to be 430 * called when generating a new parameters file, not when 431 * reading a parameters file. 432 */ 433 434 int 435 keygen_filldefaults(struct keygen *kg, size_t keylen) 436 { 437 438 if (!kg) 439 return 0; 440 switch (kg->kg_method) { 441 case KEYGEN_RANDOMKEY: 442 case KEYGEN_URANDOMKEY: 443 case KEYGEN_SHELL_CMD: 444 break; 445 case KEYGEN_PKCS5_PBKDF2_OLD: 446 case KEYGEN_PKCS5_PBKDF2_SHA1: 447 kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1); 448 kg->kg_iterations = pkcs5_pbkdf2_calibrate(BITS2BYTES(keylen), 449 DEFAULT_ITERATION_TIME); 450 if (kg->kg_iterations < 1) { 451 warnx("could not calibrate pkcs5_pbkdf2"); 452 return -1; 453 } 454 break; 455 case KEYGEN_STOREDKEY: 456 /* Generate a random stored key */ 457 kg->kg_key = bits_getrandombits(keylen, 1); 458 if (!kg->kg_key) { 459 warnx("can't generate random bits for storedkey"); 460 return -1; 461 } 462 break; 463 default: 464 return -1; 465 } 466 467 return keygen_filldefaults(kg->next, keylen); 468 } 469 470 struct keygen * 471 keygen_combine(struct keygen *kg1, struct keygen *kg2) 472 { 473 if (!kg1 && !kg2) 474 return NULL; 475 476 if (!kg1) 477 kg1 = keygen_new(); 478 479 if (!kg2) 480 return kg1; 481 482 if (kg2->kg_method != KEYGEN_UNKNOWN) 483 kg1->kg_method = kg2->kg_method; 484 485 if (kg2->kg_iterations != (size_t)-1 && kg2->kg_iterations > 0) 486 kg1->kg_iterations = kg2->kg_iterations; 487 488 if (kg2->kg_salt) 489 bits_assign(&kg1->kg_salt, kg2->kg_salt); 490 491 if (kg2->kg_key) 492 bits_assign(&kg1->kg_key, kg2->kg_key); 493 494 if (kg2->kg_cmd) 495 string_assign(&kg1->kg_cmd, kg2->kg_cmd); 496 497 return kg1; 498 } 499 500 struct keygen * 501 keygen_method(string_t *in) 502 { 503 struct keygen *kg = keygen_new(); 504 const char *kgm = string_tocharstar(in); 505 506 if (!strcmp("pkcs5_pbkdf2", kgm)) 507 kg->kg_method = KEYGEN_PKCS5_PBKDF2_OLD; 508 if (!strcmp("pkcs5_pbkdf2/sha1", kgm)) 509 kg->kg_method = KEYGEN_PKCS5_PBKDF2_SHA1; 510 if (!strcmp("randomkey", kgm)) 511 kg->kg_method = KEYGEN_RANDOMKEY; 512 if (!strcmp("storedkey", kgm)) 513 kg->kg_method = KEYGEN_STOREDKEY; 514 if (!strcmp("urandomkey", kgm)) 515 kg->kg_method = KEYGEN_URANDOMKEY; 516 if (!strcmp("shell_cmd", kgm)) 517 kg->kg_method = KEYGEN_SHELL_CMD; 518 519 string_free(in); 520 521 if (kg->kg_method == KEYGEN_UNKNOWN) 522 warnx("unrecognized key generation method \"%s\"", kgm); 523 return kg; 524 } 525 526 struct keygen * 527 keygen_set_method(struct keygen *kg, string_t *in) 528 { 529 530 return keygen_combine(kg, keygen_method(in)); 531 } 532 533 struct keygen * 534 keygen_salt(bits_t *in) 535 { 536 struct keygen *kg = keygen_new(); 537 538 kg->kg_salt = in; 539 return kg; 540 } 541 542 struct keygen * 543 keygen_iterations(size_t in) 544 { 545 struct keygen *kg = keygen_new(); 546 547 kg->kg_iterations = in; 548 return kg; 549 } 550 551 void 552 keygen_addlist(struct keygen **l, struct keygen *e) 553 { 554 struct keygen *t; 555 556 if (*l) { 557 t = *l; 558 for (;t->next; t = t->next) 559 ; 560 t->next = e; 561 } else { 562 *l = e; 563 } 564 } 565 566 struct keygen * 567 keygen_key(bits_t *in) 568 { 569 struct keygen *kg = keygen_new(); 570 571 kg->kg_key = in; 572 return kg; 573 } 574 575 struct keygen * 576 keygen_cmd(string_t *in) 577 { 578 struct keygen *kg = keygen_new(); 579 580 kg->kg_cmd = in; 581 return kg; 582 } 583 584 struct params * 585 params_fget(FILE *f) 586 { 587 struct params *p; 588 589 p = cgdparsefile(f); 590 591 if (!p) 592 return NULL; 593 594 /* 595 * We deal with the deprecated keygen structure by prepending it 596 * to the list of keygens, so that the rest of the code does not 597 * have to deal with this backwards compat issue. The deprecated 598 * ``xor_key'' field may be stored in p->dep_keygen->kg_key. If 599 * it exists, we construct a storedkey keygen struct as well. Also, 600 * default the iteration count to 128 as the old code did. 601 */ 602 603 if (p->dep_keygen) { 604 if (p->dep_keygen->kg_iterations == (size_t)-1) 605 p->dep_keygen->kg_iterations = 128; 606 p->dep_keygen->next = p->keygen; 607 if (p->dep_keygen->kg_key) { 608 p->keygen = keygen_generate(KEYGEN_STOREDKEY); 609 p->keygen->kg_key = p->dep_keygen->kg_key; 610 p->dep_keygen->kg_key = NULL; 611 p->keygen->next = p->dep_keygen; 612 } else { 613 p->keygen = p->dep_keygen; 614 } 615 p->dep_keygen = NULL; 616 } 617 return p; 618 } 619 620 struct params * 621 params_cget(const char *fn) 622 { 623 struct params *p; 624 FILE *f; 625 char filename[MAXPATHLEN]; 626 627 if ((f = fopen(fn, "r")) == NULL && fn[0] != '/') { 628 snprintf(filename, sizeof(filename), "%s/%s", 629 CGDCONFIG_DIR, fn); 630 fn = filename; 631 f = fopen(fn, "r"); 632 } 633 634 if (f == NULL) { 635 warn("failed to open params file \"%s\"", fn); 636 return NULL; 637 } 638 p = params_fget(f); 639 (void)fclose(f); 640 return p; 641 } 642 643 #define WRAP_COL 50 644 #define TAB_COL 8 645 646 static void 647 spaces(FILE *f, int len) 648 { 649 650 while (len-- > 0) 651 (void)fputc(' ', f); 652 } 653 654 static void 655 print_kvpair_cstr(FILE *f, int ts, const char *key, const char *val) 656 { 657 658 spaces(f, ts); 659 (void)fprintf(f, "%s %s;\n", key, val); 660 } 661 662 static void 663 print_kvpair_string(FILE *f, int ts, const char *key, const string_t *val) 664 { 665 666 print_kvpair_cstr(f, ts, key, string_tocharstar(val)); 667 } 668 669 static void 670 print_kvpair_int(FILE *f, int ts, const char *key, size_t val) 671 { 672 char *tmp; 673 674 if (!key || val == (size_t)-1) 675 return; 676 677 if (asprintf(&tmp, "%zu", val) == -1) 678 err(1, NULL); 679 print_kvpair_cstr(f, ts, key, tmp); 680 free(tmp); 681 } 682 683 /* 684 * prints out a base64 encoded k-v pair to f. It encodes the length 685 * of the bitstream as a 32bit unsigned integer in network byte order 686 * up front. 687 */ 688 689 static void 690 print_kvpair_b64(FILE *f, int curpos, int ts, const char *key, bits_t *val) 691 { 692 string_t *str; 693 int i; 694 int len; 695 int pos; 696 const char *out; 697 698 if (!key || !val) 699 return; 700 701 str = bits_encode(val); 702 out = string_tocharstar(str); 703 len = strlen(out); 704 705 spaces(f, ts); 706 (void)fprintf(f, "%s ", key); 707 curpos += ts + strlen(key) + 1; 708 ts = curpos; 709 710 for (i=0, pos=curpos; i < len; i++, pos++) { 711 if (pos > WRAP_COL) { 712 (void)fprintf(f, " \\\n"); 713 spaces(f, ts); 714 pos = ts; 715 } 716 (void)fputc(out[i], f); 717 } 718 (void)fprintf(f, ";\n"); 719 string_free(str); 720 } 721 722 int 723 keygen_fput(struct keygen *kg, int ts, FILE *f) 724 { 725 int curpos = 0; 726 727 if (!kg) 728 return 0; 729 (void)fprintf(f, "keygen "); 730 curpos += strlen("keygen "); 731 switch (kg->kg_method) { 732 case KEYGEN_STOREDKEY: 733 (void)fprintf(f, "storedkey "); 734 curpos += strlen("storedkey "); 735 print_kvpair_b64(f, curpos, 0, "key", kg->kg_key); 736 break; 737 case KEYGEN_RANDOMKEY: 738 (void)fprintf(f, "randomkey;\n"); 739 break; 740 case KEYGEN_URANDOMKEY: 741 (void)fprintf(f, "urandomkey;\n"); 742 break; 743 case KEYGEN_PKCS5_PBKDF2_OLD: 744 (void)fprintf(f, "pkcs5_pbkdf2 {\n"); 745 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 746 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 747 (void)fprintf(f, "};\n"); 748 break; 749 case KEYGEN_PKCS5_PBKDF2_SHA1: 750 (void)fprintf(f, "pkcs5_pbkdf2/sha1 {\n"); 751 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 752 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 753 (void)fprintf(f, "};\n"); 754 break; 755 default: 756 warnx("keygen_fput: %d not a valid method", kg->kg_method); 757 break; 758 } 759 return keygen_fput(kg->next, ts, f); 760 } 761 762 int 763 params_fput(struct params *p, FILE *f) 764 { 765 int ts = 0; /* tabstop of 0 spaces */ 766 767 print_kvpair_string(f, ts, "algorithm", p->algorithm); 768 print_kvpair_string(f, ts, "iv-method", p->ivmeth); 769 print_kvpair_int(f, ts, "keylength", p->keylen); 770 print_kvpair_int(f, ts, "blocksize", p->bsize); 771 switch (p->verify_method) { 772 case VERIFY_NONE: 773 print_kvpair_cstr(f, ts, "verify_method", "none"); 774 break; 775 case VERIFY_DISKLABEL: 776 print_kvpair_cstr(f, ts, "verify_method", "disklabel"); 777 break; 778 case VERIFY_FFS: 779 print_kvpair_cstr(f, ts, "verify_method", "ffs"); 780 break; 781 case VERIFY_REENTER: 782 print_kvpair_cstr(f, ts, "verify_method", "re-enter"); 783 break; 784 case VERIFY_MBR: 785 print_kvpair_cstr(f, ts, "verify_method", "mbr"); 786 break; 787 case VERIFY_GPT: 788 print_kvpair_cstr(f, ts, "verify_method", "gpt"); 789 break; 790 default: 791 warnx("unsupported verify_method (%d)", p->verify_method); 792 return -1; 793 } 794 return keygen_fput(p->keygen, TAB_COL, f); 795 } 796 797 int 798 params_cput(struct params *p, const char *fn) 799 { 800 FILE *f; 801 802 if (fn && *fn) { 803 if ((f = fopen(fn, "w")) == NULL) { 804 warn("could not open outfile \"%s\"", fn); 805 return -1; 806 } 807 } else { 808 f = stdout; 809 } 810 return params_fput(p, f); 811 } 812 813 static int 814 crypt_defaults_lookup(const char *alg) 815 { 816 unsigned i; 817 818 for (i=0; i < (sizeof(crypto_defaults) / sizeof(crypto_defaults[0])); i++) 819 if (!strcmp(alg, crypto_defaults[i].alg)) 820 return i; 821 822 return -1; 823 } 824