1 /*- 2 * Copyright (c) 2017-2020, Juniper Networks, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 /* 26 * Routines to verify files loaded. 27 */ 28 29 #include <sys/param.h> 30 #include <string.h> 31 #include <sys/queue.h> 32 #include <sys/kenv.h> 33 34 #include "libsecureboot.h" 35 #include <verify_file.h> 36 #include <manifests.h> 37 38 #ifdef UNIT_TEST 39 # include <err.h> 40 # define panic warn 41 /* 42 * define MANIFEST_SKIP to Skip - in tests/tvo.c so that 43 * tvo can control the value we use in find_manifest() 44 */ 45 extern char *Destdir; 46 extern size_t DestdirLen; 47 extern char *Skip; 48 # undef MANIFEST_SKIP 49 # define MANIFEST_SKIP Skip 50 # undef VE_DEBUG_LEVEL 51 #endif 52 53 /* 54 * We sometimes need to know if input is verified or not. 55 * The extra slot is for tracking most recently opened. 56 */ 57 #ifndef SOPEN_MAX 58 #define SOPEN_MAX 64 59 #endif 60 static int ve_status[SOPEN_MAX+1]; 61 static int ve_status_state; 62 struct verify_status; 63 static struct verify_status *verified_files = NULL; 64 static int loaded_manifests = 0; /* have we loaded anything? */ 65 66 enum { 67 VE_VERBOSE_SILENT, /* only report errors */ 68 VE_VERBOSE_UNVERIFIED, /* all unverified files */ 69 VE_VERBOSE_MUST, /* report VE_MUST */ 70 VE_VERBOSE_ALL, /* report all */ 71 VE_VERBOSE_DEBUG, /* extra noise */ 72 }; 73 74 #ifndef VE_VERBOSE_DEFAULT 75 # define VE_VERBOSE_DEFAULT VE_VERBOSE_MUST 76 #endif 77 static int Verbose = VE_VERBOSE_DEFAULT; 78 79 #define VE_STATUS_NONE 1 80 #define VE_STATUS_VALID 2 81 82 /** 83 * @brief set ve status for fd 84 */ 85 void 86 ve_status_set(int fd, int ves) 87 { 88 if (fd >= 0 && fd < SOPEN_MAX) { 89 ve_status[fd] = ves; 90 ve_status_state = VE_STATUS_VALID; 91 } 92 ve_status[SOPEN_MAX] = ves; 93 } 94 95 /** 96 * @brief get ve status of fd 97 * 98 * What we return depends on ve_status_state. 99 * 100 * @return 101 * @li ve_status[fd] if ve_status_state is valid 102 * @li ve_status[SOPEN_MAX] if ve_status_state is none 103 * @li VE_NOT_CHECKED if ve_status_state uninitialized 104 */ 105 int 106 ve_status_get(int fd) 107 { 108 if (!ve_status_state) { 109 return (VE_NOT_CHECKED); 110 } 111 if (ve_status_state == VE_STATUS_VALID && 112 fd >= 0 && fd < SOPEN_MAX) 113 return (ve_status[fd]); 114 return (ve_status[SOPEN_MAX]); /* most recent */ 115 } 116 117 /** 118 * @brief track verify status 119 * 120 * occasionally loader will make multiple calls 121 * for the same file, we need only check it once. 122 */ 123 struct verify_status { 124 dev_t vs_dev; 125 ino_t vs_ino; 126 int vs_status; 127 struct verify_status *vs_next; 128 }; 129 130 int 131 is_verified(struct stat *stp) 132 { 133 struct verify_status *vsp; 134 int rc = VE_NOT_CHECKED; 135 136 if (stp->st_ino > 0) { 137 for (vsp = verified_files; vsp != NULL; vsp = vsp->vs_next) { 138 if (stp->st_dev == vsp->vs_dev && 139 stp->st_ino == vsp->vs_ino) { 140 rc = vsp->vs_status; 141 break; 142 } 143 } 144 } 145 DEBUG_PRINTF(4, ("%s: dev=%lld,ino=%llu,status=%d\n", 146 __func__, (long long)stp->st_dev, 147 (unsigned long long)stp->st_ino, rc)); 148 return (rc); 149 } 150 151 /* most recent first, since most likely to see repeated calls. */ 152 void 153 add_verify_status(struct stat *stp, int status) 154 { 155 struct verify_status *vsp; 156 157 vsp = malloc(sizeof(struct verify_status)); 158 if (vsp) { 159 vsp->vs_next = verified_files; 160 vsp->vs_dev = stp->st_dev; 161 vsp->vs_ino = stp->st_ino; 162 vsp->vs_status = status; 163 verified_files = vsp; 164 } 165 DEBUG_PRINTF(4, ("%s: dev=%lld,ino=%llu,status=%d\n", 166 __func__, (long long)stp->st_dev, 167 (unsigned long long)stp->st_ino, status)); 168 } 169 170 171 /** 172 * @brief 173 * load specified manifest if verified 174 */ 175 int 176 load_manifest(const char *name, const char *prefix, 177 const char *skip, struct stat *stp) 178 { 179 struct stat st; 180 size_t n; 181 int rc; 182 char *content; 183 184 rc = VE_FINGERPRINT_NONE; 185 n = strlen(name); 186 if (n > 4) { 187 if (!stp) { 188 stp = &st; 189 if (stat(name, &st) < 0 || !S_ISREG(st.st_mode)) 190 return (rc); 191 } 192 rc = is_verified(stp); 193 if (rc != VE_NOT_CHECKED) { 194 return (rc); 195 } 196 /* loader has no sense of time */ 197 ve_utc_set(stp->st_mtime); 198 content = (char *)verify_signed(name, VerifyFlags); 199 if (content) { 200 #ifdef UNIT_TEST 201 if (DestdirLen > 0 && 202 strncmp(name, Destdir, DestdirLen) == 0) { 203 name += DestdirLen; 204 if (prefix && 205 strncmp(prefix, Destdir, DestdirLen) == 0) 206 prefix += DestdirLen; 207 } 208 #endif 209 fingerprint_info_add(name, prefix, skip, content, stp); 210 add_verify_status(stp, VE_VERIFIED); 211 loaded_manifests = 1; /* we are verifying! */ 212 DEBUG_PRINTF(3, ("loaded: %s %s %s\n", 213 name, prefix, skip)); 214 rc = VE_VERIFIED; 215 } else { 216 rc = VE_FINGERPRINT_WRONG; 217 add_verify_status(stp, rc); /* remember */ 218 } 219 } 220 return (rc); 221 } 222 223 static int 224 find_manifest(const char *name) 225 { 226 struct stat st; 227 char buf[MAXPATHLEN]; 228 char *prefix; 229 char *skip; 230 const char **tp; 231 int rc; 232 233 strncpy(buf, name, MAXPATHLEN - 1); 234 if (!(prefix = strrchr(buf, '/'))) 235 return (-1); 236 *prefix = '\0'; 237 prefix = strdup(buf); 238 rc = VE_FINGERPRINT_NONE; 239 for (tp = manifest_names; *tp; tp++) { 240 snprintf(buf, sizeof(buf), "%s/%s", prefix, *tp); 241 if (*tp[0] == '.') { 242 /* skip /../ */ 243 if (prefix[0] == '\0' || prefix[1] == '\0') 244 continue; 245 } 246 DEBUG_PRINTF(5, ("looking for %s\n", buf)); 247 if (stat(buf, &st) == 0 && st.st_size > 0) { 248 #ifdef MANIFEST_SKIP_ALWAYS /* very unlikely */ 249 skip = MANIFEST_SKIP_ALWAYS; 250 #else 251 #ifdef MANIFEST_SKIP /* rare */ 252 if (*tp[0] == '.') { 253 skip = MANIFEST_SKIP; 254 } else 255 #endif 256 skip = NULL; 257 #endif 258 rc = load_manifest(buf, skip ? prefix : NULL, 259 skip, &st); 260 break; 261 } 262 } 263 free(prefix); 264 return (rc); 265 } 266 267 268 #ifdef LOADER_VERIEXEC_TESTING 269 # define ACCEPT_NO_FP_DEFAULT VE_MUST + 1 270 #else 271 # define ACCEPT_NO_FP_DEFAULT VE_MUST 272 #endif 273 274 int 275 severity_guess(const char *filename) 276 { 277 const char *cp; 278 279 /* 280 * Some files like *.conf and *.hints may be unsigned, 281 * a *.tgz is expected to have its own signed manifest. 282 * We allow *.conf to get VE_WANT, but files we expect 283 * to always be unverified get VE_TRY and we will not 284 * report them. 285 */ 286 if ((cp = strrchr(filename, '.'))) { 287 if (strcmp(cp, ".cookie") == 0 || 288 strcmp(cp, ".dof") == 0 || 289 strcmp(cp, ".hints") == 0 || 290 strcmp(cp, ".order") == 0 || 291 strcmp(cp, ".tgz") == 0) 292 return (VE_TRY); 293 if (strcmp(cp, ".4th") == 0 || 294 strcmp(cp, ".lua") == 0 || 295 strcmp(cp, ".rc") == 0) 296 return (VE_MUST); 297 } 298 return (VE_WANT); 299 } 300 301 static int Verifying = -1; /* 0 if not verifying */ 302 303 static void 304 verify_tweak(int fd, off_t off, struct stat *stp, 305 char *tweak, int *accept_no_fp) 306 { 307 if (strcmp(tweak, "off") == 0) { 308 Verifying = 0; 309 } else if (strcmp(tweak, "strict") == 0) { 310 /* anything caller wants verified must be */ 311 *accept_no_fp = VE_WANT; 312 Verbose = VE_VERBOSE_ALL; 313 /* treat self test failure as fatal */ 314 if (!ve_self_tests()) { 315 panic("verify self tests failed"); 316 } 317 } else if (strcmp(tweak, "modules") == 0) { 318 /* modules/kernel must be verified */ 319 *accept_no_fp = VE_MUST; 320 } else if (strcmp(tweak, "try") == 0) { 321 /* best effort: always accept no fp */ 322 *accept_no_fp = VE_MUST + 1; 323 } else if (strcmp(tweak, "verbose") == 0) { 324 Verbose = VE_VERBOSE_ALL; 325 } else if (strcmp(tweak, "quiet") == 0) { 326 Verbose = VE_VERBOSE_UNVERIFIED; 327 VerifyFlags = 0; 328 } else if (strcmp(tweak, "silent") == 0) { 329 Verbose = VE_VERBOSE_SILENT; 330 VerifyFlags = 0; 331 } else if (strncmp(tweak, "trust", 5) == 0) { 332 /* content is trust anchor to add or revoke */ 333 unsigned char *ucp; 334 size_t num; 335 336 if (off > 0) 337 lseek(fd, 0, SEEK_SET); 338 ucp = read_fd(fd, stp->st_size); 339 if (ucp == NULL) 340 return; 341 if (strstr(tweak, "revoke")) { 342 num = ve_trust_anchors_revoke(ucp, stp->st_size); 343 DEBUG_PRINTF(3, ("revoked %d trust anchors\n", 344 (int) num)); 345 } else { 346 num = ve_trust_anchors_add_buf(ucp, stp->st_size); 347 DEBUG_PRINTF(3, ("added %d trust anchors\n", 348 (int) num)); 349 } 350 } 351 } 352 353 #ifndef VE_DEBUG_LEVEL 354 # define VE_DEBUG_LEVEL 0 355 #endif 356 357 static int 358 getenv_int(const char *var, int def) 359 { 360 const char *cp; 361 char *ep; 362 long val; 363 364 val = def; 365 cp = getenv(var); 366 if (cp && *cp) { 367 val = strtol(cp, &ep, 0); 368 if ((ep && *ep) || val != (int)val) { 369 val = def; 370 } 371 } 372 return (int)val; 373 } 374 375 376 /** 377 * @brief report verification status 378 * 379 * @param[in] path 380 * path we attempted to verify 381 * 382 * @param[in] severity 383 * indicator of how to handle case of missing fingerprint 384 * 385 * @param[in] status 386 * result of verification 387 * 0 not a file to be verified, > 0 success, < 0 error 388 * 389 * @param[in] stp 390 * pointer to struct stat, used in extra info to be output 391 * 392 * The output is dictated by combinations of the above and the setting 393 * of Verbose: 394 * 395 * VE_VERBOSE_SILENT 396 * report only failure to verify if severity is VE_WANT or higher. 397 * 398 * VE_VERBOSE_UNVERIFIED 399 * report any unverified file. 400 * 401 * VE_VERBOSE_MUST 402 * report verified only if severity is VE_MUST or higher. 403 * 404 * VE_VERBOSE_ALL 405 * report all verified files. 406 * 407 * VE_VERBOSE_DEBUG 408 * if stp is not NULL report dev,inode for path 409 */ 410 void 411 verify_report(const char *path, int severity, int status, struct stat *stp) 412 { 413 if (status < 0 || status == VE_FINGERPRINT_IGNORE) { 414 if (Verbose < VE_VERBOSE_ALL && severity < VE_WANT) 415 return; 416 if (Verbose >= VE_VERBOSE_UNVERIFIED || severity > VE_TRY || 417 status <= VE_FINGERPRINT_WRONG) { 418 if (Verbose == VE_VERBOSE_DEBUG && stp != NULL) 419 printf("Unverified %s %llu,%llu\n", 420 ve_error_get(), 421 (long long)stp->st_dev, 422 (long long)stp->st_ino); 423 else 424 printf("Unverified %s\n", ve_error_get()); 425 } 426 } else if (status > 0 && Verbose >= VE_VERBOSE_MUST) { 427 if (severity >= VE_MUST || Verbose >= VE_VERBOSE_ALL) { 428 if (Verbose == VE_VERBOSE_DEBUG && stp != NULL) 429 printf("Unverified %s %llu,%llu\n", 430 path, 431 (long long)stp->st_dev, 432 (long long)stp->st_ino); 433 else 434 printf("Verified %s\n", path); 435 } 436 } 437 } 438 439 440 /** 441 * @brief prepare to verify an open file 442 * 443 * @param[in] fd 444 * open descriptor 445 * 446 * @param[in] filename 447 * path we opened and will use to lookup fingerprint 448 * 449 * @param[in] stp 450 * stat pointer so we can check file type 451 */ 452 int 453 verify_prep(int fd, const char *filename, off_t off, struct stat *stp, 454 const char *caller) 455 { 456 int rc; 457 458 if (Verifying < 0) { 459 Verifying = ve_trust_init(); 460 /* initialize ve_status with default result */ 461 rc = Verifying ? VE_NOT_CHECKED : VE_NOT_VERIFYING; 462 ve_status_set(0, rc); 463 ve_status_state = VE_STATUS_NONE; 464 if (Verifying) { 465 ve_self_tests(); 466 ve_anchor_verbose_set(1); 467 } 468 } 469 if (!Verifying || fd < 0) 470 return (0); 471 if (stp) { 472 if (fstat(fd, stp) < 0 || !S_ISREG(stp->st_mode)) 473 return (0); 474 } 475 DEBUG_PRINTF(2, 476 ("verify_prep: caller=%s,fd=%d,name='%s',off=%lld,dev=%lld,ino=%llu\n", 477 caller, fd, filename, (long long)off, (long long)stp->st_dev, 478 (unsigned long long)stp->st_ino)); 479 rc = is_verified(stp); 480 if (rc == VE_NOT_CHECKED) { 481 rc = find_manifest(filename); 482 if (rc == VE_VERIFIED) 483 rc = VE_NOT_CHECKED; 484 } else { 485 ve_status_set(fd, rc); 486 } 487 return (rc); 488 } 489 490 /** 491 * @brief verify an open file 492 * 493 * @param[in] fd 494 * open descriptor 495 * 496 * @param[in] filename 497 * path we opened and will use to lookup fingerprint 498 * 499 * @param[in] off 500 * current offset in fd, must be restored on return 501 * 502 * @param[in] severity 503 * indicator of how to handle case of missing fingerprint 504 * 505 * We look for a signed manifest relative to the filename 506 * just opened and verify/load it if needed. 507 * 508 * We then use verify_fd() in libve to actually verify that hash for 509 * open file. If it returns < 0 we look at the severity arg to decide 510 * what to do about it. 511 * 512 * If verify_fd() returns VE_FINGERPRINT_NONE we accept it if severity 513 * is < accept_no_fp. 514 * 515 * @return >= 0 on success < 0 on failure 516 */ 517 int 518 verify_file(int fd, const char *filename, off_t off, int severity, 519 const char *caller) 520 { 521 static int check_verbose = 1; 522 static int accept_no_fp = ACCEPT_NO_FP_DEFAULT; 523 struct stat st; 524 char *cp; 525 int rc; 526 527 if (check_verbose) { 528 check_verbose = 0; 529 Verbose = getenv_int("VE_VERBOSE", VE_VERBOSE_DEFAULT); 530 VerifyFlags = getenv_int("VE_VERIFY_FLAGS", 531 Verbose ? VEF_VERBOSE : 0); 532 #ifndef UNIT_TEST 533 ve_debug_set(getenv_int("VE_DEBUG_LEVEL", VE_DEBUG_LEVEL)); 534 #endif 535 } 536 537 rc = verify_prep(fd, filename, off, &st, caller); 538 539 if (!rc) 540 return (0); 541 542 if (rc != VE_FINGERPRINT_WRONG && loaded_manifests) { 543 if (rc != VE_NOT_CHECKED && rc != VE_FINGERPRINT_NONE) 544 return (rc); 545 546 if (severity <= VE_GUESS) 547 severity = severity_guess(filename); 548 #ifdef VE_PCR_SUPPORT 549 /* 550 * Only update pcr with things that must verify 551 * these tend to be processed in a more deterministic 552 * order, which makes our pseudo pcr more useful. 553 */ 554 ve_pcr_updating_set((severity == VE_MUST)); 555 #endif 556 #ifdef UNIT_TEST 557 if (DestdirLen > 0 && 558 strncmp(filename, Destdir, DestdirLen) == 0) { 559 filename += DestdirLen; 560 } 561 #endif 562 rc = verify_fd(fd, filename, off, &st); 563 verify_report(filename, severity, rc, &st); 564 if (rc >= 0) { 565 if (severity < VE_MUST) { /* not a kernel or module */ 566 if ((cp = strrchr(filename, '/'))) { 567 cp++; 568 if (strncmp(cp, "loader.ve.", 10) == 0) { 569 cp += 10; 570 verify_tweak(fd, off, &st, cp, 571 &accept_no_fp); 572 } 573 } 574 } 575 add_verify_status(&st, rc); 576 ve_status_set(fd, rc); 577 return (rc); 578 } 579 if (rc == VE_FINGERPRINT_UNKNOWN && severity < VE_MUST) 580 rc = VE_UNVERIFIED_OK; 581 else if (rc == VE_FINGERPRINT_NONE && severity < accept_no_fp) 582 rc = VE_UNVERIFIED_OK; 583 584 add_verify_status(&st, rc); 585 586 /* recheck debug/verbose level next time we are called */ 587 if (rc == VE_UNVERIFIED_OK) { 588 check_verbose = 1; 589 } 590 } 591 #ifdef LOADER_VERIEXEC_TESTING 592 else if (rc != VE_FINGERPRINT_WRONG) { 593 /* 594 * We have not loaded any manifest and 595 * not because of verication failure. 596 * Most likely reason is we have none. 597 * Allow boot to proceed if we are just testing. 598 */ 599 return (VE_UNVERIFIED_OK); 600 } 601 #endif 602 if (rc == VE_FINGERPRINT_WRONG && severity > accept_no_fp) 603 panic("cannot continue"); 604 ve_status_set(fd, rc); 605 return (rc); 606 } 607 608 /** 609 * @brief get hex string for pcr value and export 610 * 611 * In case we are doing measured boot, provide 612 * value of the "pcr" data we have accumulated. 613 */ 614 void 615 verify_pcr_export(void) 616 { 617 #ifdef VE_PCR_SUPPORT 618 char hexbuf[br_sha256_SIZE * 2 + 2]; 619 unsigned char hbuf[br_sha256_SIZE]; 620 char *hinfo; 621 char *hex; 622 ssize_t hlen; 623 624 hlen = ve_pcr_get(hbuf, sizeof(hbuf)); 625 if (hlen > 0) { 626 hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen); 627 if (hex) { 628 hex[hlen*2] = '\0'; /* clobber newline */ 629 setenv("loader.ve.pcr", hex, 1); 630 DEBUG_PRINTF(1, 631 ("%s: setenv(loader.ve.pcr, %s\n", __func__, 632 hex)); 633 hinfo = ve_pcr_hashed_get(1); 634 if (hinfo) { 635 setenv("loader.ve.hashed", hinfo, 1); 636 DEBUG_PRINTF(1, 637 ("%s: setenv(loader.ve.hashed, %s\n", 638 __func__, hinfo)); 639 if ((hlen = strlen(hinfo)) > KENV_MVALLEN) { 640 /* 641 * bump kenv_mvallen 642 * roundup to multiple of KENV_MVALLEN 643 */ 644 char mvallen[16]; 645 646 hlen += KENV_MVALLEN - 647 (hlen % KENV_MVALLEN); 648 if (snprintf(mvallen, sizeof(mvallen), 649 "%d", (int) hlen) < (int)sizeof(mvallen)) 650 setenv("kenv_mvallen", mvallen, 1); 651 } 652 free(hinfo); 653 } 654 } 655 } 656 #endif 657 } 658 659 /* 660 * For tftp and http we need to hash pathname 661 * to be able to fake stat(2) data. 662 */ 663 int 664 hash_string(char *s, size_t n, char *buf, size_t bufsz) 665 { 666 br_hash_compat_context mctx; 667 const br_hash_class *md; 668 669 switch (bufsz) { 670 case br_sha1_SIZE: 671 md = &br_sha1_vtable; 672 break; 673 case br_sha256_SIZE: 674 md = &br_sha256_vtable; 675 break; 676 default: 677 if (bufsz < br_sha1_SIZE) 678 return -1; 679 md = &br_sha1_vtable; 680 bufsz = br_sha1_SIZE; 681 break; 682 } 683 if (n == 0) 684 n = strlen(s); 685 md->init(&mctx.vtable); 686 md->update(&mctx.vtable, s, n); 687 md->out(&mctx.vtable, buf); 688 return bufsz; 689 } 690 691 692