From 1a8252b87784efb84a03cdcfc00f29b2f2cdb3b2 Mon Sep 17 00:00:00 2001 From: Juergen Repp Date: Wed, 22 Nov 2023 01:52:23 +0100 Subject: [PATCH] FAPI TEST: rework test certificate creation * A CA script for initializing the CA was added. * The EK, the EK certificate and the EK fingerprint is now created in main-fapi.c * The creation of the EK certificate was removed from fint-log-compiler.sh * Unneeded helper programs are removed. Signed-off-by: Juergen Repp --- Makefile-test.am | 34 +- Makefile.am | 14 + configure.ac | 2 + script/ekca/init_ca.sh | 129 ++++ script/fint-log-compiler.sh | 132 +--- src/tss2-fapi/api/Fapi_Provision.c | 13 + test/helper/tpm_dumpstate.c | 112 ---- test/helper/tpm_getek.c | 203 ------ test/helper/tpm_getek_ecc.c | 253 -------- test/helper/tpm_startup.c | 67 -- test/helper/tpm_transientempty.c | 81 --- test/helper/tpm_writeekcert.c | 149 ----- test/integration/main-fapi.c | 953 ++++++++++++++++++++++++++++- test/integration/test-common.c | 2 - test/integration/test-common.h | 2 + test/integration/test-fapi.h | 1 - 16 files changed, 1111 insertions(+), 1036 deletions(-) create mode 100755 script/ekca/init_ca.sh delete mode 100644 test/helper/tpm_dumpstate.c delete mode 100644 test/helper/tpm_getek.c delete mode 100644 test/helper/tpm_getek_ecc.c delete mode 100644 test/helper/tpm_startup.c delete mode 100644 test/helper/tpm_transientempty.c delete mode 100644 test/helper/tpm_writeekcert.c diff --git a/Makefile-test.am b/Makefile-test.am index 4a2a3c513..6fc9d2465 100644 --- a/Makefile-test.am +++ b/Makefile-test.am @@ -21,6 +21,7 @@ EXTRA_DIST += $(srcdir)/script/int-log-compiler.sh \ $(srcdir)/script/fint-log-compiler.sh \ $(srcdir)/script/int-log-compiler-common.sh \ $(srcdir)/script/ekca/create_ca.sh \ + $(srcdir)/script/ekca/init_ca.sh \ $(srcdir)/script/ekca/ek.cnf \ $(srcdir)/script/ekca/intermed-ca.cnf \ $(srcdir)/script/ekca/root-ca.cnf @@ -43,39 +44,6 @@ test_helper_tpm_cmd_tcti_dummy_LDFLAGS = $(TESTS_LDFLAGS) test_helper_tpm_cmd_tcti_dummy_LDADD = $(TESTS_LDADD) endif #UNIT -if ENABLE_INTEGRATION -check_PROGRAMS += test/helper/tpm_startup -test_helper_tpm_startup_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration -test_helper_tpm_startup_LDFLAGS = $(TESTS_LDFLAGS) -test_helper_tpm_startup_LDADD = $(TESTS_LDADD) - -check_PROGRAMS += test/helper/tpm_transientempty -test_helper_tpm_transientempty_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration -test_helper_tpm_transientempty_LDFLAGS = $(TESTS_LDFLAGS) -test_helper_tpm_transientempty_LDADD = $(TESTS_LDADD) - -check_PROGRAMS += test/helper/tpm_dumpstate -test_helper_tpm_dumpstate_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration -test_helper_tpm_dumpstate_LDFLAGS = $(TESTS_LDFLAGS) -test_helper_tpm_dumpstate_LDADD = $(TESTS_LDADD) - -check_PROGRAMS += test/helper/tpm_getek -test_helper_tpm_getek_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration -test_helper_tpm_getek_LDFLAGS = $(TESTS_LDFLAGS) -lcrypto -test_helper_tpm_getek_LDADD = $(TESTS_LDADD) - -check_PROGRAMS += test/helper/tpm_getek_ecc -test_helper_tpm_getek_ecc_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration -test_helper_tpm_getek_ecc_LDFLAGS = $(TESTS_LDFLAGS) -lcrypto -test_helper_tpm_getek_ecc_LDADD = $(TESTS_LDADD) - - -check_PROGRAMS += test/helper/tpm_writeekcert -test_helper_tpm_writeekcert_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration -test_helper_tpm_writeekcert_LDFLAGS = $(TESTS_LDFLAGS) -test_helper_tpm_writeekcert_LDADD = $(TESTS_LDADD) -endif #ENABLE_INTEGRATION - ### Rules to enerate binary test files for FAPI from b64 files. if FAPI diff --git a/Makefile.am b/Makefile.am index 12de494fc..68c8ff53a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -966,11 +966,25 @@ install-data-hook: install-dirs fi uninstall-local: + -rm -r -f $(top_builddir)/ca -rm $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)tpm-udev.rules cd $(DESTDIR)$(man3dir) && \ [ -L Tss2_TctiLdr_Initialize_Ex.3 ] && \ rm -f Tss2_TctiLdr_Initialize_Ex.3 || true +clean-hook: + -rm -r -f $(top_builddir)/ca + +check-hook: + -rm -r -f $(top_builddir)/ca + +prepare-check: +if INIT_CA + $(top_srcdir)/script/ekca/init_ca.sh $(top_builddir) +endif + +check: prepare-check + EXTRA_DIST += \ doc/doxygen.dox \ doc/coding_standard_c.md \ diff --git a/configure.ac b/configure.ac index db4e99662..66f06efe5 100644 --- a/configure.ac +++ b/configure.ac @@ -640,6 +640,8 @@ AS_IF([test "x$enable_self_generated_certificate" = xyes], [AC_DEFINE([SELF_GENERATED_CERTIFICATE], [1], [Allow usage of self generated root certificate])], [AS_IF([test "x$integration_tcti" != "xdevice"], [AC_DEFINE([FAPI_TEST_EK_CERT_LESS], [1], [Perform integration tests without EK certificate verification])])]) +AM_CONDITIONAL([INIT_CA], [test "x$enable_self_generated_certificate" == xyes]) + AS_IF([test "x$enable_integration" = "xyes" && test "x$enable_self_generated_certificate" != "xyes" && test "x$integration_tcti" != "xdevice"], [AC_MSG_WARN([Running integration tests without EK certificate verification, use --enable-self-generated-certificate for full test coverage])]) diff --git a/script/ekca/init_ca.sh b/script/ekca/init_ca.sh new file mode 100755 index 000000000..e8c94bb4e --- /dev/null +++ b/script/ekca/init_ca.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash + +#set -x + +#set -euf +OS=$(uname) +DATE_FMT_BEFORE="" +DATE_FMT_AFTER="" +SED_CMD="" + +if [ "$OS" == "Linux" ]; then + DATE_FMT_BEFORE="+%y%m%d000000Z -u -d -1day" + DATE_FMT_AFTER="+%y%m%d000000Z -u -d +10years+1day" + SED_CMD="sed -i" +elif [ "$OS" == "FreeBSD" ]; then + DATE_FMT_BEFORE="-u -v-1d +%y%m%d000000Z" + DATE_FMT_AFTER="-u -v+10y +%y%m%d000000Z" + SED_CMD="sed -i '' -e" +fi + +EKCADIR="$(dirname $(realpath ${0}))/" +CA_DIR="$1/ca" +if test -e $CA_DIR; then + exit +fi +mkdir -p $CA_DIR + +pushd "$CA_DIR" + +mkdir root-ca +pushd root-ca + +mkdir certreqs certs crl newcerts private +touch root-ca.index +echo 00 > root-ca.crlnum +echo 1000 > root-ca.serial +echo "123456" > pass.txt + +cp "${EKCADIR}/root-ca.cnf" ./ +export OPENSSL_CONF=./root-ca.cnf +ROOT_URL="file:$ROOTCRT" +${SED_CMD} "s|ROOTCRT|$ROOT_URL|g" $OPENSSL_CONF +ROOT_URL="file:$ROOTCRL" +${SED_CMD} "s|ROOTCRL|$ROOT_URL|g" $OPENSSL_CONF +openssl req -new -out root-ca.req.pem -passout file:pass.txt + +# +# Create self signed root certificate +# + +openssl ca -selfsign \ + -in root-ca.req.pem \ + -out root-ca.cert.pem \ + -extensions root-ca_ext \ + -startdate `date ${DATE_FMT_BEFORE}` \ + -enddate `date ${DATE_FMT_AFTER}` \ + -passin file:pass.txt -batch + +openssl x509 -outform der -in root-ca.cert.pem -out root-ca.cert.crt + +openssl verify -verbose -CAfile root-ca.cert.pem \ + root-ca.cert.pem + +openssl ca -gencrl -cert root-ca.cert.pem \ + -out root-ca.cert.crl.pem -passin file:pass.txt +openssl crl -in root-ca.cert.crl.pem -outform DER -out root-ca.cert.crl + +popd #root-ca + +# +# Create intermediate certificate +# +mkdir intermed-ca +pushd intermed-ca + +mkdir certreqs certs crl newcerts private +touch intermed-ca.index +echo 00 > intermed-ca.crlnum +echo 2000 > intermed-ca.serial +echo "abcdef" > pass.txt + +cp "${EKCADIR}/intermed-ca.cnf" ./ +export OPENSSL_CONF=./intermed-ca.cnf + +# Adapt CRT URL to current test directory +${SED_CMD} "s|ROOTCRT|$ROOT_URL|g" $OPENSSL_CONF + +openssl req -new -out intermed-ca.req.pem -passout file:pass.txt + +openssl rsa -inform PEM -in private/intermed-ca.key.pem \ + -outform DER -out private/intermed-ca.key.der -passin file:pass.txt + +cp intermed-ca.req.pem \ + ../root-ca/certreqs/ + +INTERMED_URL="file:$INTERMEDCRT" +${SED_CMD} "s|INTERMEDCRT|$INTERMED_URL|g" $OPENSSL_CONF + +pushd ../root-ca +export OPENSSL_CONF=./root-ca.cnf + +openssl ca \ + -in certreqs/intermed-ca.req.pem \ + -out certs/intermed-ca.cert.pem \ + -extensions intermed-ca_ext \ + -startdate `date ${DATE_FMT_BEFORE}` \ + -enddate `date ${DATE_FMT_AFTER}` \ + -passin file:pass.txt -batch + +openssl x509 -outform der -in certs/intermed-ca.cert.pem \ + -out certs/intermed-ca.cert.crt + +openssl verify -verbose -CAfile root-ca.cert.pem \ + certs/intermed-ca.cert.pem + +cp certs/intermed-ca.cert.pem \ + ../intermed-ca + +cp certs/intermed-ca.cert.crt \ + ../intermed-ca + +popd #root-ca + +export OPENSSL_CONF=./intermed-ca.cnf +openssl ca -gencrl -cert ../root-ca/certs/intermed-ca.cert.pem \ + -out intermed-ca.crl.pem -passin file:pass.txt +openssl crl -in intermed-ca.crl.pem -outform DER -out intermed-ca.crl + +popd #intermed-ca diff --git a/script/fint-log-compiler.sh b/script/fint-log-compiler.sh index 841ffe111..d6cb30e6d 100755 --- a/script/fint-log-compiler.sh +++ b/script/fint-log-compiler.sh @@ -42,109 +42,8 @@ echo "TPM20TEST_TCTI=${TPM20TEST_TCTI}" while true; do -if [[ ${TPM20TEST_TCTI} != *device* ]]; then - env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_startup - if [ $? -ne 0 ]; then - echo "TPM_StartUp failed" - ret=99 - break - fi -else - env TPM20TEST_TCTI=${TPM20TEST_TCTI} \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_transientempty - if [ $? -ne 0 ]; then - echo "TPM transient area not empty => skipping" - ret=99 - break - fi -fi - -# Certificate generation for simulator tests -if [[ ${TPM20TEST_TCTI} != *device* ]]; then - EKPUB_FILE=${TEST_BIN}_ekpub.pem - EKCERT_FILE=${TEST_BIN}_ekcert.crt - EKCERT_PEM_FILE=${TEST_BIN}_ekcert.pem - - env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_getek ${EKPUB_FILE} - if [ $? -ne 0 ]; then - echo "TPM_getek failed" - ret=99 - break - fi - - EKECCPUB_FILE=${TEST_BIN}_ekeccpub.pem - EKECCCERT_FILE=${TEST_BIN}_ekecccert.crt - EKECCCERT_PEM_FILE=${TEST_BIN}_ekecccert.pem - - env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_getek_ecc ${EKECCPUB_FILE} - if [ $? -ne 0 ]; then - echo "TPM_getek_ecc failed" - ret=99 - break - fi - - INTERMEDCA_FILE=${TEST_BIN}_intermedecc-ca - ROOTCA_FILE=${TEST_BIN}_root-ca - - SCRIPTDIR="$(dirname $(realpath $0))/" - ${SCRIPTDIR}/ekca/create_ca.sh "${EKPUB_FILE}" "${EKECCPUB_FILE}" "${EKCERT_FILE}" \ - "${EKECCCERT_FILE}" "${INTERMEDCA_FILE}" "${ROOTCA_FILE}" >${TEST_BIN}_ca.log 2>&1 - if [ $? -ne 0 ]; then - echo "ek-cert ca failed" - ret=99 - break - fi - - # Determine the fingerprint of the RSA EK public. - FINGERPRINT=$(openssl pkey -pubin -inform PEM -in ${EKPUB_FILE} -outform DER | shasum -a 256 | cut -f 1 -d ' ') - export FAPI_TEST_FINGERPRINT=" { \"hashAlg\" : \"sha256\", \"digest\" : \"${FINGERPRINT}\" }" - openssl x509 -inform DER -in ${EKCERT_FILE} -outform PEM -out ${EKCERT_PEM_FILE} - export FAPI_TEST_CERTIFICATE="file:${EKCERT_PEM_FILE}" - - # Determine the fingerprint of the RSA EK public. - FINGERPRINT_ECC=$(openssl pkey -pubin -inform PEM -in ${EKECCPUB_FILE} -outform DER | shasum -a 256 | cut -f 1 -d ' ') - export FAPI_TEST_FINGERPRINT_ECC=" { \"hashAlg\" : \"sha256\", \"digest\" : \"${FINGERPRINT_ECC}\" }" - openssl x509 -inform DER -in ${EKECCCERT_FILE} -outform PEM -out ${EKECCCERT_PEM_FILE} - export FAPI_TEST_CERTIFICATE_ECC="file:${EKECCCERT_PEM_FILE}" - - cat $EKCERT_FILE | \ - env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_writeekcert 1C00002 - if [ $? -ne 0 ]; then - echo "TPM_writeekcert failed" - ret=99 - break - fi - - cat $EKECCCERT_FILE | \ - env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_writeekcert 1C0000A - if [ $? -ne 0 ]; then - echo "TPM_writeekcert failed" - ret=99 - fi -fi # certificate generation - -TPMSTATE_FILE1=${TEST_BIN}_state1 -TPMSTATE_FILE2=${TEST_BIN}_state2 - -env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>${TPMSTATE_FILE1} -if [ $? -ne 0 ]; then - echo "Error during dumpstate" - ret=99 - break -fi +INTERMEDCA_FILE=ca/intermed-ca/intermed-ca.cert +ROOTCA_FILE=ca/root-ca/root-ca.cert echo "Execute the test script" if [[ ${TPM20TEST_TCTI} == *device* ]]; then @@ -154,34 +53,21 @@ if [[ ${TPM20TEST_TCTI} == *device* ]]; then G_MESSAGES_DEBUG=all ${@: -1} else # Run test with generated certificate. + + EKECCCERT_PEM_FILE=${TEST_BIN}_ekecccert.pem + export FAPI_TEST_CERTIFICATE_ECC="${EKECCCERT_PEM_FILE}" + EKCERT_PEM_FILE=${TEST_BIN}_ekcert.pem + export FAPI_TEST_CERTIFICATE="${EKCERT_PEM_FILE}" + env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ FAPI_TEST_ROOT_CERT=${ROOTCA_FILE}.pem \ + FAPI_TEST_INT_CERT=${INTERMEDCA_FILE}.pem \ G_MESSAGES_DEBUG=all ${@: -1} fi ret=$? echo "Script returned $ret" -#We check the state before a reboot to see if transients and NV were chagned. -env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \ - TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \ - G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>${TPMSTATE_FILE2} -if [ $? -ne 0 ]; then - echo "Error during dumpstate" - ret=99 - break -fi - -if [ "$(cat ${TPMSTATE_FILE1})" != "$(cat ${TPMSTATE_FILE2})" ]; then - echo "TPM changed state during test" - echo "State before ($TPMSTATE_FILE1):" - cat ${TPMSTATE_FILE1} - echo "State after ($TPMSTATE_FILE2):" - cat ${TPMSTATE_FILE2} - ret=1 - break -fi - #TODO: Add a tpm-restart/reboot here break diff --git a/src/tss2-fapi/api/Fapi_Provision.c b/src/tss2-fapi/api/Fapi_Provision.c index d1a9a626a..823ce2730 100644 --- a/src/tss2-fapi/api/Fapi_Provision.c +++ b/src/tss2-fapi/api/Fapi_Provision.c @@ -37,6 +37,9 @@ #define ECC_EK_TEMPLATE_NV_INDEX 0x01c0000c #define ECC_SM2_EK_TEMPLATE_NV_INDEX 0x01c0001b +#define FAPI_TEST_ROOT_CERT "./ca/root-ca/root-ca.cert.pem" +#define FAPI_TEST_INT_CERT "./ca/intermed-ca/intermed-ca.cert.pem" + /** Error cleanup of provisioning * * The profile directory will be deleted. @@ -891,6 +894,11 @@ Fapi_Provision_Finish(FAPI_CONTEXT *context) #ifdef SELF_GENERATED_CERTIFICATE #pragma message ( "*** Allow self generated certifcate ***" ) root_ca_file = getenv("FAPI_TEST_ROOT_CERT"); + if (!root_ca_file && ifapi_io_path_exists(FAPI_TEST_ROOT_CERT)) { + root_ca_file = FAPI_TEST_ROOT_CERT; + } else { + LOG_WARNING("Environment variable " FAPI_TEST_ROOT_CERT " not set."); + } #endif if (!root_ca_file) { context->state = PROVISION_EK_CHECK_CERT; @@ -917,6 +925,11 @@ Fapi_Provision_Finish(FAPI_CONTEXT *context) #ifdef SELF_GENERATED_CERTIFICATE #pragma message ( "*** Allow self generated certifcate ***" ) int_ca_file = getenv("FAPI_TEST_INT_CERT"); + if (!int_ca_file && ifapi_io_path_exists(FAPI_TEST_INT_CERT)) { + int_ca_file = FAPI_TEST_INT_CERT; + } else { + LOG_WARNING("Environment variable " FAPI_TEST_INT_CERT " not set."); + } #endif if (!int_ca_file) { context->state = PROVISION_EK_CHECK_CERT; diff --git a/test/helper/tpm_dumpstate.c b/test/helper/tpm_dumpstate.c deleted file mode 100644 index ca6ece24a..000000000 --- a/test/helper/tpm_dumpstate.c +++ /dev/null @@ -1,112 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "tss2_tctildr.h" -#include "tss2_sys.h" -#include "tss2_mu.h" - -#define LOGMODULE test -#include "util/log.h" -#include "test-common.h" - -#define TAB_SIZE(x) (sizeof(x)/sizeof(x[0])) - -/* NOTE: CAP_PCRS and CAP_HANDLES->HR_PCR do not change until a reboot is - triggered. This should be improved if an approach is found. */ -struct { - TPM2_CAP cap; - UINT32 prop; - UINT32 count; -} capabilities[] = { - { TPM2_CAP_PCRS, 0, 10 }, - { TPM2_CAP_HANDLES, TPM2_HR_PCR, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_HMAC_SESSION, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_POLICY_SESSION, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_TRANSIENT, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_PERSISTENT, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_NV_INDEX, TPM2_MAX_CAP_HANDLES }, -}; - -int -main (int argc, char *argv[]) -{ - TSS2_RC rc; - TSS2_ABI_VERSION abi_version = { - .tssCreator = 1, - .tssFamily = 2, - .tssLevel = 1, - .tssVersion = 108, - }; - TSS2_TCTI_CONTEXT *tcti_context; - TSS2_SYS_CONTEXT *sys_context; - size_t size; - char *name_conf; - - name_conf = getenv(ENV_TCTI); - if (!name_conf) { - LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI); - return 1; - } - - rc = Tss2_TctiLdr_Initialize(name_conf, &tcti_context); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Error loading TCTI: %s", name_conf); - return 1; - } - - size = Tss2_Sys_GetContextSize(0); - sys_context = (TSS2_SYS_CONTEXT *) calloc(1, size); - if (sys_context == NULL) { - LOG_ERROR("Failed to allocate 0x%zx bytes for the SYS context\n", size); - return 1; - } - rc = Tss2_Sys_Initialize(sys_context, size, tcti_context, &abi_version); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Failed to initialize SYS context: 0x%x\n", rc); - free(sys_context); - return 1; - } - - for (size_t i = 0; i < TAB_SIZE(capabilities); i++) { - TPMS_CAPABILITY_DATA caps; - uint8_t buffer[sizeof(caps)]; - size_t off = 0; - - rc = Tss2_Sys_GetCapability(sys_context, NULL, capabilities[i].cap, - capabilities[i].prop, - capabilities[i].count, NULL, - &caps, NULL); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM GetCapabilities FAILED: 0x%"PRIx32, rc); - exit(1); - } - - rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&caps, &buffer[off], - sizeof(buffer) - off - 1, - &off); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Marshaling FAILED: 0x%"PRIx32, rc); - exit(1); - } - - buffer[off++] = '\0'; - - printf("cap%zi: ", i); - for (size_t j = 0; j < off; j++) - printf("%02"PRIx8, buffer[j]); - printf("\n"); - } - - Tss2_Sys_Finalize(sys_context); - free(sys_context); - Tss2_TctiLdr_Finalize(&tcti_context); - - return 0; -} diff --git a/test/helper/tpm_getek.c b/test/helper/tpm_getek.c deleted file mode 100644 index 892c37707..000000000 --- a/test/helper/tpm_getek.c +++ /dev/null @@ -1,203 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x30000000 -#include -#else -#include -#include -#include -#endif - -#include "tss2_tctildr.h" -#include "tss2_sys.h" -#include "tss2_mu.h" - -#define LOGMODULE test -#include "util/log.h" -#include "test-common.h" - -int -main (int argc, char *argv[]) -{ - TSS2_RC rc; - TSS2_ABI_VERSION abi_version = { - .tssCreator = 1, - .tssFamily = 2, - .tssLevel = 1, - .tssVersion = 108, - }; - TSS2_TCTI_CONTEXT *tcti_context; - TSS2_SYS_CONTEXT *sys_context; - TSS2L_SYS_AUTH_COMMAND auth_cmd = { - .auths = {{ .sessionHandle = TPM2_RH_PW }}, - .count = 1 - }; - TPM2B_SENSITIVE_CREATE in_sensitive = { 0 }; - TPM2B_PUBLIC in_public = { - .publicArea = { - .type = TPM2_ALG_RSA, - .nameAlg = TPM2_ALG_SHA256, - .objectAttributes = ( - TPMA_OBJECT_FIXEDTPM | - TPMA_OBJECT_FIXEDPARENT | - TPMA_OBJECT_SENSITIVEDATAORIGIN | - TPMA_OBJECT_ADMINWITHPOLICY | - TPMA_OBJECT_RESTRICTED | - TPMA_OBJECT_DECRYPT - ), - .authPolicy = { - .size = 32, - .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, - 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D, - 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52, - 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64, - 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, - 0x69, 0xAA, - }, - .parameters.rsaDetail = { - .symmetric = { - .algorithm = TPM2_ALG_AES, - .keyBits.aes = 128, - .mode.aes = TPM2_ALG_CFB, - }, - .scheme = { - .scheme = TPM2_ALG_NULL, - }, - .keyBits = 2048, - .exponent = 0, - }, - .unique.rsa = { - .size = 256, - .buffer = {0}, - } - } - }; - TPML_PCR_SELECTION creation_pcr = { 0 }; - TPM2_HANDLE handle; - TPM2B_PUBLIC out_public = { 0 }; - TSS2L_SYS_AUTH_RESPONSE auth_rsp = { - .count = 0 - }; - size_t size; - char *name_conf; - - name_conf = getenv(ENV_TCTI); - if (!name_conf) { - LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI); - return 1; - } - - rc = Tss2_TctiLdr_Initialize(name_conf, &tcti_context); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Error loading TCTI: %s", name_conf); - return 1; - } - - size = Tss2_Sys_GetContextSize(0); - sys_context = (TSS2_SYS_CONTEXT *) calloc(1, size); - if (sys_context == NULL) { - LOG_ERROR("Failed to allocate 0x%zx bytes for the SYS context\n", size); - return 1; - } - rc = Tss2_Sys_Initialize(sys_context, size, tcti_context, &abi_version); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Failed to initialize SYS context: 0x%x\n", rc); - free(sys_context); - return 1; - } - - /* Generate the EK key */ - - rc = Tss2_Sys_CreatePrimary(sys_context, TPM2_RH_ENDORSEMENT, &auth_cmd, - &in_sensitive, &in_public, NULL, &creation_pcr, - &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM CreatePrimary FAILED: 0x%"PRIx32, rc); - exit(1); - } - - rc = Tss2_Sys_FlushContext(sys_context, handle); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM FlushContext FAILED: 0x%"PRIx32, rc); - exit(1); - } - - Tss2_Sys_Finalize(sys_context); - free(sys_context); - Tss2_TctiLdr_Finalize(&tcti_context); - - /* Convert the key from out_public to PEM */ - - EVP_PKEY *evp = NULL; - BIO *bio; - FILE *out = NULL; - - if (argc == 2) { - out = fopen(argv[1], "w"); - if (!out) { - LOG_ERROR("Can not open file %s", argv[1]); - exit(1); - } - bio = BIO_new_fp(out, BIO_NOCLOSE); - } - else - bio = BIO_new_fp(stdout, BIO_NOCLOSE); - - BIGNUM *n = BN_bin2bn(out_public.publicArea.unique.rsa.buffer, - out_public.publicArea.unique.rsa.size, NULL); - uint32_t exp; - if (out_public.publicArea.parameters.rsaDetail.exponent == 0) - exp = 65537; - else - exp = out_public.publicArea.parameters.rsaDetail.exponent; - -#if OPENSSL_VERSION_NUMBER < 0x30000000 - BIGNUM *e = BN_new(); - BN_set_word(e, exp); - - RSA *rsa = RSA_new(); - RSA_set0_key(rsa, n, e, NULL); - n = NULL; - e = NULL; - - evp = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(evp, rsa); -#else /* OPENSSL_VERSION_NUMBER < 0x30000000 */ - OSSL_PARAM_BLD *build = OSSL_PARAM_BLD_new(); - OSSL_PARAM_BLD_push_BN(build, OSSL_PKEY_PARAM_RSA_N, n); - OSSL_PARAM_BLD_push_uint32(build, OSSL_PKEY_PARAM_RSA_E, exp); - OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(build); - - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - EVP_PKEY_fromdata_init(ctx); - EVP_PKEY_fromdata(ctx, &evp, EVP_PKEY_PUBLIC_KEY, params); -#endif /* OPENSSL_VERSION_NUMBER < 0x30000000 */ - - if (!PEM_write_bio_PUBKEY(bio, evp)) { - LOG_ERROR("PEM_write failed"); - exit(1); - } - - EVP_PKEY_free(evp); -#if OPENSSL_VERSION_NUMBER < 0x30000000 - /* ownership was taken by the EVP_PKEY */ -#else - EVP_PKEY_CTX_free(ctx); - OSSL_PARAM_free(params); - OSSL_PARAM_BLD_free(build); -#endif - BN_free(n); - BIO_free(bio); - fclose(out); - - return 0; -} diff --git a/test/helper/tpm_getek_ecc.c b/test/helper/tpm_getek_ecc.c deleted file mode 100644 index 78da6527b..000000000 --- a/test/helper/tpm_getek_ecc.c +++ /dev/null @@ -1,253 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x30000000 -#include -#else -#include -#include -#include -#endif -#include - -#include "tss2_tctildr.h" -#include "tss2_sys.h" -#include "tss2_mu.h" - -#define LOGMODULE test -#include "util/log.h" -#include "test-common.h" - -void handleErrors(void) -{ - unsigned long errCode; - - printf("An error occurred\n"); - while((errCode = ERR_get_error())) - { - char *err = ERR_error_string(errCode, NULL); - printf("%s\n", err); - } - abort(); -} - -int -main (int argc, char *argv[]) -{ - TSS2_RC rc; - TSS2_ABI_VERSION abi_version = { - .tssCreator = 1, - .tssFamily = 2, - .tssLevel = 1, - .tssVersion = 108, - }; - TSS2_TCTI_CONTEXT *tcti_context; - TSS2_SYS_CONTEXT *sys_context; - TSS2L_SYS_AUTH_COMMAND auth_cmd = { - .auths = {{ .sessionHandle = TPM2_RH_PW }}, - .count = 1 - }; - TPM2B_SENSITIVE_CREATE in_sensitive = { 0 }; - TPM2B_PUBLIC in_public = { - .publicArea = { - .type = TPM2_ALG_ECC, - .nameAlg = TPM2_ALG_SHA256, - .objectAttributes = ( - TPMA_OBJECT_FIXEDTPM | - TPMA_OBJECT_FIXEDPARENT | - TPMA_OBJECT_SENSITIVEDATAORIGIN | - TPMA_OBJECT_ADMINWITHPOLICY | - TPMA_OBJECT_RESTRICTED | - TPMA_OBJECT_DECRYPT - ), - .authPolicy = { - .size = 32, - .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, - 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D, - 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52, - 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64, - 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, - 0x69, 0xAA, - }, - .parameters.eccDetail = { - .symmetric = { - .algorithm = TPM2_ALG_AES, - .keyBits.aes = 128, - .mode.aes = TPM2_ALG_CFB, - }, - .scheme = { - .scheme = TPM2_ALG_NULL, - .details = { 0 } - }, - .curveID = TPM2_ECC_NIST_P256, - .kdf = {.scheme = TPM2_ALG_NULL, - .details = { 0 } - } - }, - .unique.ecc = { - .x = {.size = 32,.buffer = { 0 }}, - .y = {.size = 32,.buffer = { 0 }} - } - } - }; - TPML_PCR_SELECTION creation_pcr = { 0 }; - TPM2_HANDLE handle; - TPM2B_PUBLIC out_public = { 0 }; - TSS2L_SYS_AUTH_RESPONSE auth_rsp = { - .count = 0 - }; - size_t size; - char *name_conf; - - name_conf = getenv(ENV_TCTI); - if (!name_conf) { - LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI); - return 1; - } - - rc = Tss2_TctiLdr_Initialize(name_conf, &tcti_context); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Error loading TCTI: %s", name_conf); - return 1; - } - - size = Tss2_Sys_GetContextSize(0); - sys_context = (TSS2_SYS_CONTEXT *) calloc(1, size); - if (sys_context == NULL) { - LOG_ERROR("Failed to allocate 0x%zx bytes for the SYS context\n", size); - return 1; - } - rc = Tss2_Sys_Initialize(sys_context, size, tcti_context, &abi_version); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Failed to initialize SYS context: 0x%x\n", rc); - free(sys_context); - return 1; - } - - /* Generate the EK key */ - - rc = Tss2_Sys_CreatePrimary(sys_context, TPM2_RH_ENDORSEMENT, &auth_cmd, - &in_sensitive, &in_public, NULL, &creation_pcr, - &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM CreatePrimary FAILED: 0x%"PRIx32, rc); - exit(1); - } - - rc = Tss2_Sys_FlushContext(sys_context, handle); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM FlushContext FAILED: 0x%"PRIx32, rc); - exit(1); - } - - Tss2_Sys_Finalize(sys_context); - free(sys_context); - Tss2_TctiLdr_Finalize(&tcti_context); - - /* Convert the key from out_public to PEM */ - - EVP_PKEY *evp = NULL; - BIGNUM *x = NULL, *y = NULL; - BIO *bio; - FILE *out = NULL; - int nid; - - if (argc == 2) { - out = fopen(argv[1], "w"); - if (!out) { - LOG_ERROR("Can not open file %s", argv[1]); - exit(1); - } - bio = BIO_new_fp(out, BIO_NOCLOSE); - } - else - bio = BIO_new_fp(stdout, BIO_NOCLOSE); - - nid = EC_curve_nist2nid("P-256"); - EC_GROUP *ecgroup = EC_GROUP_new_by_curve_name(nid); - - /* Set the ECC parameters in the OpenSSL key */ - x = BN_bin2bn(out_public.publicArea.unique.ecc.x.buffer, - out_public.publicArea.unique.ecc.x.size, NULL); - - y = BN_bin2bn(out_public.publicArea.unique.ecc.y.buffer, - out_public.publicArea.unique.ecc.y.size, NULL); - - if (!x || !y) { - exit(1); - } - - EC_POINT *point = EC_POINT_new(ecgroup); -#if OPENSSL_VERSION_NUMBER < 0x10101000L - EC_POINT_set_affine_coordinates_GFp(ecgroup, point, x, y, NULL); -#else - EC_POINT_set_affine_coordinates(ecgroup, point, x, y, NULL); -#endif - -#if OPENSSL_VERSION_NUMBER < 0x30000000 - EC_KEY *ecc_key = EC_KEY_new(); - if (!EC_KEY_set_group(ecc_key, ecgroup)) - exit(1); - - if (!EC_KEY_set_public_key(ecc_key, point)) { - exit(1); - } - - evp = EVP_PKEY_new(); - if (!EVP_PKEY_assign_EC_KEY(evp, ecc_key)) { - handleErrors(); - LOG_ERROR("PEM_write failed"); - exit(1); - } -#else /* OPENSSL_VERSION_NUMBER < 0x30000000 */ - unsigned char *puboct = NULL; - size_t bsize; - - bsize = EC_POINT_point2buf(ecgroup, point, POINT_CONVERSION_UNCOMPRESSED, - &puboct, NULL); - - OSSL_PARAM_BLD *build = OSSL_PARAM_BLD_new(); - OSSL_PARAM_BLD_push_utf8_string(build, OSSL_PKEY_PARAM_GROUP_NAME, - (char *)OBJ_nid2sn(nid), 0); - OSSL_PARAM_BLD_push_octet_string(build, OSSL_PKEY_PARAM_PUB_KEY, - puboct, bsize); - OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(build); - - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); - EVP_PKEY_fromdata_init(ctx); - EVP_PKEY_fromdata(ctx, &evp, EVP_PKEY_PUBLIC_KEY, params); -#endif /* OPENSSL_VERSION_NUMBER < 0x30000000 */ - - if (!PEM_write_bio_PUBKEY(bio, evp)) { - handleErrors(); - LOG_ERROR("PEM_write failed"); - exit(1); - } - - EVP_PKEY_free(evp); -#if OPENSSL_VERSION_NUMBER < 0x30000000 - /* ownership was taken by the EVP_PKEY */ -#else - EVP_PKEY_CTX_free(ctx); - OSSL_PARAM_free(params); - OSSL_PARAM_BLD_free(build); - OPENSSL_free(puboct); -#endif - EC_POINT_free(point); - EC_GROUP_free(ecgroup); - BN_free(y); - BN_free(x); - BIO_free(bio); - fclose(out); - - return 0; -} diff --git a/test/helper/tpm_startup.c b/test/helper/tpm_startup.c deleted file mode 100644 index d12504c5a..000000000 --- a/test/helper/tpm_startup.c +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "tss2_tctildr.h" -#include "tss2_sys.h" - -#define LOGMODULE test -#include "util/log.h" -#include "test-common.h" - -int -main (int argc, char *argv[]) -{ - TSS2_RC rc; - TSS2_ABI_VERSION abi_version = { - .tssCreator = 1, - .tssFamily = 2, - .tssLevel = 1, - .tssVersion = 108, - }; - TSS2_TCTI_CONTEXT *tcti_context; - TSS2_SYS_CONTEXT *sys_context; - size_t size; - char *name_conf; - - name_conf = getenv(ENV_TCTI); - if (!name_conf) { - LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI); - return 1; - } - - rc = Tss2_TctiLdr_Initialize(name_conf, &tcti_context); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Error loading TCTI: %s", name_conf); - return 1; - } - - size = Tss2_Sys_GetContextSize(0); - sys_context = (TSS2_SYS_CONTEXT *) calloc(1, size); - if (sys_context == NULL) { - LOG_ERROR("Failed to allocate 0x%zx bytes for the SYS context\n", size); - return 1; - } - rc = Tss2_Sys_Initialize(sys_context, size, tcti_context, &abi_version); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Failed to initialize SYS context: 0x%x\n", rc); - free(sys_context); - return 1; - } - - rc = Tss2_Sys_Startup(sys_context, TPM2_SU_CLEAR); - if (rc != TSS2_RC_SUCCESS && rc != TPM2_RC_INITIALIZE) { - LOG_ERROR("TPM Startup FAILED! Response Code : 0x%x", rc); - exit(1); - } - - Tss2_Sys_Finalize(sys_context); - free(sys_context); - Tss2_TctiLdr_Finalize(&tcti_context); - - return 0; -} diff --git a/test/helper/tpm_transientempty.c b/test/helper/tpm_transientempty.c deleted file mode 100644 index fa665512a..000000000 --- a/test/helper/tpm_transientempty.c +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "tss2_tctildr.h" -#include "tss2_sys.h" - -#define LOGMODULE test -#include "util/log.h" -#include "test-common.h" - -#define TAB_SIZE(x) (sizeof(x)/sizeof(x[0])) - -int -main (int argc, char *argv[]) -{ - TSS2_RC rc; - TSS2_ABI_VERSION abi_version = { - .tssCreator = 1, - .tssFamily = 2, - .tssLevel = 1, - .tssVersion = 108, - }; - TSS2_TCTI_CONTEXT *tcti_context; - TSS2_SYS_CONTEXT *sys_context; - TPMS_CAPABILITY_DATA caps; - size_t size; - char *name_conf; - - name_conf = getenv(ENV_TCTI); - if (!name_conf) { - LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI); - return 1; - } - - rc = Tss2_TctiLdr_Initialize(name_conf, &tcti_context); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Error loading TCTI: %s", name_conf); - return 1; - } - - size = Tss2_Sys_GetContextSize(0); - sys_context = (TSS2_SYS_CONTEXT *) calloc(1, size); - if (sys_context == NULL) { - LOG_ERROR("Failed to allocate 0x%zx bytes for the SYS context\n", size); - return 1; - } - rc = Tss2_Sys_Initialize(sys_context, size, tcti_context, &abi_version); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Failed to initialize SYS context: 0x%x\n", rc); - free(sys_context); - return 1; - } - - rc = Tss2_Sys_GetCapability(sys_context, NULL, TPM2_CAP_HANDLES, - TPM2_HR_TRANSIENT, - TAB_SIZE(caps.data.handles.handle), NULL, - &caps, NULL); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM GetCapabilities FAILED! Response Code : 0x%"PRIx32, rc); - exit(1); - } - - Tss2_Sys_Finalize(sys_context); - free(sys_context); - Tss2_TctiLdr_Finalize(&tcti_context); - - if (caps.data.handles.count) { - LOG_ERROR("TPM contains transient entries"); - for (UINT32 i = 0; i < caps.data.handles.count; i++) - LOG_ERROR("Handle %"PRIx32, caps.data.handles.handle[i]); - return 1; - } - - return 0; -} diff --git a/test/helper/tpm_writeekcert.c b/test/helper/tpm_writeekcert.c deleted file mode 100644 index fc1565658..000000000 --- a/test/helper/tpm_writeekcert.c +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "tss2_tctildr.h" -#include "tss2_sys.h" -#include "tss2_mu.h" - -#define LOGMODULE test -#include "util/log.h" -#include "test-common.h" - -#define TAB_SIZE(x) (sizeof(x)/sizeof(x[0])) - -/* NOTE: CAP_PCRS and CAP_HANDLES->HR_PCR do not change until a reboot is - triggered. This should be improved if an approach is found. */ -struct { - TPM2_CAP cap; - UINT32 prop; - UINT32 count; -} capabilities[] = { - { TPM2_CAP_PCRS, 0, 10 }, - { TPM2_CAP_HANDLES, TPM2_HR_PCR, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_HMAC_SESSION, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_POLICY_SESSION, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_TRANSIENT, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_PERSISTENT, TPM2_MAX_CAP_HANDLES }, - { TPM2_CAP_HANDLES, TPM2_HR_NV_INDEX, TPM2_MAX_CAP_HANDLES }, -}; - -int -main (int argc, char *argv[]) -{ - TSS2_RC rc; - TSS2_ABI_VERSION abi_version = { - .tssCreator = 1, - .tssFamily = 2, - .tssLevel = 1, - .tssVersion = 108, - }; - TSS2_TCTI_CONTEXT *tcti_context; - TSS2_SYS_CONTEXT *sys_context; - TSS2L_SYS_AUTH_COMMAND auth_cmd = { - .auths = {{ .sessionHandle = TPM2_RH_PW }}, - .count = 1 - }; - TPMI_RH_NV_INDEX nvIndex; - size_t size; - char *name_conf; - - if (argv[1]) - nvIndex = strtol(argv[1], NULL, 16); - else - nvIndex = 0x01c00002; - - TPM2B_AUTH nv_auth = { 0 }; - TPM2B_NV_PUBLIC public_info = { - .nvPublic = { - .nameAlg = TPM2_ALG_SHA1, - .attributes = TPMA_NV_PPWRITE | TPMA_NV_AUTHREAD | TPMA_NV_OWNERREAD | - TPMA_NV_PLATFORMCREATE | TPMA_NV_NO_DA, - .dataSize = 0, - .nvIndex = nvIndex, - }, - }; - - TSS2L_SYS_AUTH_RESPONSE auth_rsp = { - .count = 0 - }; - TPM2B_MAX_NV_BUFFER buf1 = { 0 }; - TPM2B_MAX_NV_BUFFER buf2 = { 0 }; - - buf1.size += fread(&buf1.buffer[buf1.size], sizeof(buf1.buffer[0]), - sizeof(buf1.buffer) - buf1.size, stdin); - if (buf1.size >= sizeof(buf1.buffer)) { - LOG_ERROR("input to large"); - exit(1); - } - - name_conf = getenv(ENV_TCTI); - if (!name_conf) { - LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI); - return 1; - } - - rc = Tss2_TctiLdr_Initialize(name_conf, &tcti_context); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Error loading TCTI: %s", name_conf); - return 1; - } - - size = Tss2_Sys_GetContextSize(0); - sys_context = (TSS2_SYS_CONTEXT *) calloc(1, size); - if (sys_context == NULL) { - LOG_ERROR("Failed to allocate 0x%zx bytes for the SYS context\n", size); - return 1; - } - rc = Tss2_Sys_Initialize(sys_context, size, tcti_context, &abi_version); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("Failed to initialize SYS context: 0x%x\n", rc); - free(sys_context); - return 1; - } - - /* First make sure that not EK certificate is currently loaded */ - LOG_WARNING("Cert input size is %"PRIu16, buf1.size); - public_info.nvPublic.dataSize = buf1.size; - - LOG_WARNING("Define NV cert with nv index: %x", public_info.nvPublic.nvIndex); - - rc = Tss2_Sys_NV_DefineSpace(sys_context, TPM2_RH_PLATFORM, &auth_cmd, - &nv_auth, &public_info, &auth_rsp); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM NV DefineSpace FAILED: 0x%"PRIx32, rc); - exit(1); - } - - /* Split the input buffer into 2 chunks */ - buf2.size = buf1.size; - buf1.size /= 2; - buf2.size -= buf1.size; - memcpy(&buf2.buffer[0], &buf1.buffer[buf1.size], buf2.size); - - rc = Tss2_Sys_NV_Write(sys_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd, - &buf1, 0, &auth_rsp); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM NV Write FAILED: 0x%"PRIx32, rc); - exit(1); - } - - rc = Tss2_Sys_NV_Write(sys_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd, - &buf2, buf1.size, &auth_rsp); - if (rc != TSS2_RC_SUCCESS) { - LOG_ERROR("TPM NV Write FAILED: 0x%"PRIx32, rc); - exit(1); - } - - Tss2_Sys_Finalize(sys_context); - free(sys_context); - Tss2_TctiLdr_Finalize(&tcti_context); - - return 0; -} diff --git a/test/integration/main-fapi.c b/test/integration/main-fapi.c index 9d6d8a037..12c3ce0c3 100644 --- a/test/integration/main-fapi.c +++ b/test/integration/main-fapi.c @@ -14,12 +14,25 @@ #include #include #include -#include + +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x30000000L +#include +#else +#include +#include +#include +#endif +#include +#include #include "tss2_esys.h" #include "tss2_fapi.h" #include "test-fapi.h" #include "fapi_int.h" +#include "tss2_rc.h" #define LOGDEFAULT LOGLEVEL_INFO #define LOGMODULE test @@ -28,6 +41,30 @@ #include "test-common.h" +#if OPENSSL_VERSION_NUMBER >= 0x10101000L +#define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \ + EC_POINT_set_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy) + +#define EC_POINT_get_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \ + EC_POINT_get_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy) + +#else +#define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \ + EC_POINT_set_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy) + +#define EC_POINT_get_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \ + EC_POINT_get_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy) +#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */ + +#define SYS_CALL(rc,fu,...) \ + do { \ + rc = fu(__VA_ARGS__); \ + } while (rc == TPM2_RC_YIELDED); \ + if (rc != TPM2_RC_SUCCESS) { \ + LOG_ERROR("%s FAILED: 0x%"PRIx32, #fu, rc); \ + return rc; \ + } + char *fapi_profile = NULL; TSS2_TEST_FAPI_CONTEXT *fapi_test_ctx = NULL; @@ -240,11 +277,11 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) #if defined(FAPI_TEST_EK_CERT_LESS) " \"ek_cert_less\": \"yes\",\n" #else - " \"ek_fingerprint\": %s,\n" + " \"ek_fingerprint\": { \"hashAlg\": \"sha256\", \"digest\": \"%s\" },\n" #endif "}\n", profile, tmpdir, tmpdir, tmpdir, - getenv("TPM20TEST_TCTI") + getenv(ENV_TCTI) #if !defined(FAPI_TEST_EK_CERT_LESS) , getenv("FAPI_TEST_FINGERPRINT") #endif @@ -261,11 +298,11 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) #if defined(FAPI_TEST_EK_CERT_LESS) " \"ek_cert_less\": \"yes\",\n" #else - " \"ek_cert_file\": \"%s\",\n" + " \"ek_cert_file\": \"file:%s\",\n" #endif "}\n", profile, tmpdir, tmpdir, tmpdir, - getenv("TPM20TEST_TCTI") + getenv(ENV_TCTI) #if !defined(FAPI_TEST_EK_CERT_LESS) , getenv("FAPI_TEST_CERTIFICATE") #endif @@ -282,11 +319,11 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) #if defined(FAPI_TEST_EK_CERT_LESS) " \"ek_cert_less\": \"yes\",\n" #else - " \"ek_fingerprint\": %s,\n" + " \"ek_fingerprint\": { \"hashAlg\": \"sha256\", \"digest\": \"%s\" },\n" #endif "}\n", profile, tmpdir, tmpdir, tmpdir, - getenv("TPM20TEST_TCTI") + getenv(ENV_TCTI) #if !defined(FAPI_TEST_EK_CERT_LESS) , getenv("FAPI_TEST_FINGERPRINT_ECC") #endif @@ -303,11 +340,11 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) #if defined(FAPI_TEST_EK_CERT_LESS) " \"ek_cert_less\": \"yes\",\n" #else - " \"ek_cert_file\": \"%s\",\n" + " \"ek_cert_file\": \"file:%s\",\n" #endif "}\n", profile, tmpdir, tmpdir, tmpdir, - getenv("TPM20TEST_TCTI") + getenv(ENV_TCTI) #if defined(FAPI_TEST_EK_CERT_LESS) #else , getenv("FAPI_TEST_CERTIFICATE_ECC") @@ -322,12 +359,12 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) " \"system_pcrs\" : [],\n" " \"log_dir\" : \"%s\",\n" " \"tcti\": \"%s\",\n" -#if defined(FAPI_TEST_EK_CERT_LESS) +#if defined(FAPI_TEST_EK_CERT_LESS) || defined(DLOPEN) " \"ek_cert_less\": \"yes\",\n" #endif "", profile, tmpdir, tmpdir, tmpdir, - getenv("TPM20TEST_TCTI")); + getenv(ENV_TCTI)); #endif /* FAPI_NONTPM */ if (size < 0) { @@ -432,12 +469,14 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) * Call FAPI ***********/ + rc = Fapi_Initialize(fapi_context, NULL); if (rc != TSS2_RC_SUCCESS) { LOG_ERROR("Esys_Initialize FAILED! Response Code : 0x%x", rc); ret = EXIT_FAILURE; goto error; } + fapi_test_ctx->fapi_ctx = *fapi_context; SAFE_FREE(config_env); SAFE_FREE(config); @@ -453,6 +492,848 @@ int init_fapi(char *profile, FAPI_CONTEXT **fapi_context) return ret; } +TSS2_RC +rsa_pub_from_tpm(const TPM2B_PUBLIC *tpmPublicKey, EVP_PKEY **evpPublicKey) +{ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *rsa = NULL; +#else + OSSL_PARAM_BLD *build = NULL; + OSSL_PARAM *params = NULL; + EVP_PKEY_CTX *ctx = NULL; +#endif + + /* Check for NULL parameters */ + return_if_null(tpmPublicKey, "tpmPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE); + return_if_null(evpPublicKey, "evpPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE); + + TSS2_RC r = TSS2_RC_SUCCESS; + /* Initialize the RSA parameters */ + BIGNUM *e = NULL; + BIGNUM *n = BN_bin2bn(tpmPublicKey->publicArea.unique.rsa.buffer, + tpmPublicKey->publicArea.unique.rsa.size, NULL); + if (!n) { + goto_error(r, TSS2_FAPI_RC_MEMORY, "Out of memory", error_cleanup); + } + + uint32_t exp; + if (tpmPublicKey->publicArea.parameters.rsaDetail.exponent == 0) + exp = 65537; + else + exp = tpmPublicKey->publicArea.parameters.rsaDetail.exponent; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if ((rsa = RSA_new()) == NULL) { + goto_error(r, TSS2_FAPI_RC_MEMORY, "Out of memory", error_cleanup); + } + + if ((e = BN_new()) == NULL) { + goto_error(r, TSS2_FAPI_RC_MEMORY, "Out of memory", error_cleanup); + } + if (1 != BN_set_word(e, exp)) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, + "Could not set exponent.", error_cleanup); + } + + if (!RSA_set0_key(rsa, n, e, NULL)) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, + "Could not set public key.", error_cleanup); + } + n = NULL; /* ownership transferred */ + e = NULL; + + *evpPublicKey = EVP_PKEY_new(); + goto_if_null2(*evpPublicKey, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, error_cleanup); + + /* Assign the parameters to the key */ + if (!EVP_PKEY_assign_RSA(*evpPublicKey, rsa)) { + EVP_PKEY_free(*evpPublicKey); + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Assign rsa key", + error_cleanup); + } + rsa = NULL; /* ownership transferred */ +error_cleanup: + OSSL_FREE(rsa, RSA); +#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ + if ((build = OSSL_PARAM_BLD_new()) == NULL + || !OSSL_PARAM_BLD_push_BN(build, OSSL_PKEY_PARAM_RSA_N, n) + || !OSSL_PARAM_BLD_push_uint32(build, OSSL_PKEY_PARAM_RSA_E, exp) + || (params = OSSL_PARAM_BLD_to_param(build)) == NULL) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Create rsa key parameters", + error_cleanup); + } + + if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL + || EVP_PKEY_fromdata_init(ctx) <= 0 + || EVP_PKEY_fromdata(ctx, evpPublicKey, EVP_PKEY_PUBLIC_KEY, params) <= 0) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Create rsa key", + error_cleanup); + } +error_cleanup: + OSSL_FREE(ctx, EVP_PKEY_CTX); + OSSL_FREE(params, OSSL_PARAM); + OSSL_FREE(build, OSSL_PARAM_BLD); +#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ + OSSL_FREE(e, BN); + OSSL_FREE(n, BN); + return r; +} + +TSS2_RC +ecc_pub_from_tpm(const TPM2B_PUBLIC *tpmPublicKey, EVP_PKEY **evpPublicKey) +{ + /* Check for NULL parameters */ + return_if_null(tpmPublicKey, "tpmPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE); + return_if_null(evpPublicKey, "evpPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE); + + TSS2_RC r = TSS2_RC_SUCCESS; + EC_GROUP *ecgroup = NULL; + int curveId; + BIGNUM *x = NULL, *y = NULL; + EC_POINT *ecPoint = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY *ecKey = NULL; +#else + OSSL_PARAM_BLD *build = NULL; + OSSL_PARAM *params = NULL; + EVP_PKEY_CTX *ctx = NULL; + unsigned char *puboct = NULL; + size_t bsize; +#endif + + /* Find the curve of the ECC key */ + switch (tpmPublicKey->publicArea.parameters.eccDetail.curveID) { + case TPM2_ECC_NIST_P192: + curveId = NID_X9_62_prime192v1; + break; + case TPM2_ECC_NIST_P224: + curveId = NID_secp224r1; + break; + case TPM2_ECC_NIST_P256: + curveId = NID_X9_62_prime256v1; + break; + case TPM2_ECC_NIST_P384: + curveId = NID_secp384r1; + break; + case TPM2_ECC_NIST_P521: + curveId = NID_secp521r1; + break; +#ifdef NID_sm2 + case TPM2_ECC_SM2_P256: + curveId = NID_sm2; + break; +#endif + default: + return_error(TSS2_FAPI_RC_BAD_VALUE, + "ECC curve not implemented."); + } + + /* Initialize the OpenSSL ECC key with its group */ + ecgroup = EC_GROUP_new_by_curve_name(curveId); + goto_if_null(ecgroup, "new EC group.", TSS2_FAPI_RC_GENERAL_FAILURE, + error_cleanup); + + /* Set the ECC parameters in the OpenSSL key */ + x = BN_bin2bn(tpmPublicKey->publicArea.unique.ecc.x.buffer, + tpmPublicKey->publicArea.unique.ecc.x.size, NULL); + + y = BN_bin2bn(tpmPublicKey->publicArea.unique.ecc.y.buffer, + tpmPublicKey->publicArea.unique.ecc.y.size, NULL); + + if (!x || !y) { + goto_error(r, TSS2_FAPI_RC_MEMORY, "Out of memory", error_cleanup); + } + + if ((ecPoint = EC_POINT_new(ecgroup)) == NULL + || !EC_POINT_set_affine_coordinates_tss(ecgroup, ecPoint, x, y, NULL)) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EC_POINT_set_affine_coordinates", + error_cleanup); + } + +#if OPENSSL_VERSION_NUMBER < 0x30000000 + ecKey = EC_KEY_new(); + return_if_null(ecKey, "Out of memory.", TSS2_FAPI_RC_MEMORY); + + if (!EC_KEY_set_group(ecKey, ecgroup)) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EC_KEY_set_group", + error_cleanup); + } + + if (!EC_KEY_set_public_key(ecKey, ecPoint)) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, + "EC_KEY_set_public_key", error_cleanup); + } + + *evpPublicKey = EVP_PKEY_new(); + goto_if_null2(*evpPublicKey, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, error_cleanup); + + if (!EVP_PKEY_assign_EC_KEY(*evpPublicKey, ecKey)) { + EVP_PKEY_free(*evpPublicKey); + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Assign ecc key", + error_cleanup); + } + ecKey = NULL; /* ownership transferred */ +error_cleanup: + OSSL_FREE(ecKey, EC_KEY); +#else + if ((build = OSSL_PARAM_BLD_new()) == NULL + || !OSSL_PARAM_BLD_push_utf8_string(build, OSSL_PKEY_PARAM_GROUP_NAME, + (char *)OBJ_nid2sn(curveId), 0) + || (bsize = EC_POINT_point2buf(ecgroup, ecPoint, + POINT_CONVERSION_COMPRESSED, + &puboct, NULL)) == 0 + || !OSSL_PARAM_BLD_push_octet_string(build, OSSL_PKEY_PARAM_PUB_KEY, + puboct, bsize) + || (params = OSSL_PARAM_BLD_to_param(build)) == NULL) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Create ecc key parameters", + error_cleanup); + } + + if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL + || EVP_PKEY_fromdata_init(ctx) <= 0 + || EVP_PKEY_fromdata(ctx, evpPublicKey, EVP_PKEY_PUBLIC_KEY, params) <= 0) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Create ecc key", + error_cleanup); + } +error_cleanup: + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(build); + OPENSSL_free(puboct); +#endif + OSSL_FREE(ecPoint, EC_POINT); + OSSL_FREE(ecgroup, EC_GROUP); + OSSL_FREE(y, BN); + OSSL_FREE(x, BN); + return r; +} + +TPM2_RC +get_rsa_ek_public(TSS2_SYS_CONTEXT *sys_context, EVP_PKEY **evp_pub) +{ + TSS2_RC rc; + TSS2L_SYS_AUTH_COMMAND auth_cmd = { + .auths = {{ .sessionHandle = TPM2_RH_PW }}, + .count = 1 + }; + TPM2B_SENSITIVE_CREATE in_sensitive = { 0 }; + TPM2B_PUBLIC in_public = { + .publicArea = { + .type = TPM2_ALG_RSA, + .nameAlg = TPM2_ALG_SHA256, + .objectAttributes = ( + TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN | + TPMA_OBJECT_ADMINWITHPOLICY | + TPMA_OBJECT_RESTRICTED | + TPMA_OBJECT_DECRYPT + ), + .authPolicy = { + .size = 32, + .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, + 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D, + 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52, + 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64, + 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, + 0x69, 0xAA, + }, + .parameters.rsaDetail = { + .symmetric = { + .algorithm = TPM2_ALG_AES, + .keyBits.aes = 128, + .mode.aes = TPM2_ALG_CFB, + }, + .scheme = { + .scheme = TPM2_ALG_NULL, + }, + .keyBits = 2048, + .exponent = 0, + }, + .unique.rsa = { + .size = 256, + .buffer = {0}, + } + } + }; + TPML_PCR_SELECTION creation_pcr = { 0 }; + TPM2_HANDLE handle; + TPM2B_PUBLIC out_public = { 0 }; + TSS2L_SYS_AUTH_RESPONSE auth_rsp = { + .count = 0 + }; + + /* Generate the EK key */ + + SYS_CALL(rc, Tss2_Sys_CreatePrimary, + sys_context, TPM2_RH_ENDORSEMENT, &auth_cmd, + &in_sensitive, &in_public, NULL, &creation_pcr, + &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp); + + SYS_CALL(rc, Tss2_Sys_FlushContext, sys_context, handle); + + rc = rsa_pub_from_tpm(&out_public, evp_pub); + if (rc != TPM2_RC_SUCCESS) { + LOG_ERROR("Failed to create EVP key from RSA EK: 0x%"PRIx32, rc); + return rc; + } + + return TSS2_RC_SUCCESS; +} + +TSS2_RC +get_ecc_ek_public(TSS2_SYS_CONTEXT *sys_context, EVP_PKEY **evp_pub) +{ + TSS2_RC rc; + TSS2L_SYS_AUTH_COMMAND auth_cmd = { + .auths = {{ .sessionHandle = TPM2_RH_PW }}, + .count = 1 + }; + TPM2B_SENSITIVE_CREATE in_sensitive = { 0 }; + TPM2B_PUBLIC in_public = { + .publicArea = { + .type = TPM2_ALG_ECC, + .nameAlg = TPM2_ALG_SHA256, + .objectAttributes = ( + TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN | + TPMA_OBJECT_ADMINWITHPOLICY | + TPMA_OBJECT_RESTRICTED | + TPMA_OBJECT_DECRYPT + ), + .authPolicy = { + .size = 32, + .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, + 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D, + 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52, + 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64, + 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, + 0x69, 0xAA, + }, + .parameters.eccDetail = { + .symmetric = { + .algorithm = TPM2_ALG_AES, + .keyBits.aes = 128, + .mode.aes = TPM2_ALG_CFB, + }, + .scheme = { + .scheme = TPM2_ALG_NULL, + .details = { 0 } + }, + .curveID = TPM2_ECC_NIST_P256, + .kdf = {.scheme = TPM2_ALG_NULL, + .details = { 0 } + } + }, + .unique.ecc = { + .x = {.size = 32,.buffer = { 0 }}, + .y = {.size = 32,.buffer = { 0 }} + } + } + }; + TPML_PCR_SELECTION creation_pcr = { 0 }; + TPM2_HANDLE handle; + TPM2B_PUBLIC out_public = { 0 }; + TSS2L_SYS_AUTH_RESPONSE auth_rsp = { + .count = 0 + }; + SYS_CALL(rc, Tss2_Sys_CreatePrimary, + sys_context, TPM2_RH_ENDORSEMENT, &auth_cmd, + &in_sensitive, &in_public, NULL, &creation_pcr, + &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp); + + + SYS_CALL(rc, Tss2_Sys_FlushContext, sys_context, handle); + + rc = ecc_pub_from_tpm(&out_public, evp_pub); + if (rc != TPM2_RC_SUCCESS) { + LOG_ERROR("Failed to create EVP key from ECC EK: 0x%"PRIx32, rc); + return rc; + } + + return TSS2_RC_SUCCESS; + +} + +char pwd[6] = "abcdef"; + +int pass_cb(char *buf, int size, int rwflag, void *u) +{ + (void)rwflag; + memcpy(buf, &pwd[0], 6); + return 6; +} + +TSS2_RC +nv_write(TSS2_SYS_CONTEXT *sys_context, TPMI_RH_NV_INDEX nvIndex, X509 *cert) +{ + TSS2_RC rc; + TSS2L_SYS_AUTH_COMMAND auth_cmd = { + .auths = {{ .sessionHandle = TPM2_RH_PW }}, + .count = 1 + }; + + if (!nvIndex) { + nvIndex = 0x01c00002; + } + + TPM2B_AUTH nv_auth = { 0 }; + TPM2B_NV_PUBLIC public_info = { + .nvPublic = { + .nameAlg = TPM2_ALG_SHA1, + .attributes = TPMA_NV_PPWRITE | TPMA_NV_AUTHREAD | TPMA_NV_OWNERREAD | + TPMA_NV_PLATFORMCREATE | TPMA_NV_NO_DA, + .dataSize = 0, + .nvIndex = nvIndex, + }, + }; + + TSS2L_SYS_AUTH_RESPONSE auth_rsp = { + .count = 0 + }; + TPM2B_MAX_NV_BUFFER buf1 = { 0 }; + TPM2B_MAX_NV_BUFFER buf2 = { 0 }; + unsigned char *cert_buf = NULL; + int cert_size; + + cert_size = i2d_X509(cert, &cert_buf); + if (cert_size < 0) { + LOG_ERROR("Certificate buffer can't be created."); + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + if (buf1.size >= sizeof(buf1.buffer)) { + LOG_ERROR("Certificate to large"); + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + buf1.size = cert_size; + memcpy(&buf1.buffer[0], cert_buf, cert_size); + free(cert_buf); + + /* First make sure that not EK certificate is currently loaded */ + LOG_WARNING("Cert input size is %"PRIu16, buf1.size); + public_info.nvPublic.dataSize = buf1.size; + + LOG_WARNING("Define NV cert with nv index: %x", public_info.nvPublic.nvIndex); + + SYS_CALL(rc, Tss2_Sys_NV_DefineSpace, + sys_context, TPM2_RH_PLATFORM, &auth_cmd, + &nv_auth, &public_info, &auth_rsp); + + /* Split the input buffer into 2 chunks */ + buf2.size = buf1.size; + buf1.size /= 2; + buf2.size -= buf1.size; + memcpy(&buf2.buffer[0], &buf1.buffer[buf1.size], buf2.size); + + SYS_CALL(rc, Tss2_Sys_NV_Write, sys_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd, + &buf1, 0, &auth_rsp); + + SYS_CALL(rc, Tss2_Sys_NV_Write, sys_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd, + &buf2, buf1.size, &auth_rsp); + + return TSS2_RC_SUCCESS; +} + +TSS2_RC +load_intermed_cert_and_key(const char *ca_key_path, EVP_PKEY **ca_key, + const char *ca_cert_path, X509 **ca_crt) +{ + BIO *bio = NULL; + *ca_crt = NULL; + *ca_key = NULL; + + /* Load the intermediate certificate */ + bio = BIO_new(BIO_s_file()); + if (!bio || !BIO_read_filename(bio, ca_cert_path)) { + LOG_ERROR("Failure in BIO_read_filename %s", ca_cert_path); + goto error_cleanup; + } + *ca_crt = PEM_read_bio_X509(bio, NULL, NULL, NULL); + if (!*ca_crt) { + LOG_ERROR("Could not read intermediate cert %s", ca_cert_path); + goto error_cleanup; + } + BIO_free_all(bio); + + /* Load the intermediate key. */ + bio = BIO_new(BIO_s_file()); + if (!bio || !BIO_read_filename(bio, ca_key_path)) { + LOG_ERROR("Failure in BIO_read_filename %s", ca_key_path); + goto error_cleanup; + } + *ca_key = PEM_read_bio_PrivateKey(bio, NULL, pass_cb, NULL); + if (!*ca_key) { + LOG_ERROR("Could not read intermediate key %s", ca_key_path); + goto error_cleanup; + } + BIO_free_all(bio); + return TSS2_RC_SUCCESS; + + error_cleanup: + BIO_free_all(bio); + X509_free(*ca_crt); + EVP_PKEY_free(*ca_key); + return TSS2_FAPI_RC_GENERAL_FAILURE; +} + +TSS2_RC +get_dummy_csr(EVP_PKEY **dmy_key, X509_REQ **req) +{ + *dmy_key = NULL; + *req = NULL; + EVP_PKEY_CTX *ctx = NULL; + + *dmy_key = NULL; + *req = X509_REQ_new(); + if (!*req) { + LOG_ERROR("Failed to allocate Memory for request"); + goto error_cleanup; + } + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!ctx) { + LOG_ERROR("Failed to allocate Memory for PKEY context"); + goto error_cleanup; + } + + /* Create dummy key */ + + if (EVP_PKEY_keygen_init(ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0 || + EVP_PKEY_keygen(ctx, dmy_key) <= 0) { + LOG_ERROR("Failed to create key"); + goto error_cleanup; + } + + X509_REQ_set_pubkey(*req, *dmy_key); + + /* Self-sign the request to prove that we posses the key. */ + if (!X509_REQ_sign(*req, *dmy_key, EVP_sha256())) { + LOG_ERROR("Failed to sign request."); + goto error_cleanup; + } + EVP_PKEY_CTX_free(ctx); + return TSS2_RC_SUCCESS; + + error_cleanup: + if (dmy_key) + EVP_PKEY_free(*dmy_key); + if (req) + X509_REQ_free(*req); + if (ctx) + EVP_PKEY_CTX_free(ctx); + return TSS2_FAPI_RC_GENERAL_FAILURE; +} + +TSS2_RC +get_ek_certificate(EVP_PKEY *ca_key, X509 *ca_cert, + X509_REQ *req, + EVP_PKEY *ek, X509 **ek_cert) +{ + BIGNUM *bn = NULL; + unsigned char serial_ary[5] = { 0x01, 0x02, 0x03, 0x04, 0x05 }; + ASN1_INTEGER *serial_asn1 = NULL; + + *ek_cert = X509_new(); + if (!*ek_cert) { + LOG_ERROR("Failed to allocate Memory for PKEY context"); + goto error_cleanup; + } + if (X509_set_version(*ek_cert, 2) <= 0) goto error_cleanup; + bn = BN_new(); + if (!bn) { + LOG_ERROR("Failed to allocate BN"); + goto error_cleanup; + } + BN_bin2bn(&serial_ary[0], sizeof(serial_ary), bn); + serial_asn1 = ASN1_INTEGER_new(); + if (!serial_asn1) { + LOG_ERROR("Failed to allocate ASN1 serial."); + goto error_cleanup; + } + + BN_to_ASN1_INTEGER(bn, serial_asn1); + + if (X509_set_serialNumber(*ek_cert, serial_asn1) <= 0 || + X509_set_issuer_name(*ek_cert, X509_get_subject_name(ca_cert)) <= 0) { + LOG_ERROR("Failed to initialize EK cert."); + goto error_cleanup; + } + + X509_gmtime_adj(X509_get_notBefore(*ek_cert), 0); + X509_gmtime_adj(X509_get_notAfter(*ek_cert), (long)3*365*24*3600); + + ASN1_INTEGER_free(serial_asn1); + BN_free(bn); + + EVP_PKEY *req_pubkey = X509_REQ_get_pubkey(req); + if (X509_set_pubkey(*ek_cert, ek) <= 0) { + LOG_ERROR("Failed to set pubkey of EK cert."); + goto error_cleanup; + } + EVP_PKEY_free(req_pubkey); + + if (X509_sign(*ek_cert, ca_key, EVP_sha256()) == 0) { + LOG_ERROR("Failed to sign certificate."); + goto error_cleanup; + } + X509_REQ_free(req); + return TSS2_RC_SUCCESS; + + error_cleanup: + X509_REQ_free(req); + if (bn) + BN_free(bn); + if (serial_asn1) + ASN1_INTEGER_free(serial_asn1); + if (*ek_cert) + X509_free(*ek_cert); + return TSS2_FAPI_RC_GENERAL_FAILURE; +} + +TSS2_RC +get_pubkey_fingerprint(EVP_PKEY *key, char **fingerprint) +{ + TPM2_RC rc = TSS2_FAPI_RC_GENERAL_FAILURE; + size_t size_der_pub; + unsigned char *der_key = NULL; + BUF_MEM *bio_mem_data = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + SHA256_CTX sha256_context; +#else + size_t size_hash; +#endif + unsigned char fingerprint_digest[TPM2_SHA256_DIGEST_SIZE]; + + BIO *bio_mem = BIO_new(BIO_s_mem()); + if (!bio_mem) { + LOG_ERROR("Failed to allocate BIO."); + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + if (i2d_PUBKEY_bio(bio_mem, key) == 0) { + LOG_ERROR("Failed to get public key."); + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + BIO_get_mem_ptr(bio_mem, &bio_mem_data); + der_key = (unsigned char *)bio_mem_data->data; + size_der_pub = bio_mem_data->length; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (SHA256_Init(&sha256_context) == 0 || + SHA256_Update(&sha256_context, der_key, size_der_pub) == 0 || + SHA256_Final(&fingerprint_digest[0], &sha256_context) == 0) { + LOG_ERROR("sha256 update failed."); + goto error_cleanup; + } +#else + if (EVP_Q_digest(NULL, "sha256", NULL, der_key, size_der_pub, + &fingerprint_digest[0], &size_hash) == 0) { + LOG_ERROR("sha256 update failed."); + goto error_cleanup; + } +#endif + *fingerprint = calloc(TPM2_SHA256_DIGEST_SIZE * 2 + 1, 1); + if (!(*fingerprint)) { + LOG_ERROR("Failed to allocate fingerprint."); + goto error_cleanup; + } + char *pf = &(*fingerprint)[0]; + for (size_t i = 0; i < TPM2_SHA256_DIGEST_SIZE; i++) { + pf += sprintf(pf, "%.2x", fingerprint_digest[i]); + } + rc = TSS2_RC_SUCCESS; + + error_cleanup: + if (bio_mem) + BIO_free_all(bio_mem); + return rc; + } + +TSS2_RC +get_ek_fingerprints(TSS2_SYS_CONTEXT *sys_ctx, + char **rsa_fingerprint, char **ecc_fingerprint) +{ + TSS2_RC rc; + EVP_PKEY *ecc_ek_key_pub = NULL; + EVP_PKEY *rsa_ek_key_pub = NULL; + + rc = get_ecc_ek_public(sys_ctx, &ecc_ek_key_pub); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get ECC EK: %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + rc = get_pubkey_fingerprint(ecc_ek_key_pub, ecc_fingerprint); + if (rc != TSS2_RC_SUCCESS) { + goto error_cleanup; + } + + rc = get_rsa_ek_public(sys_ctx, &rsa_ek_key_pub); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get RSA EK: %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + + rc = get_pubkey_fingerprint(rsa_ek_key_pub, rsa_fingerprint); + if (rc != TSS2_RC_SUCCESS) { + SAFE_FREE(*ecc_fingerprint); + goto error_cleanup; + } + + error_cleanup: + if (ecc_ek_key_pub) + EVP_PKEY_free(ecc_ek_key_pub); + if (rsa_ek_key_pub) + EVP_PKEY_free(rsa_ek_key_pub); + return rc; +} + +TSS2_RC +prepare_certificate(TSS2_SYS_CONTEXT *sys_ctx, X509 *ek_cert, + TPM2_NV_INDEX nv_index, char* env_var) { + TSS2_RC rc; + +#if defined(FAPI_TEST_CERTIFICATE) || defined(FAPI_TEST_CERTIFICATE_ECC) + char *pem_filename; + FILE *output_file; + // (void)nv_idex; + (void)sys_ctx; + + pem_filename = getenv(env_var); + if (!pem_filename) { + LOG_ERROR("Environment variable FAPI_TEST_CERTIFICATE_ECC not set."); + rc = TSS2_FAPI_RC_GENERAL_FAILURE; + goto error_cleanup; + } + output_file = fopen(pem_filename, "w"); + if (!output_file) { + LOG_ERROR("Error opening output file: %s", pem_filename); + rc = TSS2_FAPI_RC_GENERAL_FAILURE; + goto error_cleanup; + } + if (PEM_write_X509(output_file, ek_cert) != 1) { + perror("Error writing X.509 certificate to file"); + fclose(output_file); + rc = TSS2_FAPI_RC_GENERAL_FAILURE; + goto error_cleanup; + } + fclose(output_file); +#else + // (void)env_var; + + rc = nv_write(sys_ctx, nv_index, ek_cert); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to write ECC EK cert."); + goto error_cleanup; + } +#endif + rc = TSS2_RC_SUCCESS; + + error_cleanup: + return rc; +} + +TSS2_RC +init_ek_certificates(TSS2_SYS_CONTEXT *sys_ctx) +{ + TSS2_RC rc; + X509_REQ *req = NULL; + EVP_PKEY *dmy_key = NULL; + X509 *ecc_ek_cert = NULL; + EVP_PKEY *ecc_ek_key_pub = NULL; + X509 *rsa_ek_cert = NULL; + EVP_PKEY *rsa_ek_key_pub = NULL; + X509 *intermed_cert = NULL; + EVP_PKEY *intermed_key = NULL; + + rc = get_ecc_ek_public(sys_ctx, &ecc_ek_key_pub); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get ECC EK: %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + + rc = get_rsa_ek_public(sys_ctx, &rsa_ek_key_pub); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get RSA EK: %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + + rc = load_intermed_cert_and_key("ca/intermed-ca/private/intermed-ca.key.pem", + &intermed_key, + "ca/intermed-ca/intermed-ca.cert.pem", + &intermed_cert); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to load intermediate key and cert %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + + rc = get_dummy_csr(&dmy_key, &req); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get req: %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + + rc = get_ek_certificate(intermed_key, intermed_cert, req, + ecc_ek_key_pub, &ecc_ek_cert); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get ECC EK cert."); + goto error_cleanup; + } + + rc = prepare_certificate(sys_ctx, ecc_ek_cert, 0x1c0000a, + "FAPI_TEST_CERTIFICATE_ECC"); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to prepare ECC EK cert."); + goto error_cleanup; + } + + EVP_PKEY_free(dmy_key); + dmy_key = NULL; + X509_REQ_free(req); + req = NULL; + + rc = get_dummy_csr(&dmy_key, &req); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get req: %s\n", Tss2_RC_Decode(rc)); + goto error_cleanup; + } + + rc = get_ek_certificate(intermed_key, intermed_cert, req, + rsa_ek_key_pub, &rsa_ek_cert); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get RSA EK cert."); + goto error_cleanup; + } + + rc = prepare_certificate(sys_ctx, rsa_ek_cert, 0x1c00002, + "FAPI_TEST_CERTIFICATE"); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to prepare RSA EK cert."); + goto error_cleanup; + } + + rc = TSS2_RC_SUCCESS; + + error_cleanup: + if (req) + X509_REQ_free(req); + if (rsa_ek_cert) + X509_free(rsa_ek_cert); + if (ecc_ek_cert) + X509_free(ecc_ek_cert); + if (dmy_key) + EVP_PKEY_free(dmy_key); + if (ecc_ek_key_pub) + EVP_PKEY_free(ecc_ek_key_pub); + if (rsa_ek_key_pub) + EVP_PKEY_free(rsa_ek_key_pub); + if (intermed_cert) + X509_free(intermed_cert); + if (intermed_key) + EVP_PKEY_free(intermed_key); + + return rc; +} int test_fapi_setup(TSS2_TEST_FAPI_CONTEXT **test_ctx) @@ -530,6 +1411,54 @@ main(int argc, char *argv[]) char *remove_cmd = NULL; TSS2_TEST_FAPI_CONTEXT *test_ctx = NULL; + TSS2_TEST_ESYS_CONTEXT *test_esys_ctx; + + ret = test_esys_setup(&test_esys_ctx); + if (ret != 0) { + return ret; + } +#if !defined(FAPI_NONTPM) && !defined(DLOPEN) && defined(SELF_GENERATED_CERTIFICATE) && \ + !defined(FAPI_TEST_FINGERPRINT) && !defined(FAPI_TEST_FINGERPRINT_ECC) + TSS2_SYS_CONTEXT *sys_ctx; + TSS2_RC rc; + + rc = Esys_GetSysContext(test_esys_ctx->esys_ctx, &sys_ctx); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get SysContext: %s\n", Tss2_RC_Decode(rc)); + ret = 1; + goto error; + } + rc = init_ek_certificates(sys_ctx); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to initialize EK certificates: %s\n", + Tss2_RC_Decode(rc)); + ret = 1; + goto error; + } +#else + char *ecc_fingerprint = NULL; + char *rsa_fingerprint = NULL; + TSS2_SYS_CONTEXT *sys_ctx; + TSS2_RC rc; + + rc = Esys_GetSysContext(test_esys_ctx->esys_ctx, &sys_ctx); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("Failed to get SysContext: %s\n", Tss2_RC_Decode(rc)); + return EXIT_ERROR; + } + + rc = get_ek_fingerprints(sys_ctx, &rsa_fingerprint, &ecc_fingerprint); + if (rc != TSS2_RC_SUCCESS) { + return EXIT_ERROR; + } + setenv("FAPI_TEST_FINGERPRINT", rsa_fingerprint, 1); + setenv("FAPI_TEST_FINGERPRINT_ECC", ecc_fingerprint, 1); + free(rsa_fingerprint); + free(ecc_fingerprint); +#endif + + test_esys_teardown(test_esys_ctx); + ret = test_fapi_setup(&test_ctx); if (ret != 0) { goto error; @@ -543,7 +1472,6 @@ main(int argc, char *argv[]) #endif ret = test_invoke_fapi(test_ctx->fapi_ctx); - LOG_INFO("Test returned %i", ret); if (ret) goto error; @@ -553,6 +1481,7 @@ main(int argc, char *argv[]) if (ret != 0) { goto error; } + #endif size = asprintf(&remove_cmd, "rm -r -f %s", test_ctx->tmpdir); diff --git a/test/integration/test-common.c b/test/integration/test-common.c index ba2ded1e6..a7d41c0ef 100644 --- a/test/integration/test-common.c +++ b/test/integration/test-common.c @@ -568,8 +568,6 @@ test_fapi_checks_post(TSS2_TEST_FAPI_CONTEXT *test_ctx) return test_esys_checks_post(&test_ctx->test_esys_ctx); } - - void test_esys_teardown(TSS2_TEST_ESYS_CONTEXT *test_ctx) { diff --git a/test/integration/test-common.h b/test/integration/test-common.h index ca1a65543..8c16b897f 100644 --- a/test/integration/test-common.h +++ b/test/integration/test-common.h @@ -67,5 +67,7 @@ int test_fapi_setup(TSS2_TEST_FAPI_CONTEXT **test_ctx); int test_fapi_checks_pre(TSS2_TEST_FAPI_CONTEXT *test_ctx); int test_fapi_checks_post(TSS2_TEST_FAPI_CONTEXT *test_ctx); void test_fapi_teardown(TSS2_TEST_FAPI_CONTEXT *test_ctx); +void test_esys_teardown(TSS2_TEST_ESYS_CONTEXT *test_ctx); + #endif /* TEST_COMMON_H */ diff --git a/test/integration/test-fapi.h b/test/integration/test-fapi.h index d654bd2fd..64fd972a0 100644 --- a/test/integration/test-fapi.h +++ b/test/integration/test-fapi.h @@ -21,7 +21,6 @@ #define ASSERT_SIZE 10 /* sanity check value for string outputs of Fapi commands */ - #define ASSERT(EXPR) \ if (!(EXPR)) { \ LOG_ERROR("Failed assertion: " #EXPR); \