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@-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@static char vh_$H[] = \"`cat 
${.ALLSRC:N*crl*:Mv*.pem} | ${$H:U${H:tl}}`\";${.newline}@}"; ) > ${.TARGET}
+       echo "${.newline}${VE_HASH_LIST:O:u:@H@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())
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to