From ffd93ef1839fb4afe377ef4e37926728ee51675c Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Sun, 25 Aug 2024 15:08:31 -0400 Subject: [PATCH] WIP: tpm2: Add RuntimeAttribute fips-140-3 to restrict TPM 2 (StateFormatLevel 8) Add RuntimeAttribute 'fips-140-3' that restricts a TPM 2 following requirements of the FIPS-140-3 standard: - Prevents raw RSA encryption and decryption - Prevents SHA1 signature generation + verification - Prevents derivation of ECC keys from derivation parent and for creation of ephemeral keys - Performs a pairwise consistency test on RSA keys and ECC signing keys - Enables continous DRBG test Signed-off-by: Stefan Berger --- man/man3/TPMLIB_SetProfile.pod | 35 +++++++++++++++++++++++++++++++++ src/tpm2/RuntimeAttributes.c | 7 +++++++ src/tpm2/RuntimeAttributes_fp.h | 2 +- src/tpm2/RuntimeProfile.c | 6 +++--- tests/tpm2_setprofile.c | 2 +- 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/man/man3/TPMLIB_SetProfile.pod b/man/man3/TPMLIB_SetProfile.pod index 70057f77d..9aa015ba1 100644 --- a/man/man3/TPMLIB_SetProfile.pod +++ b/man/man3/TPMLIB_SetProfile.pod @@ -168,6 +168,10 @@ now. RSA key OBJECTs may be 4 bytes bigger while others are smaller now. This I enabled the I attribute. +=item 8: (since v0.10) + +This I enabled the I attribute. + =back A user may specify the I when using the I profile. @@ -280,6 +284,33 @@ keys =back +=item B + +This verb enables the following: + +=over 2 + +=item * Prohibits raw RSA encryption and decryption + +=item * Forbids SHA1 signature generation + +=item * Forbids RSA < 2048 signature generation + +=item * Forbids RSA < 2048 key generation + +=item * Prevents derivation of ECC keys from derivation parent and for creation +of ephemeral keys + +=item * Performs a pairwise consistency test on RSA keys and ECC signing keys + +=item * Enables continous DRBG test + +=back + +Note that usage of the I verb does not translate into a claim that +the TPM 2 instance is FIPS-140-3 compliant but merely restricts the usage of +crypto algorithms by the TPM 2 following the above list. + =back =head1 FIPS mode on the host @@ -315,6 +346,10 @@ A profile should contain the following verbs for minimum key sizes: =back +=over 4 + +=back + =head1 ERRORS =over 4 diff --git a/src/tpm2/RuntimeAttributes.c b/src/tpm2/RuntimeAttributes.c index 82c9643a7..2085b7446 100644 --- a/src/tpm2/RuntimeAttributes.c +++ b/src/tpm2/RuntimeAttributes.c @@ -80,6 +80,13 @@ static const struct { 7), ATTRIBUTE("no-ecc-key-derivation", RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION, 7), + ATTRIBUTE("fips-140-3", RUNTIME_ATTRIBUTE_NO_UNPADDED_ENCRYPTION | + RUNTIME_ATTRIBUTE_NO_SHA1_SIGNING | + RUNTIME_ATTRIBUTE_NO_SHA1_VERIFICATION | + RUNTIME_ATTRIBUTE_DRBG_CONTINOUS_TEST | + RUNTIME_ATTRIBUTE_PAIRWISE_CONSISTENCY_TEST | + RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION, + 8), }; LIB_EXPORT void diff --git a/src/tpm2/RuntimeAttributes_fp.h b/src/tpm2/RuntimeAttributes_fp.h index b61b090ec..30dc0b175 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 10 +#define NUM_ENTRIES_ATTRIBUTE_PROPERTIES 11 #define RUNTIME_ATTRIBUTE_NO_UNPADDED_ENCRYPTION (1 << 0) #define RUNTIME_ATTRIBUTE_NO_SHA1_SIGNING (1 << 1) diff --git a/src/tpm2/RuntimeProfile.c b/src/tpm2/RuntimeProfile.c index d45657d9d..7cd785a06 100644 --- a/src/tpm2/RuntimeProfile.c +++ b/src/tpm2/RuntimeProfile.c @@ -78,7 +78,7 @@ static const struct RuntimeProfileDesc { * This basically locks the name of the profile to the stateFormatLevel. */ unsigned int stateFormatLevel; -#define STATE_FORMAT_LEVEL_CURRENT 7 +#define STATE_FORMAT_LEVEL_CURRENT 8 #define STATE_FORMAT_LEVEL_UNKNOWN 0 /* JSON didn't provide StateFormatLevel; this is only allowed for the 'default' profile or when user passed JSON via SetProfile() */ @@ -958,8 +958,8 @@ RuntimeProfileGetSeedCompatLevel(void) case 1: /* profile runs on v0.9 */ return SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX; - case 2 ... 7: /* profile runs on v0.10 */ { - MUST_BE(STATE_FORMAT_LEVEL_CURRENT == 7); // force update when this changes + case 2 ... 8: /* profile runs on v0.10 */ { + MUST_BE(STATE_FORMAT_LEVEL_CURRENT == 8); // force update when this changes return SEED_COMPAT_LEVEL_LAST; } diff --git a/tests/tpm2_setprofile.c b/tests/tpm2_setprofile.c index 38335ca79..d5bbbe4e1 100644 --- a/tests/tpm2_setprofile.c +++ b/tests/tpm2_setprofile.c @@ -60,7 +60,7 @@ static const struct { .exp_profile = "{\"ActiveProfile\":{" "\"Name\":\"default-v1\"," - "\"StateFormatLevel\":7," + "\"StateFormatLevel\":8," "\"Commands\":\"0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159," "0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178," "0x17a-0x193,0x197,0x199-0x19c\","