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
ve_status_set(int fd,int ves)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
ve_status_get(int fd)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
is_verified(struct stat * stp)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
add_verify_status(struct stat * stp,int status)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
load_manifest(const char * name,const char * prefix,const char * skip,struct stat * stp)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
find_manifest(const char * name)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 static int
severity_guess(const char * filename)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, ".hints") == 0 ||
289 strcmp(cp, ".order") == 0 ||
290 strcmp(cp, ".tgz") == 0)
291 return (VE_TRY);
292 if (strcmp(cp, ".4th") == 0 ||
293 strcmp(cp, ".lua") == 0 ||
294 strcmp(cp, ".rc") == 0)
295 return (VE_MUST);
296 }
297 return (VE_WANT);
298 }
299
300 static int Verifying = -1; /* 0 if not verifying */
301
302 static void
verify_tweak(int fd,off_t off,struct stat * stp,char * tweak,int * accept_no_fp)303 verify_tweak(int fd, off_t off, struct stat *stp,
304 char *tweak, int *accept_no_fp)
305 {
306 if (strcmp(tweak, "off") == 0) {
307 Verifying = 0;
308 } else if (strcmp(tweak, "strict") == 0) {
309 /* anything caller wants verified must be */
310 *accept_no_fp = VE_WANT;
311 Verbose = VE_VERBOSE_ALL;
312 /* treat self test failure as fatal */
313 if (!ve_self_tests()) {
314 panic("verify self tests failed");
315 }
316 } else if (strcmp(tweak, "modules") == 0) {
317 /* modules/kernel must be verified */
318 *accept_no_fp = VE_MUST;
319 } else if (strcmp(tweak, "try") == 0) {
320 /* best effort: always accept no fp */
321 *accept_no_fp = VE_MUST + 1;
322 } else if (strcmp(tweak, "verbose") == 0) {
323 Verbose = VE_VERBOSE_ALL;
324 } else if (strcmp(tweak, "quiet") == 0) {
325 Verbose = VE_VERBOSE_UNVERIFIED;
326 VerifyFlags = 0;
327 } else if (strcmp(tweak, "silent") == 0) {
328 Verbose = VE_VERBOSE_SILENT;
329 VerifyFlags = 0;
330 } else if (strncmp(tweak, "trust", 5) == 0) {
331 /* content is trust anchor to add or revoke */
332 unsigned char *ucp;
333 size_t num;
334
335 if (off > 0)
336 lseek(fd, 0, SEEK_SET);
337 ucp = read_fd(fd, stp->st_size);
338 if (ucp == NULL)
339 return;
340 if (strstr(tweak, "revoke")) {
341 num = ve_trust_anchors_revoke(ucp, stp->st_size);
342 DEBUG_PRINTF(3, ("revoked %d trust anchors\n",
343 (int) num));
344 } else {
345 num = ve_trust_anchors_add_buf(ucp, stp->st_size);
346 DEBUG_PRINTF(3, ("added %d trust anchors\n",
347 (int) num));
348 }
349 }
350 }
351
352 #ifndef VE_DEBUG_LEVEL
353 # define VE_DEBUG_LEVEL 0
354 #endif
355
356 static int
getenv_int(const char * var,int def)357 getenv_int(const char *var, int def)
358 {
359 const char *cp;
360 char *ep;
361 long val;
362
363 val = def;
364 cp = getenv(var);
365 if (cp && *cp) {
366 val = strtol(cp, &ep, 0);
367 if ((ep && *ep) || val != (int)val) {
368 val = def;
369 }
370 }
371 return (int)val;
372 }
373
374
375 /**
376 * @brief report verification status
377 *
378 * @param[in] path
379 * path we attempted to verify
380 *
381 * @param[in] severity
382 * indicator of how to handle case of missing fingerprint
383 *
384 * @param[in] status
385 * result of verification
386 * 0 not a file to be verified, > 0 success, < 0 error
387 *
388 * @param[in] stp
389 * pointer to struct stat, used in extra info to be output
390 *
391 * The output is dictated by combinations of the above and the setting
392 * of Verbose:
393 *
394 * VE_VERBOSE_SILENT
395 * report only failure to verify if severity is VE_WANT or higher.
396 *
397 * VE_VERBOSE_UNVERIFIED
398 * report any unverified file.
399 *
400 * VE_VERBOSE_MUST
401 * report verified only if severity is VE_MUST or higher.
402 *
403 * VE_VERBOSE_ALL
404 * report all verified files.
405 *
406 * VE_VERBOSE_DEBUG
407 * if stp is not NULL report dev,inode for path
408 */
409 void
verify_report(const char * path,int severity,int status,struct stat * stp)410 verify_report(const char *path, int severity, int status, struct stat *stp)
411 {
412 if (status < 0 || status == VE_FINGERPRINT_IGNORE) {
413 if (Verbose < VE_VERBOSE_ALL && severity < VE_WANT)
414 return;
415 if (Verbose >= VE_VERBOSE_UNVERIFIED || severity > VE_TRY ||
416 status <= VE_FINGERPRINT_WRONG) {
417 if (Verbose == VE_VERBOSE_DEBUG && stp != NULL)
418 printf("Unverified %s %llu,%llu\n",
419 ve_error_get(),
420 (long long)stp->st_dev,
421 (long long)stp->st_ino);
422 else
423 printf("Unverified %s\n", ve_error_get());
424 }
425 } else if (status > 0 && Verbose >= VE_VERBOSE_MUST) {
426 if (severity >= VE_MUST || Verbose >= VE_VERBOSE_ALL) {
427 if (Verbose == VE_VERBOSE_DEBUG && stp != NULL)
428 printf("Unverified %s %llu,%llu\n",
429 path,
430 (long long)stp->st_dev,
431 (long long)stp->st_ino);
432 else
433 printf("Verified %s\n", path);
434 }
435 }
436 }
437
438
439 /**
440 * @brief prepare to verify an open file
441 *
442 * @param[in] fd
443 * open descriptor
444 *
445 * @param[in] filename
446 * path we opened and will use to lookup fingerprint
447 *
448 * @param[in] stp
449 * stat pointer so we can check file type
450 */
451 int
verify_prep(int fd,const char * filename,off_t off,struct stat * stp,const char * caller)452 verify_prep(int fd, const char *filename, off_t off, struct stat *stp,
453 const char *caller)
454 {
455 int rc;
456
457 if (Verifying < 0) {
458 Verifying = ve_trust_init();
459 /* initialize ve_status with default result */
460 rc = Verifying ? VE_NOT_CHECKED : VE_NOT_VERIFYING;
461 ve_status_set(0, rc);
462 ve_status_state = VE_STATUS_NONE;
463 if (Verifying) {
464 ve_self_tests();
465 ve_anchor_verbose_set(1);
466 }
467 }
468 if (!Verifying || fd < 0)
469 return (0);
470 if (stp) {
471 if (fstat(fd, stp) < 0 || !S_ISREG(stp->st_mode))
472 return (0);
473 }
474 DEBUG_PRINTF(2,
475 ("verify_prep: caller=%s,fd=%d,name='%s',off=%lld,dev=%lld,ino=%llu\n",
476 caller, fd, filename, (long long)off, (long long)stp->st_dev,
477 (unsigned long long)stp->st_ino));
478 rc = is_verified(stp);
479 if (rc == VE_NOT_CHECKED) {
480 rc = find_manifest(filename);
481 if (rc == VE_VERIFIED)
482 rc = VE_NOT_CHECKED;
483 } else {
484 ve_status_set(fd, rc);
485 }
486 return (rc);
487 }
488
489 /**
490 * @brief verify an open file
491 *
492 * @param[in] fd
493 * open descriptor
494 *
495 * @param[in] filename
496 * path we opened and will use to lookup fingerprint
497 *
498 * @param[in] off
499 * current offset in fd, must be restored on return
500 *
501 * @param[in] severity
502 * indicator of how to handle case of missing fingerprint
503 *
504 * We look for a signed manifest relative to the filename
505 * just opened and verify/load it if needed.
506 *
507 * We then use verify_fd() in libve to actually verify that hash for
508 * open file. If it returns < 0 we look at the severity arg to decide
509 * what to do about it.
510 *
511 * If verify_fd() returns VE_FINGERPRINT_NONE we accept it if severity
512 * is < accept_no_fp.
513 *
514 * @return >= 0 on success < 0 on failure
515 */
516 int
verify_file(int fd,const char * filename,off_t off,int severity,const char * caller)517 verify_file(int fd, const char *filename, off_t off, int severity,
518 const char *caller)
519 {
520 static int check_verbose = 1;
521 static int accept_no_fp = ACCEPT_NO_FP_DEFAULT;
522 struct stat st;
523 char *cp;
524 int rc;
525
526 if (check_verbose) {
527 check_verbose = 0;
528 Verbose = getenv_int("VE_VERBOSE", VE_VERBOSE_DEFAULT);
529 VerifyFlags = getenv_int("VE_VERIFY_FLAGS",
530 Verbose ? VEF_VERBOSE : 0);
531 #ifndef UNIT_TEST
532 ve_debug_set(getenv_int("VE_DEBUG_LEVEL", VE_DEBUG_LEVEL));
533 #endif
534 }
535
536 rc = verify_prep(fd, filename, off, &st, caller);
537
538 if (!rc)
539 return (0);
540
541 if (rc != VE_FINGERPRINT_WRONG && loaded_manifests) {
542 if (rc != VE_NOT_CHECKED)
543 return (rc);
544
545 if (severity <= VE_GUESS)
546 severity = severity_guess(filename);
547 #ifdef VE_PCR_SUPPORT
548 /*
549 * Only update pcr with things that must verify
550 * these tend to be processed in a more deterministic
551 * order, which makes our pseudo pcr more useful.
552 */
553 ve_pcr_updating_set((severity == VE_MUST));
554 #endif
555 #ifdef UNIT_TEST
556 if (DestdirLen > 0 &&
557 strncmp(filename, Destdir, DestdirLen) == 0) {
558 filename += DestdirLen;
559 }
560 #endif
561 rc = verify_fd(fd, filename, off, &st);
562 verify_report(filename, severity, rc, &st);
563 if (rc >= 0) {
564 if (severity < VE_MUST) { /* not a kernel or module */
565 if ((cp = strrchr(filename, '/'))) {
566 cp++;
567 if (strncmp(cp, "loader.ve.", 10) == 0) {
568 cp += 10;
569 verify_tweak(fd, off, &st, cp,
570 &accept_no_fp);
571 }
572 }
573 }
574 add_verify_status(&st, rc);
575 ve_status_set(fd, rc);
576 return (rc);
577 }
578 if (rc == VE_FINGERPRINT_UNKNOWN && severity < VE_MUST)
579 rc = VE_UNVERIFIED_OK;
580 else if (rc == VE_FINGERPRINT_NONE && severity < accept_no_fp)
581 rc = VE_UNVERIFIED_OK;
582
583 add_verify_status(&st, rc);
584
585 /* recheck debug/verbose level next time we are called */
586 if (rc == VE_UNVERIFIED_OK) {
587 check_verbose = 1;
588 }
589 }
590 #ifdef LOADER_VERIEXEC_TESTING
591 else if (rc != VE_FINGERPRINT_WRONG) {
592 /*
593 * We have not loaded any manifest and
594 * not because of verication failure.
595 * Most likely reason is we have none.
596 * Allow boot to proceed if we are just testing.
597 */
598 return (VE_UNVERIFIED_OK);
599 }
600 #endif
601 if (rc == VE_FINGERPRINT_WRONG && severity > accept_no_fp)
602 panic("cannot continue");
603 ve_status_set(fd, rc);
604 return (rc);
605 }
606
607 /**
608 * @brief get hex string for pcr value and export
609 *
610 * In case we are doing measured boot, provide
611 * value of the "pcr" data we have accumulated.
612 */
613 void
verify_pcr_export(void)614 verify_pcr_export(void)
615 {
616 #ifdef VE_PCR_SUPPORT
617 char hexbuf[br_sha256_SIZE * 2 + 2];
618 unsigned char hbuf[br_sha256_SIZE];
619 char *hinfo;
620 char *hex;
621 ssize_t hlen;
622
623 hlen = ve_pcr_get(hbuf, sizeof(hbuf));
624 if (hlen > 0) {
625 hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen);
626 if (hex) {
627 hex[hlen*2] = '\0'; /* clobber newline */
628 setenv("loader.ve.pcr", hex, 1);
629 DEBUG_PRINTF(1,
630 ("%s: setenv(loader.ve.pcr, %s\n", __func__,
631 hex));
632 hinfo = ve_pcr_hashed_get(1);
633 if (hinfo) {
634 setenv("loader.ve.hashed", hinfo, 1);
635 DEBUG_PRINTF(1,
636 ("%s: setenv(loader.ve.hashed, %s\n",
637 __func__, hinfo));
638 if ((hlen = strlen(hinfo)) > KENV_MVALLEN) {
639 /*
640 * bump kenv_mvallen
641 * roundup to multiple of KENV_MVALLEN
642 */
643 char mvallen[16];
644
645 hlen += KENV_MVALLEN -
646 (hlen % KENV_MVALLEN);
647 if (snprintf(mvallen, sizeof(mvallen),
648 "%d", (int) hlen) < (int)sizeof(mvallen))
649 setenv("kenv_mvallen", mvallen, 1);
650 }
651 free(hinfo);
652 }
653 }
654 }
655 #endif
656 }
657
658 /*
659 * For tftp and http we need to hash pathname
660 * to be able to fake stat(2) data.
661 */
662 int
hash_string(char * s,size_t n,char * buf,size_t bufsz)663 hash_string(char *s, size_t n, char *buf, size_t bufsz)
664 {
665 br_hash_compat_context mctx;
666 const br_hash_class *md;
667
668 switch (bufsz) {
669 case br_sha1_SIZE:
670 md = &br_sha1_vtable;
671 break;
672 case br_sha256_SIZE:
673 md = &br_sha256_vtable;
674 break;
675 default:
676 if (bufsz < br_sha1_SIZE)
677 return -1;
678 md = &br_sha1_vtable;
679 bufsz = br_sha1_SIZE;
680 break;
681 }
682 if (n == 0)
683 n = strlen(s);
684 md->init(&mctx.vtable);
685 md->update(&mctx.vtable, s, n);
686 md->out(&mctx.vtable, buf);
687 return bufsz;
688 }
689
690
691