From ecff064e8d764943cf23855c1862ecb76823ffb9 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Fri, 23 Aug 2024 09:06:54 -0400 Subject: [PATCH] tpm2: Implement check to disable ECC key derivation: no-ecc-key-derivation Per "TCG FIPS 140-3 guidance for TPM 2.0" document the following functions must prevent an asymmetric ECC key derivation: - Table 14: TPM2_CreateLoaded - Table 18: TPM2_ZGen_2Phase - Table 26: TPM2_Commit - Table 26: TPM2_EC_Ephemeral Return TPM_RC_TYPE as a return code to indicate failure of deriving a key. Signed-off-by: Stefan Berger --- man/man3/TPMLIB_SetProfile.pod | 8 ++++++++ src/tpm2/AsymmetricCommands.c | 6 ++++++ src/tpm2/EphemeralCommands.c | 9 +++++++++ src/tpm2/ObjectCommands.c | 4 ++++ src/tpm2/RuntimeAttributes.c | 2 ++ src/tpm2/RuntimeAttributes_fp.h | 3 ++- tests/tpm2_setprofile.c | 6 ++++-- 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/man/man3/TPMLIB_SetProfile.pod b/man/man3/TPMLIB_SetProfile.pod index 693d0e66..70057f77 100644 --- a/man/man3/TPMLIB_SetProfile.pod +++ b/man/man3/TPMLIB_SetProfile.pod @@ -272,6 +272,14 @@ keys =back +=item B: (since v0.10) + +=over 2 + +=item * Prevent ECC key derivation + +=back + =back =head1 FIPS mode on the host diff --git a/src/tpm2/AsymmetricCommands.c b/src/tpm2/AsymmetricCommands.c index c3e67197..8eea24b0 100644 --- a/src/tpm2/AsymmetricCommands.c +++ b/src/tpm2/AsymmetricCommands.c @@ -248,6 +248,12 @@ TPM2_ZGen_2Phase( OBJECT *eccKey; TPM2B_ECC_PARAMETER r; TPM_ALG_ID scheme; + // libtpms added begin + /* 2phase key exchange uses ecc key derivation; check whether it is allowed */ + if(RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, + RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION)) + return TPM_RC_TYPE; // libtpms added end + // Input Validation eccKey = HandleToObject(in->keyA); // keyA must be an ECC key diff --git a/src/tpm2/EphemeralCommands.c b/src/tpm2/EphemeralCommands.c index 0f1fd6bd..84f98704 100644 --- a/src/tpm2/EphemeralCommands.c +++ b/src/tpm2/EphemeralCommands.c @@ -95,6 +95,10 @@ TPM2_Commit(Commit_In* in, // IN: input parameter list TPMS_ECC_PARMS* parms; // Input Validation + if(RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, // libtpms added begin + RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION)) + return TPM_RC_TYPE; // libtpms added end + eccKey = HandleToObject(in->signHandle); parms = &eccKey->publicArea.parameters.eccDetail; @@ -204,6 +208,11 @@ TPM2_EC_Ephemeral( { TPM2B_ECC_PARAMETER r; TPM_RC result; + + if(RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, // libtpms added begin + RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION)) + return TPM_RC_TYPE; // libtpms added end + // do { diff --git a/src/tpm2/ObjectCommands.c b/src/tpm2/ObjectCommands.c index 5bbe54ab..fe80925b 100644 --- a/src/tpm2/ObjectCommands.c +++ b/src/tpm2/ObjectCommands.c @@ -586,6 +586,10 @@ TPM2_CreateLoaded(CreateLoaded_In* in, // IN: input parameter list // Don't derive RSA keys if(publicArea->type == TPM_ALG_RSA) return TPM_RCS_TYPE + RC_CreateLoaded_inPublic; + if(publicArea->type == TPM_ALG_ECC && // libtpms added begin + RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, + RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION)) + return TPM_RCS_TYPE + RC_CreateLoaded_inPublic; // libtpms added end // sensitiveDataOrigin has to be CLEAR in a derived object. Since this // is specific to a derived object, it is checked here. if(IS_ATTRIBUTE( diff --git a/src/tpm2/RuntimeAttributes.c b/src/tpm2/RuntimeAttributes.c index 7e13fdbb..82c9643a 100644 --- a/src/tpm2/RuntimeAttributes.c +++ b/src/tpm2/RuntimeAttributes.c @@ -77,6 +77,8 @@ static const struct { ATTRIBUTE("drbg-continous-test", RUNTIME_ATTRIBUTE_DRBG_CONTINOUS_TEST, 7), ATTRIBUTE("pct", RUNTIME_ATTRIBUTE_PAIRWISE_CONSISTENCY_TEST, + 7), + ATTRIBUTE("no-ecc-key-derivation", RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION, 7), }; diff --git a/src/tpm2/RuntimeAttributes_fp.h b/src/tpm2/RuntimeAttributes_fp.h index 3e6c1e28..b61b090e 100644 --- a/src/tpm2/RuntimeAttributes_fp.h +++ b/src/tpm2/RuntimeAttributes_fp.h @@ -42,7 +42,7 @@ #ifndef RUNTIME_ATTRIBUTES_H #define RUNTIME_ATTRIBUTES_H -#define NUM_ENTRIES_ATTRIBUTE_PROPERTIES 9 +#define NUM_ENTRIES_ATTRIBUTE_PROPERTIES 10 #define RUNTIME_ATTRIBUTE_NO_UNPADDED_ENCRYPTION (1 << 0) #define RUNTIME_ATTRIBUTE_NO_SHA1_SIGNING (1 << 1) @@ -51,6 +51,7 @@ #define RUNTIME_ATTRIBUTE_NO_SHA1_HMAC_VERIFICATION (1 << 4) #define RUNTIME_ATTRIBUTE_DRBG_CONTINOUS_TEST (1 << 5) #define RUNTIME_ATTRIBUTE_PAIRWISE_CONSISTENCY_TEST (1 << 6) +#define RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION (1 << 7) struct RuntimeAttributes { /* */ diff --git a/tests/tpm2_setprofile.c b/tests/tpm2_setprofile.c index 2098355b..38335ca7 100644 --- a/tests/tpm2_setprofile.c +++ b/tests/tpm2_setprofile.c @@ -329,7 +329,8 @@ static const struct { "0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178," "0x17a-0x193,0x197\"," "\"Attributes\":\"no-unpadded-encryption,no-sha1-signing," - "no-sha1-verification,drbg-continous-test\"," + "no-sha1-verification,drbg-continous-test,pct," + "no-ecc-key-derivation\"," "\"Description\":\"test\"" "}", .exp_fail = false, @@ -348,7 +349,8 @@ static const struct { "ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia," "camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb\"," "\"Attributes\":\"no-unpadded-encryption,no-sha1-signing," - "no-sha1-verification,drbg-continous-test\"," + "no-sha1-verification,drbg-continous-test,pct," + "no-ecc-key-derivation\"," "\"Description\":\"test\"" "}}", }, {