xref: /freebsd/lib/libsecureboot/tests/tvo.c (revision 666554111a7e6b4c1a9a6ff2e73f12cd582573bb)
15fff9558SSimon J. Gerraty /*
25fff9558SSimon J. Gerraty  * Copyright (c) 2017-2018, Juniper Networks, Inc.
35fff9558SSimon J. Gerraty  *
45fff9558SSimon J. Gerraty  * Redistribution and use in source and binary forms, with or without
55fff9558SSimon J. Gerraty  * modification, are permitted provided that the following conditions
65fff9558SSimon J. Gerraty  * are met:
75fff9558SSimon J. Gerraty  * 1. Redistributions of source code must retain the above copyright
85fff9558SSimon J. Gerraty  *    notice, this list of conditions and the following disclaimer.
95fff9558SSimon J. Gerraty  * 2. Redistributions in binary form must reproduce the above copyright
105fff9558SSimon J. Gerraty  *    notice, this list of conditions and the following disclaimer in the
115fff9558SSimon J. Gerraty  *    documentation and/or other materials provided with the distribution.
125fff9558SSimon J. Gerraty  *
135fff9558SSimon J. Gerraty  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
145fff9558SSimon J. Gerraty  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
155fff9558SSimon J. Gerraty  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
165fff9558SSimon J. Gerraty  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
175fff9558SSimon J. Gerraty  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
185fff9558SSimon J. Gerraty  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
195fff9558SSimon J. Gerraty  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
205fff9558SSimon J. Gerraty  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
215fff9558SSimon J. Gerraty  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225fff9558SSimon J. Gerraty  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
235fff9558SSimon J. Gerraty  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245fff9558SSimon J. Gerraty  */
255fff9558SSimon J. Gerraty #include <sys/cdefs.h>
265fff9558SSimon J. Gerraty __FBSDID("$FreeBSD$");
275fff9558SSimon J. Gerraty 
285fff9558SSimon J. Gerraty #include "../libsecureboot-priv.h"
295fff9558SSimon J. Gerraty 
305fff9558SSimon J. Gerraty #include <unistd.h>
315fff9558SSimon J. Gerraty #include <err.h>
325fff9558SSimon J. Gerraty #include <verify_file.h>
335fff9558SSimon J. Gerraty 
34*66655411SSimon J. Gerraty /* keep clang quiet */
35*66655411SSimon J. Gerraty extern char *Destdir;
36*66655411SSimon J. Gerraty extern size_t DestdirLen;
37*66655411SSimon J. Gerraty extern char *Skip;
38*66655411SSimon J. Gerraty extern time_t ve_utc;
39*66655411SSimon J. Gerraty 
40afc571b1SSimon J. Gerraty size_t DestdirLen;
41afc571b1SSimon J. Gerraty char *Destdir;
425fff9558SSimon J. Gerraty char *Skip;
435fff9558SSimon J. Gerraty 
445fff9558SSimon J. Gerraty int
455fff9558SSimon J. Gerraty main(int argc, char *argv[])
465fff9558SSimon J. Gerraty {
475fff9558SSimon J. Gerraty 	int n;
485fff9558SSimon J. Gerraty 	int fd;
495fff9558SSimon J. Gerraty 	int c;
505fff9558SSimon J. Gerraty 	int Vflag;
51*66655411SSimon J. Gerraty 	int vflag;
525fff9558SSimon J. Gerraty 	char *cp;
535fff9558SSimon J. Gerraty 	char *prefix;
545fff9558SSimon J. Gerraty 
55afc571b1SSimon J. Gerraty 	Destdir = NULL;
56afc571b1SSimon J. Gerraty 	DestdirLen = 0;
575fff9558SSimon J. Gerraty 	prefix = NULL;
585fff9558SSimon J. Gerraty 	Skip = NULL;
595fff9558SSimon J. Gerraty 
605fff9558SSimon J. Gerraty 	n = ve_trust_init();
615fff9558SSimon J. Gerraty 	Vflag = 0;
62*66655411SSimon J. Gerraty 	vflag = 0;
635fff9558SSimon J. Gerraty 
64*66655411SSimon J. Gerraty 	while ((c = getopt(argc, argv, "D:dp:s:T:u:Vv")) != -1) {
655fff9558SSimon J. Gerraty 		switch (c) {
66afc571b1SSimon J. Gerraty 		case 'D':
67afc571b1SSimon J. Gerraty 			Destdir = optarg;
68afc571b1SSimon J. Gerraty 			DestdirLen = strlen(optarg);
69afc571b1SSimon J. Gerraty 			break;
705fff9558SSimon J. Gerraty 		case 'd':
715fff9558SSimon J. Gerraty 			DebugVe++;
725fff9558SSimon J. Gerraty 			break;
735fff9558SSimon J. Gerraty 		case 'p':
745fff9558SSimon J. Gerraty 			prefix = optarg;
755fff9558SSimon J. Gerraty 			break;
765fff9558SSimon J. Gerraty 		case 's':
775fff9558SSimon J. Gerraty 			Skip = optarg;
785fff9558SSimon J. Gerraty 			break;
795fff9558SSimon J. Gerraty 		case 'T':
805fff9558SSimon J. Gerraty 			n = ve_trust_add(optarg);
815fff9558SSimon J. Gerraty 			printf("Local trust %s: %d\n", optarg, n);
825fff9558SSimon J. Gerraty 			break;
835fff9558SSimon J. Gerraty 		case 'V':
845fff9558SSimon J. Gerraty 			Vflag = 1;
855fff9558SSimon J. Gerraty 			break;
86*66655411SSimon J. Gerraty 		case 'v':
87*66655411SSimon J. Gerraty 			vflag = 1;
88*66655411SSimon J. Gerraty 			break;
89*66655411SSimon J. Gerraty 		case 'u':
90*66655411SSimon J. Gerraty 			ve_utc = (time_t)atoi(optarg);
91*66655411SSimon J. Gerraty 			break;
925fff9558SSimon J. Gerraty 		default:
935fff9558SSimon J. Gerraty 			errx(1, "unknown option: -%c", c);
945fff9558SSimon J. Gerraty 			break;
955fff9558SSimon J. Gerraty 		}
965fff9558SSimon J. Gerraty 	}
975fff9558SSimon J. Gerraty 
98*66655411SSimon J. Gerraty 	if (!vflag) {
99*66655411SSimon J. Gerraty 		printf("Trust %d\n", n);
100980bde58SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
101980bde58SSimon J. Gerraty 		ve_pcr_updating_set(1);
102980bde58SSimon J. Gerraty #endif
1035fff9558SSimon J. Gerraty 		ve_self_tests();
104*66655411SSimon J. Gerraty 	}
1055fff9558SSimon J. Gerraty 	for ( ; optind < argc; optind++) {
1065fff9558SSimon J. Gerraty 		if (Vflag) {
1075fff9558SSimon J. Gerraty 			/*
1085fff9558SSimon J. Gerraty 			 * Simulate what loader does.
1095fff9558SSimon J. Gerraty 			 * verify_file should "just work"
1105fff9558SSimon J. Gerraty 			 */
1115fff9558SSimon J. Gerraty 			fd = open(argv[optind], O_RDONLY);
1125fff9558SSimon J. Gerraty 			if (fd > 0) {
1135fff9558SSimon J. Gerraty 				/*
1145fff9558SSimon J. Gerraty 				 * See if verify_file is happy
1155fff9558SSimon J. Gerraty 				 */
1165fff9558SSimon J. Gerraty 				int x;
1175fff9558SSimon J. Gerraty 
118afc571b1SSimon J. Gerraty 				x = verify_file(fd, argv[optind], 0, VE_GUESS, __func__);
1195fff9558SSimon J. Gerraty 				printf("verify_file(%s) = %d\n", argv[optind], x);
1205fff9558SSimon J. Gerraty 				close(fd);
1215fff9558SSimon J. Gerraty 			}
1225fff9558SSimon J. Gerraty 			continue;
1235fff9558SSimon J. Gerraty 		}
1245fff9558SSimon J. Gerraty #ifdef VE_OPENPGP_SUPPORT
1255fff9558SSimon J. Gerraty 		if (strstr(argv[optind], "asc")) {
1265fff9558SSimon J. Gerraty 			cp = (char *)verify_asc(argv[optind], 1);
1275fff9558SSimon J. Gerraty 			if (cp) {
1285fff9558SSimon J. Gerraty 				printf("Verified: %s: %.28s...\n",
1295fff9558SSimon J. Gerraty 				    argv[optind], cp);
130*66655411SSimon J. Gerraty 				if (!vflag)
1315fff9558SSimon J. Gerraty 				    fingerprint_info_add(argv[optind],
1325fff9558SSimon J. Gerraty 					prefix, Skip, cp, NULL);
1335fff9558SSimon J. Gerraty 			} else {
1345fff9558SSimon J. Gerraty 				fprintf(stderr, "%s: %s\n",
1355fff9558SSimon J. Gerraty 				    argv[optind], ve_error_get());
1365fff9558SSimon J. Gerraty 			}
1375fff9558SSimon J. Gerraty 		} else
1385fff9558SSimon J. Gerraty #endif
1395fff9558SSimon J. Gerraty 		if (strstr(argv[optind], "sig")) {
1405fff9558SSimon J. Gerraty 			cp = (char *)verify_sig(argv[optind], 1);
1415fff9558SSimon J. Gerraty 			if (cp) {
1425fff9558SSimon J. Gerraty 				printf("Verified: %s: %.28s...\n",
1435fff9558SSimon J. Gerraty 				    argv[optind], cp);
144*66655411SSimon J. Gerraty 				if (!vflag)
1455fff9558SSimon J. Gerraty 					fingerprint_info_add(argv[optind],
1465fff9558SSimon J. Gerraty 					    prefix, Skip, cp, NULL);
1475fff9558SSimon J. Gerraty 			} else {
1485fff9558SSimon J. Gerraty 				fprintf(stderr, "%s: %s\n",
1495fff9558SSimon J. Gerraty 				    argv[optind], ve_error_get());
1505fff9558SSimon J. Gerraty 			}
1515fff9558SSimon J. Gerraty 		} else if (strstr(argv[optind], "manifest")) {
1525fff9558SSimon J. Gerraty 			cp = (char *)read_file(argv[optind], NULL);
1535fff9558SSimon J. Gerraty 			if (cp) {
1545fff9558SSimon J. Gerraty 				fingerprint_info_add(argv[optind],
1555fff9558SSimon J. Gerraty 				    prefix, Skip, cp, NULL);
1565fff9558SSimon J. Gerraty 			}
1575fff9558SSimon J. Gerraty 		} else {
1585fff9558SSimon J. Gerraty 			fd = verify_open(argv[optind], O_RDONLY);
1595fff9558SSimon J. Gerraty 			printf("verify_open(%s) = %d %s\n", argv[optind], fd,
1605fff9558SSimon J. Gerraty 			    (fd < 0) ? ve_error_get() : "");
1615fff9558SSimon J. Gerraty 			if (fd > 0) {
1625fff9558SSimon J. Gerraty 				/*
1635fff9558SSimon J. Gerraty 				 * Check that vectx_* can also verify the file.
1645fff9558SSimon J. Gerraty 				 */
1655fff9558SSimon J. Gerraty 				void *vp;
1665fff9558SSimon J. Gerraty 				char buf[BUFSIZ];
1675fff9558SSimon J. Gerraty 				struct stat st;
1685fff9558SSimon J. Gerraty 				int error;
169*66655411SSimon J. Gerraty 				off_t off;
170*66655411SSimon J. Gerraty 				size_t nb;
1715fff9558SSimon J. Gerraty 
1725fff9558SSimon J. Gerraty 				fstat(fd, &st);
1735fff9558SSimon J. Gerraty 				lseek(fd, 0, SEEK_SET);
1745fff9558SSimon J. Gerraty 				off = st.st_size % 512;
1755fff9558SSimon J. Gerraty 				vp = vectx_open(fd, argv[optind], off,
176afc571b1SSimon J. Gerraty 				    &st, &error, __func__);
1775fff9558SSimon J. Gerraty 				if (!vp) {
1785fff9558SSimon J. Gerraty 					printf("vectx_open(%s) failed: %d %s\n",
1795fff9558SSimon J. Gerraty 					    argv[optind], error,
1805fff9558SSimon J. Gerraty 					    ve_error_get());
1815fff9558SSimon J. Gerraty 				} else {
1825fff9558SSimon J. Gerraty 					off = vectx_lseek(vp,
1835fff9558SSimon J. Gerraty 					    (st.st_size % 1024), SEEK_SET);
184afc571b1SSimon J. Gerraty 					/* we can seek backwards! */
185afc571b1SSimon J. Gerraty 					off = vectx_lseek(vp, off/2, SEEK_SET);
1865fff9558SSimon J. Gerraty 					if (off < st.st_size) {
187*66655411SSimon J. Gerraty 						nb = vectx_read(vp, buf,
1885fff9558SSimon J. Gerraty 						    sizeof(buf));
189*66655411SSimon J. Gerraty 						if (nb > 0)
190*66655411SSimon J. Gerraty 							off += nb;
1915fff9558SSimon J. Gerraty 					}
1925fff9558SSimon J. Gerraty 					off = vectx_lseek(vp, 0, SEEK_END);
1935fff9558SSimon J. Gerraty 					/* repeating that should be harmless */
1945fff9558SSimon J. Gerraty 					off = vectx_lseek(vp, 0, SEEK_END);
195afc571b1SSimon J. Gerraty 					error = vectx_close(vp, VE_MUST, __func__);
1965fff9558SSimon J. Gerraty 					if (error) {
1975fff9558SSimon J. Gerraty 						printf("vectx_close(%s) == %d %s\n",
1985fff9558SSimon J. Gerraty 						    argv[optind], error,
1995fff9558SSimon J. Gerraty 						    ve_error_get());
2005fff9558SSimon J. Gerraty 					} else {
2015fff9558SSimon J. Gerraty 						printf("vectx_close: Verified: %s\n",
2025fff9558SSimon J. Gerraty 						    argv[optind]);
2035fff9558SSimon J. Gerraty 					}
2045fff9558SSimon J. Gerraty 				}
2055fff9558SSimon J. Gerraty 				close(fd);
2065fff9558SSimon J. Gerraty 			}
2075fff9558SSimon J. Gerraty 		}
2085fff9558SSimon J. Gerraty 	}
209980bde58SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
210980bde58SSimon J. Gerraty 	verify_pcr_export();
211980bde58SSimon J. Gerraty 	printf("pcr=%s\n", getenv("loader.ve.pcr"));
212980bde58SSimon J. Gerraty #endif
2135fff9558SSimon J. Gerraty 	return (0);
2145fff9558SSimon J. Gerraty }
2155fff9558SSimon J. Gerraty 
216