svn commit: r347408 - in head/lib/libsecureboot: . openpgp tests

Simon J. Gerraty sjg at FreeBSD.org
Thu May 9 22:25:16 UTC 2019


Author: sjg
Date: Thu May  9 22:25:12 2019
New Revision: 347408
URL: https://svnweb.freebsd.org/changeset/base/347408

Log:
  libsecureboot: make it easier to customize trust anchors
  
  Avoid making hash self-tests depend on X.509 certs.
  Include OpenPGP keys in trust store count.
  
  Reviewed by:	stevek
  MFC after:	1 week
  Sponsored by:	Juniper Networks
  Differential Revision:	https://reviews.freebsd.org/D20208

Modified:
  head/lib/libsecureboot/Makefile.inc
  head/lib/libsecureboot/libsecureboot-priv.h
  head/lib/libsecureboot/local.trust.mk
  head/lib/libsecureboot/openpgp/Makefile.inc
  head/lib/libsecureboot/openpgp/opgp_key.c
  head/lib/libsecureboot/tests/Makefile
  head/lib/libsecureboot/vets.c

Modified: head/lib/libsecureboot/Makefile.inc
==============================================================================
--- head/lib/libsecureboot/Makefile.inc	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/Makefile.inc	Thu May  9 22:25:12 2019	(r347408)
@@ -98,10 +98,20 @@ CFLAGS+= ${VE_HASH_LIST:@H at -DVE_$H_SUPPORT@} \
 
 .if ${VE_SELF_TESTS} != "no"
 # The input used for hash KATs
+# we use a string by default so it is independent of any other test
+VE_HASH_KAT_STRLEN?= strlen
+.if ${VE_HASH_KAT_STRLEN} == "strlen"
+VE_HASH_KAT_STR?= self-tests-are-good
+VE_HASH_KAT_STR_INPUT= echo -n
+XCFLAGS.vets+= -DVE_HASH_KAT_STR=\"${VE_HASH_KAT_STR}\"
+.else
 VE_HASH_KAT_STR?= vc_PEM
-
+VE_HASH_KAT_STR_INPUT= cat
+VE_HASH_KAT_STRLEN= sizeof
 XCFLAGS.vets+= -DVE_HASH_KAT_STR=${VE_HASH_KAT_STR}
 .endif
+XCFLAGS.vets+= -DVE_HASH_KAT_STRLEN=${VE_HASH_KAT_STRLEN}
+.endif
 
 # this should be updated occassionally this is 2019-01-01Z
 SOURCE_DATE_EPOCH?= 1546329600
@@ -121,17 +131,20 @@ BUILD_UTC?= ${${STAT:Ustat} -f %m ${BUILD_UTC_FILE}:L:
 # If we are doing self-tests, we define another arrary vc_PEM
 # containing certificates that we can verify for each trust anchor.
 # This is typically a subordinate CA cert.
-# Finally we generate a hash of vc_PEM using each supported hash method
+# Finally we generate a hash of VE_HASH_KAT_STR
+# using each supported hash method
 # to use as a Known Answer Test (needed for FIPS 140-2)
 #
+TA_PEM_LIST ?= ${.ALLSRC:N*crl*:Mt*.pem}
+VC_PEM_LIST ?= ${.ALLSRC:N*crl*:Mv*.pem}
 vets.o vets.po vets.pico: ta.h
-ta.h: ${.ALLTARGETS:M[tv]*pem:O:u}
+ta.h:
 	@( echo '/* Autogenerated - DO NOT EDIT!!! */'; echo; \
-	cat ${.ALLSRC:N*crl*:Mt*.pem} /dev/null | \
+	cat ${TA_PEM_LIST:O:u} /dev/null | \
 	file2c -sx 'static const char ta_PEM[] = {' '};'; \
-	echo "${.newline}${VE_HASH_LIST:@H at static char vh_$H[] = \"`cat ${.ALLSRC:N*crl*:Mv*.pem} | ${$H:U${H:tl}}`\";${.newline}@}"; ) > ${.TARGET}
+	echo "${.newline}${VE_HASH_LIST:O:u:@H at static char vh_$H[] = \"`${VE_HASH_KAT_STR_INPUT} ${VE_HASH_KAT_STR} | ${$H:U${H:tl}}`\";${.newline}@}"; ) > ${.TARGET}
 .if ${VE_SELF_TESTS} != "no"
-	( cat ${.ALLSRC:N*crl*:Mv*.pem} /dev/null | \
+	( cat ${VC_PEM_LIST:O:u} /dev/null | \
 	file2c -sx 'static const char vc_PEM[] = {' '};'; echo ) >> ${.TARGET}
 .endif
 	echo '#define BUILD_UTC ${BUILD_UTC}' >> ${.TARGET} ${.OODATE:MNOMETA_CMP}
@@ -141,7 +154,7 @@ vesigned.o vesigned.po vesigned.pico: vse.h
 vse.h:
 	@( echo '/* Autogenerated - DO NOT EDIT!!! */'; echo; \
 	echo "static const char *signature_exts[] = {"; \
-	echo '${VE_SIGNATURE_EXT_LIST:@e@"$e",${.newline}@}'; \
+	echo '${VE_SIGNATURE_EXT_LIST:O:u:@e@"$e",${.newline}@}'; \
 	echo 'NULL };' ) > ${.TARGET}
 
 

Modified: head/lib/libsecureboot/libsecureboot-priv.h
==============================================================================
--- head/lib/libsecureboot/libsecureboot-priv.h	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/libsecureboot-priv.h	Thu May  9 22:25:12 2019	(r347408)
@@ -55,6 +55,7 @@ int verify_rsa_digest(br_rsa_public_key *pkey,
 int is_verified(struct stat *stp);
 void add_verify_status(struct stat *stp, int status);
 
+int openpgp_trust_init(void);
 int openpgp_self_tests(void);
 
 int                     efi_secure_boot_enabled(void);

Modified: head/lib/libsecureboot/local.trust.mk
==============================================================================
--- head/lib/libsecureboot/local.trust.mk	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/local.trust.mk	Thu May  9 22:25:12 2019	(r347408)
@@ -51,7 +51,7 @@ SIGN_OPENPGP= ${PYTHON} ${SIGNER:H}/openpgp-sign.py -a
 ta_openpgp.asc:
 	${SIGN_OPENPGP} -C ${.TARGET}
 
-ta.h: ta_openpgp.asc
+ta_asc.h: ta_openpgp.asc
 
 .if ${VE_SELF_TESTS} != "no"
 # for self test
@@ -59,7 +59,7 @@ vc_openpgp.asc: ta_openpgp.asc
 	${SIGN_OPENPGP} ${.ALLSRC:M*.asc}
 	mv ta_openpgp.asc.asc ${.TARGET}
 
-ta.h: vc_openpgp.asc
+ta_asc.h: vc_openpgp.asc
 .endif
 .endif
 
@@ -72,17 +72,20 @@ ecerts.pem:
 .if ${VE_SIGNATURE_LIST:tu:MECDSA} != ""
 # the last cert in the chain is the one we want
 ta_ec.pem: ecerts.pem _LAST_PEM_USE
-
+ta.h: ta_ec.pem
 .if ${VE_SELF_TESTS} != "no"
 # these are for verification self test
 vc_ec.pem: ecerts.pem _2ndLAST_PEM_USE
+ta.h: vc_ec.pem
 .endif
 .endif
 
 .if ${VE_SIGNATURE_LIST:tu:MRSA} != ""
 ta_rsa.pem: rcerts.pem _LAST_PEM_USE
+ta.h: ta_rsa.pem
 .if ${VE_SELF_TESTS} != "no"
 vc_rsa.pem: rcerts.pem _2ndLAST_PEM_USE
+ta.h: vc_rsa.pem
 .endif
 .endif
 

Modified: head/lib/libsecureboot/openpgp/Makefile.inc
==============================================================================
--- head/lib/libsecureboot/openpgp/Makefile.inc	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/openpgp/Makefile.inc	Thu May  9 22:25:12 2019	(r347408)
@@ -23,26 +23,29 @@ opgp_key.o opgp_key.po opgp_key.pico: ta_asc.h
 # It is assumed that these v*.asc files are named similarly to
 # the appropriate t*.asc so that the relative order of vc_ASC
 # entries matches ta_ASC.
-# 
-ta_asc.h: ${.ALLTARGETS:M[tv]*.asc:O:u}
+#
+TA_ASC_LIST ?= ${.ALLSRC:Mt*.asc}
+VC_ASC_LIST ?= ${.ALLSRC:Mv*.asc}
+
+ta_asc.h: 
 .if ${VE_SIGNATURE_LIST:MOPENPGP} != ""
 	@( echo '/* Autogenerated - DO NOT EDIT!!! */'; echo; \
 	echo "#define HAVE_TA_ASC 1"; \
-	set -- ${.ALLSRC:Mt*.asc:@f@$f ${f:T:R}@}; \
+	set -- ${TA_ASC_LIST:@f@$f ${f:T:R}@}; \
 	while test $$# -ge 2; do \
 		file2c -sx "static const char $$2[] = {" ', 0x00 };' < $$1; \
 		shift 2; \
 	done; \
-	echo 'static const char *ta_ASC[] = { ${.ALLSRC:Mt*.asc:T:R:ts,}, NULL };'; \
+	echo 'static const char *ta_ASC[] = { ${TA_ASC_LIST:T:R:ts,}, NULL };'; \
 	echo; ) > ${.TARGET}
 .if ${VE_SELF_TESTS} != "no"
 	@( echo "#define HAVE_VC_ASC 1"; \
-	set -- ${.ALLSRC:Mv*.asc:@f@$f ${f:T:R}@}; \
+	set -- ${VC_ASC_LIST:@f@$f ${f:T:R}@}; \
 	while test $$# -ge 2; do \
 		file2c -sx "static const char $$2[] = {" ', 0x00 };' < $$1; \
 		shift 2; \
 	done; \
-	echo 'static const char *vc_ASC[] = { ${.ALLSRC:Mv*.asc:T:R:ts,}, NULL };'; \
+	echo 'static const char *vc_ASC[] = { ${VC_ASC_LIST:T:R:ts,}, NULL };'; \
 	echo; ) >> ${.TARGET}
 .endif
 .endif

Modified: head/lib/libsecureboot/openpgp/opgp_key.c
==============================================================================
--- head/lib/libsecureboot/openpgp/opgp_key.c	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/openpgp/opgp_key.c	Thu May  9 22:25:12 2019	(r347408)
@@ -289,32 +289,47 @@ load_trusted_key_id(const char *keyID)
 OpenPGP_key *
 load_key_id(const char *keyID)
 {
-	static int once = 0;
 	OpenPGP_key *key;
 
-	if (!once) {
+	key = openpgp_trust_get(keyID);
+#ifndef _STANDALONE
+	if (!key)
+		key = load_trusted_key_id(keyID);
+#endif
+	return (key);
+}
+
+/**
+ * @brief initialize our internal trust store if any
+ */
+int
+openpgp_trust_init(void)
+{
+	static int once = -1;
 #ifdef HAVE_TA_ASC
-		const char **tp;
-		char *cp;
-		size_t n;
+	OpenPGP_key *key;
+	const char **tp;
+	char *cp;
+	size_t n;
+#endif
 
+	if (once < 0) {
+		once = 0;
+#ifdef HAVE_TA_ASC
 		for (tp = ta_ASC; *tp; tp++) {
 			if ((cp = strdup(*tp))) {
 				n = strlen(cp);
 				key = load_key_buf((unsigned char *)cp, n);
 				free(cp);
-				openpgp_trust_add(key);
+				if (key) {
+					openpgp_trust_add(key);
+					once++;
+				}
 			}
 		}
-#endif
-		once = 1;
 	}
-	key = openpgp_trust_get(keyID);
-#ifndef _STANDALONE
-	if (!key)
-		key = load_trusted_key_id(keyID);
 #endif
-	return (key);
+	return (once);
 }
 
 /**
@@ -333,19 +348,21 @@ openpgp_self_tests(void)
 	char *fdata, *sdata = NULL;
 	size_t fbytes, sbytes;
 
-	for (tp = ta_ASC, vp = vc_ASC; *tp && *vp && rc; tp++, vp++) {
-		if ((fdata = strdup(*tp)) &&
-		    (sdata = strdup(*vp))) {
-			fbytes = strlen(fdata);
-			sbytes = strlen(sdata);
-			rc = openpgp_verify("ta_ASC",
-			    (unsigned char *)fdata, fbytes,
-			    (unsigned char *)sdata, sbytes, 0);
-			printf("Testing verify OpenPGP signature:\t\t%s\n",
-			    rc ? "Failed" : "Passed");
+	if (openpgp_trust_init() > 0) {
+		for (tp = ta_ASC, vp = vc_ASC; *tp && *vp && rc; tp++, vp++) {
+			if ((fdata = strdup(*tp)) &&
+			    (sdata = strdup(*vp))) {
+				fbytes = strlen(fdata);
+				sbytes = strlen(sdata);
+				rc = openpgp_verify("ta_ASC",
+				    (unsigned char *)fdata, fbytes,
+				    (unsigned char *)sdata, sbytes, 0);
+				printf("Testing verify OpenPGP signature:\t\t%s\n",
+				    rc ? "Failed" : "Passed");
+			}
+			free(fdata);
+			free(sdata);
 		}
-		free(fdata);
-		free(sdata);
 	}
 #endif
 	return (rc);

Modified: head/lib/libsecureboot/tests/Makefile
==============================================================================
--- head/lib/libsecureboot/tests/Makefile	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/tests/Makefile	Thu May  9 22:25:12 2019	(r347408)
@@ -13,6 +13,7 @@ NO_SHARED=
 
 # we want to test verify_file api too
 # which requires a kludge or two
+MK_LOADER_EFI_SECUREBOOT= no
 .include "../Makefile.libsa.inc"
 BRSSL_CFLAGS := ${BRSSL_CFLAGS:N-DNO_STDIO}
 XCFLAGS.verify_file += -DSOPEN_MAX=64

Modified: head/lib/libsecureboot/vets.c
==============================================================================
--- head/lib/libsecureboot/vets.c	Thu May  9 21:00:15 2019	(r347407)
+++ head/lib/libsecureboot/vets.c	Thu May  9 22:25:12 2019	(r347408)
@@ -246,7 +246,9 @@ ve_trust_init(void)
 		num = ve_trust_anchors_add(xcs, num);
 #endif
 	once = (int) VEC_LEN(trust_anchors);
-
+#ifdef VE_OPENPGP_SUPPORT
+	once += openpgp_trust_init();
+#endif
 	return (once);
 }
 
@@ -814,7 +816,7 @@ test_hash(const br_hash_class *md, size_t hlen,
 #define ve_test_hash(n, N) \
 	printf("Testing hash: " #n "\t\t\t\t%s\n", \
 	    test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \
-	    VE_HASH_KAT_STR, sizeof(VE_HASH_KAT_STR), \
+	    VE_HASH_KAT_STR, VE_HASH_KAT_STRLEN(VE_HASH_KAT_STR), \
 	    vh_ ## N) ? "Failed" : "Passed")
 
 /**
@@ -863,34 +865,32 @@ ve_self_tests(void)
 #ifdef VERIFY_CERTS_STR
 	xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR),
 	    sizeof(VERIFY_CERTS_STR), &num);
-	if (xcs == NULL)
-		return (0);
-	/*
-	 * We want the commonName field
-	 * the OID we want is 2,5,4,3 - but DER encoded
-	 */
-	cn_oid[0] = 3;
-	cn_oid[1] = 0x55;
-	cn_oid[2] = 4;
-	cn_oid[3] = 3;
-	cn.oid = cn_oid;
-	cn.buf = cn_buf;
+	if (xcs != NULL) {
+		/*
+		 * We want the commonName field
+		 * the OID we want is 2,5,4,3 - but DER encoded
+		 */
+		cn_oid[0] = 3;
+		cn_oid[1] = 0x55;
+		cn_oid[2] = 4;
+		cn_oid[3] = 3;
+		cn.oid = cn_oid;
+		cn.buf = cn_buf;
 
-	for (u = 0; u < num; u ++) {
-		cn.len = sizeof(cn_buf);
-		if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) {
-			free_cert_contents(&xcs[u]);
-			once++;
-			printf("Testing verify certificate: %s\tPassed\n",
-			    cn.status ? cn_buf : "");
-			xfreepkey(pk);
+		for (u = 0; u < num; u ++) {
+			cn.len = sizeof(cn_buf);
+			if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) {
+				free_cert_contents(&xcs[u]);
+				once++;
+				printf("Testing verify certificate: %s\tPassed\n",
+				    cn.status ? cn_buf : "");
+				xfreepkey(pk);
+			}
 		}
+		if (!once)
+			printf("Testing verify certificate:\t\t\tFailed\n");
+		xfree(xcs);
 	}
-	if (!once)
-		printf("Testing verify certificate:\t\t\tFailed\n");
-	xfree(xcs);
-#else
-	printf("No X.509 self tests\n");
 #endif	/* VERIFY_CERTS_STR */
 #ifdef VE_OPENPGP_SUPPORT
 	if (!openpgp_self_tests())


More information about the svn-src-all mailing list