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 */
45extern char *Destdir;
46extern size_t DestdirLen;
47extern 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
60static int ve_status[SOPEN_MAX+1];
61static int ve_status_state;
62struct verify_status;
63static struct verify_status *verified_files = NULL;
64static int loaded_manifests = 0;	/* have we loaded anything? */
65
66enum {
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
77static 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 */
85void
86ve_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 */
105int
106ve_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 */
123struct verify_status {
124	dev_t	vs_dev;
125	ino_t	vs_ino;
126	int	vs_status;
127	struct verify_status *vs_next;
128};
129
130int
131is_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. */
152void
153add_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 */
175int
176load_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
223static int
224find_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
274static int
275severity_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
300static int Verifying = -1;		/* 0 if not verifying */
301
302static void
303verify_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
356static int
357getenv_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 */
409void
410verify_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 */
451int
452verify_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 */
516int
517verify_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 */
613void
614verify_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 */
662int
663hash_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