Index: head/lib/libsecureboot/Makefile.inc =================================================================== --- head/lib/libsecureboot/Makefile.inc +++ head/lib/libsecureboot/Makefile.inc @@ -98,10 +98,20 @@ .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 @@ # 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 @@ 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} Index: head/lib/libsecureboot/libsecureboot-priv.h =================================================================== --- head/lib/libsecureboot/libsecureboot-priv.h +++ head/lib/libsecureboot/libsecureboot-priv.h @@ -55,6 +55,7 @@ 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); Index: head/lib/libsecureboot/local.trust.mk =================================================================== --- head/lib/libsecureboot/local.trust.mk +++ head/lib/libsecureboot/local.trust.mk @@ -51,7 +51,7 @@ 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 @@ ${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 @@ .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 Index: head/lib/libsecureboot/openpgp/Makefile.inc =================================================================== --- head/lib/libsecureboot/openpgp/Makefile.inc +++ head/lib/libsecureboot/openpgp/Makefile.inc @@ -23,26 +23,29 @@ # 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 Index: head/lib/libsecureboot/openpgp/opgp_key.c =================================================================== --- head/lib/libsecureboot/openpgp/opgp_key.c +++ head/lib/libsecureboot/openpgp/opgp_key.c @@ -289,32 +289,47 @@ 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 @@ 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); Index: head/lib/libsecureboot/tests/Makefile =================================================================== --- head/lib/libsecureboot/tests/Makefile +++ head/lib/libsecureboot/tests/Makefile @@ -13,6 +13,7 @@ # 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 Index: head/lib/libsecureboot/vets.c =================================================================== --- head/lib/libsecureboot/vets.c +++ head/lib/libsecureboot/vets.c @@ -246,7 +246,9 @@ 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 @@ #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 @@ #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())