From 9a44d5682e27885df560e3754586c85fb5bec382 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Tue, 3 Oct 2023 10:25:19 -0400 Subject: [PATCH] tpm2: add test to verify srk templates Verify the tpm2_get_srk_template() and tpm2_get_best_srk_template() functions work as expected. (cherry picked from commit 2eea1b8f2f787ea2ed4e571096b48c5a301f63f4) Related: RHEL-16182 --- src/shared/tpm2-util.c | 4 +- src/shared/tpm2-util.h | 2 + src/test/test-tpm2.c | 84 +++++++++++++++++++++++++++++++----------- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 1751c82450..4f1aafedf8 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1175,7 +1175,7 @@ int tpm2_get_srk_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) { } /* Get the best supported SRK template. ECC is preferred, then RSA. */ -static int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template) { +int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template) { TPMT_PUBLIC template; int r; @@ -1216,7 +1216,7 @@ static int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template) /* Get the SRK. Returns 1 if SRK is found, 0 if there is no SRK, or < 0 on error. Also see * tpm2_get_or_create_srk() below. */ -static int tpm2_get_srk( +int tpm2_get_srk( Tpm2Context *c, const Tpm2Handle *session, TPM2B_PUBLIC **ret_public, diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index fe26b98e76..bf41bac76e 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -182,7 +182,9 @@ int tpm2_calculate_policy_pcr(const Tpm2PCRValue *pcr_values, size_t n_pcr_value int tpm2_calculate_sealing_policy(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, const TPM2B_PUBLIC *public, bool use_pin, TPM2B_DIGEST *digest); int tpm2_get_srk_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template); +int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template); +int tpm2_get_srk(Tpm2Context *c, const Tpm2Handle *session, TPM2B_PUBLIC **ret_public, TPM2B_NAME **ret_name, TPM2B_NAME **ret_qname, Tpm2Handle **ret_handle); int tpm2_get_or_create_srk(Tpm2Context *c, const Tpm2Handle *session, TPM2B_PUBLIC **ret_public, TPM2B_NAME **ret_name, TPM2B_NAME **ret_qname, Tpm2Handle **ret_handle); int tpm2_seal(Tpm2Context *c, uint32_t seal_key_handle, const TPM2B_DIGEST *policy, const char *pin, void **ret_secret, size_t *ret_secret_size, void **ret_blob, size_t *ret_blob_size, uint16_t *ret_primary_alg, void **ret_srk_buf, size_t *ret_srk_buf_size); diff --git a/src/test/test-tpm2.c b/src/test/test-tpm2.c index 8a27ffc7db..ede08a39aa 100644 --- a/src/test/test-tpm2.c +++ b/src/test/test-tpm2.c @@ -960,29 +960,49 @@ TEST(calculate_policy_pcr) { assert_se(digest_check(&d, "7481fd1b116078eb3ac2456e4ad542c9b46b9b8eb891335771ca8e7c8f8e4415")); } +static void check_srk_rsa_template(TPMT_PUBLIC *template) { + assert_se(template->type == TPM2_ALG_RSA); + assert_se(template->nameAlg == TPM2_ALG_SHA256); + assert_se(template->objectAttributes == 0x30472); + assert_se(template->parameters.rsaDetail.symmetric.algorithm == TPM2_ALG_AES); + assert_se(template->parameters.rsaDetail.symmetric.keyBits.sym == 128); + assert_se(template->parameters.rsaDetail.symmetric.mode.sym == TPM2_ALG_CFB); + assert_se(template->parameters.rsaDetail.scheme.scheme == TPM2_ALG_NULL); + assert_se(template->parameters.rsaDetail.keyBits == 2048); +} + +static void check_srk_ecc_template(TPMT_PUBLIC *template) { + assert_se(template->type == TPM2_ALG_ECC); + assert_se(template->nameAlg == TPM2_ALG_SHA256); + assert_se(template->objectAttributes == 0x30472); + assert_se(template->parameters.eccDetail.symmetric.algorithm == TPM2_ALG_AES); + assert_se(template->parameters.eccDetail.symmetric.keyBits.sym == 128); + assert_se(template->parameters.eccDetail.symmetric.mode.sym == TPM2_ALG_CFB); + assert_se(template->parameters.eccDetail.scheme.scheme == TPM2_ALG_NULL); + assert_se(template->parameters.eccDetail.kdf.scheme == TPM2_ALG_NULL); + assert_se(template->parameters.eccDetail.curveID == TPM2_ECC_NIST_P256); +} + TEST(tpm2_get_srk_template) { - TPMT_PUBLIC rsa; - assert_se(tpm2_get_srk_template(TPM2_ALG_RSA, &rsa) >= 0); - assert_se(rsa.type == TPM2_ALG_RSA); - assert_se(rsa.nameAlg == TPM2_ALG_SHA256); - assert_se(rsa.objectAttributes == 0x30472); - assert_se(rsa.parameters.rsaDetail.symmetric.algorithm == TPM2_ALG_AES); - assert_se(rsa.parameters.rsaDetail.symmetric.keyBits.sym == 128); - assert_se(rsa.parameters.rsaDetail.symmetric.mode.sym == TPM2_ALG_CFB); - assert_se(rsa.parameters.rsaDetail.scheme.scheme == TPM2_ALG_NULL); - assert_se(rsa.parameters.rsaDetail.keyBits == 2048); - - TPMT_PUBLIC ecc; - assert_se(tpm2_get_srk_template(TPM2_ALG_ECC, &ecc) >= 0); - assert_se(ecc.type == TPM2_ALG_ECC); - assert_se(ecc.nameAlg == TPM2_ALG_SHA256); - assert_se(ecc.objectAttributes == 0x30472); - assert_se(ecc.parameters.eccDetail.symmetric.algorithm == TPM2_ALG_AES); - assert_se(ecc.parameters.eccDetail.symmetric.keyBits.sym == 128); - assert_se(ecc.parameters.eccDetail.symmetric.mode.sym == TPM2_ALG_CFB); - assert_se(ecc.parameters.eccDetail.scheme.scheme == TPM2_ALG_NULL); - assert_se(ecc.parameters.eccDetail.kdf.scheme == TPM2_ALG_NULL); - assert_se(ecc.parameters.eccDetail.curveID == TPM2_ECC_NIST_P256); + TPMT_PUBLIC template; + + assert_se(tpm2_get_srk_template(TPM2_ALG_RSA, &template) >= 0); + check_srk_rsa_template(&template); + + assert_se(tpm2_get_srk_template(TPM2_ALG_ECC, &template) >= 0); + check_srk_ecc_template(&template); +} + +static void check_best_srk_template(Tpm2Context *c) { + TPMT_PUBLIC template; + assert_se(tpm2_get_best_srk_template(c, &template) >= 0); + + assert_se(IN_SET(template.type, TPM2_ALG_ECC, TPM2_ALG_RSA)); + + if (template.type == TPM2_ALG_RSA) + check_srk_rsa_template(&template); + else + check_srk_ecc_template(&template); } static void check_test_parms(Tpm2Context *c) { @@ -1040,6 +1060,24 @@ static void check_supports_command(Tpm2Context *c) { assert_se(tpm2_supports_command(c, TPM2_CC_Unseal)); } +static void check_get_or_create_srk(Tpm2Context *c) { + _cleanup_free_ TPM2B_PUBLIC *public = NULL; + _cleanup_free_ TPM2B_NAME *name = NULL, *qname = NULL; + _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL; + assert_se(tpm2_get_or_create_srk(c, NULL, &public, &name, &qname, &handle) >= 0); + assert_se(public && name && qname && handle); + + _cleanup_free_ TPM2B_PUBLIC *public2 = NULL; + _cleanup_free_ TPM2B_NAME *name2 = NULL, *qname2 = NULL; + _cleanup_(tpm2_handle_freep) Tpm2Handle *handle2 = NULL; + assert_se(tpm2_get_srk(c, NULL, &public2, &name2, &qname2, &handle2) >= 0); + assert_se(public2 && name2 && qname2 && handle2); + + assert_se(memcmp_nn(public, sizeof(*public), public2, sizeof(*public2)) == 0); + assert_se(memcmp_nn(name->name, name->size, name2->name, name2->size) == 0); + assert_se(memcmp_nn(qname->name, qname->size, qname2->name, qname2->size) == 0); +} + static void check_seal_unseal_for_handle(Tpm2Context *c, TPM2_HANDLE handle) { TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE); @@ -1120,6 +1158,8 @@ TEST_RET(tests_which_require_tpm) { check_test_parms(c); check_supports_alg(c); check_supports_command(c); + check_best_srk_template(c); + check_get_or_create_srk(c); check_seal_unseal(c); return 0;