diff options
author | Vadim Sukhomlinov <sukhomlinov@google.com> | 2021-09-16 10:24:17 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-17 00:20:47 +0000 |
commit | 83a5b5bd7f9773a33728b223930a16425f380541 (patch) | |
tree | 77956e3f6b3906ecb953fe1fdb841a8a07a78393 /common | |
parent | 539cbdd254c1af84ddee1ac19dc355b42afdc766 (diff) | |
download | chrome-ec-83a5b5bd7f9773a33728b223930a16425f380541.tar.gz |
cr50: switch to using DRBG for key generation purposes.
An "Approved" RNG listed in FIPS 140-2 Annex C must be used for the
generation of random data or cryptographic keys used by an approved
security function. Detailed information and guidance on Key Generation
can be found in NIST SP 800-133 and FIPS 140-2 IG 7.8 and D.12.
Many of function use raw entropy from TRNG without any health tests or
even checking returned status, as old API didn't provide any indication
of failure.
With this patch we remove old API: rand() and rand_bytes() and expose
new API:
fips_rand_bytes() - generation of random bits from properly instantiated
and reseeded as needed DRBG.
fips_trng_bytes() - generation of entropy from TRNG with statistical
testing and checking for TRNG failures.
fips_trng_rand32() - generation of 32 bits from TRNG with health check
and indication of status.
ccd, rsa, ecc, pinweaver, rma_auth are updated to use new APIs.
These functions are moved into dcrypto.h which will become "Public API"
for the module.
trng_test vendor command moved to dcrypto/trng.c where it belongs.
BUG=b:138577416
TEST=make BOARD=cr50 CRYPTO_TEST=1; test/tpmtest.py
TCG tests.
-------------------------- Test Result Summary -------------------------
Test executed on: Thu Sep 16 10:16:59 2021
Performed Tests: 248
Passed Tests: 248
Failed Tests: 0
Errors: 0
Warnings: 0
======================================================================
Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com>
Change-Id: I80d103ead1962ee388df5cabfabe0498d8d06d38
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3165870
Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Auto-Submit: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/ccd_config.c | 17 | ||||
-rw-r--r-- | common/pinweaver.c | 10 | ||||
-rw-r--r-- | common/rma_auth.c | 11 |
3 files changed, 26 insertions, 12 deletions
diff --git a/common/ccd_config.c b/common/ccd_config.c index b3b12e12a7..d009acfd92 100644 --- a/common/ccd_config.c +++ b/common/ccd_config.c @@ -20,7 +20,6 @@ #include "timer.h" #include "tpm_registers.h" #include "tpm_vendor_cmds.h" -#include "trng.h" #include "wp.h" #define CPRINTS(format, args...) cprints(CC_CCD, format, ## args) @@ -310,11 +309,14 @@ static void raw_reset_password(void) * Set the password. * * @param password New password; must be non-empty + * @return EC_SUCCESS if successful */ -static void raw_set_password(const char *password) +static int raw_set_password(const char *password) { /* Get a new salt */ - rand_bytes(config.password_salt, sizeof(config.password_salt)); + if (!fips_rand_bytes(config.password_salt, + sizeof(config.password_salt))) + return EC_ERROR_HW_INTERNAL; /* Update the password digest */ ccd_password_digest(config.password_digest, password); @@ -322,6 +324,8 @@ static void raw_set_password(const char *password) /* Track whether we were opened when we set the password */ raw_set_flag(CCD_FLAG_PASSWORD_SET_WHEN_UNLOCKED, ccd_state == CCD_STATE_UNLOCKED); + + return EC_SUCCESS; } /******************************************************************************/ @@ -540,10 +544,15 @@ static int ccd_reset_password(void) */ static int ccd_set_password(const char *password) { + int result; + mutex_lock(&ccd_config_mutex); - raw_set_password(password); + result = raw_set_password(password); mutex_unlock(&ccd_config_mutex); + if (!result) + return result; + return ccd_save_config(); } diff --git a/common/pinweaver.c b/common/pinweaver.c index 7cea0ca1b0..5b9f498fd9 100644 --- a/common/pinweaver.c +++ b/common/pinweaver.c @@ -15,7 +15,6 @@ #include <pinweaver_types.h> #include <timer.h> #include <tpm_vendor_cmds.h> -#include <trng.h> #include <tpm_registers.h> #include <util.h> @@ -175,8 +174,9 @@ static int create_merkle_tree(struct bits_per_level_t bits_per_level, } memcpy(merkle_tree->root, temp_hash, PW_HASH_SIZE); - rand_bytes(merkle_tree->key_derivation_nonce, - sizeof(merkle_tree->key_derivation_nonce)); + if (!fips_rand_bytes(merkle_tree->key_derivation_nonce, + sizeof(merkle_tree->key_derivation_nonce))) + return PW_ERR_CRYPTO_FAILURE; return derive_keys(merkle_tree); } @@ -272,7 +272,9 @@ static int encrypt_leaf_data(const struct merkle_tree_t *merkle_tree, * a new IV should be generated and stored as part of the log for a * replay to be possible. */ - rand_bytes(wrapped_leaf_data->iv, sizeof(wrapped_leaf_data->iv)); + if (!fips_rand_bytes(wrapped_leaf_data->iv, + sizeof(wrapped_leaf_data->iv))) + return PW_ERR_CRYPTO_FAILURE; memcpy(&wrapped_leaf_data->pub, &leaf_data->pub, sizeof(leaf_data->pub)); if (!DCRYPTO_aes_ctr(wrapped_leaf_data->cipher_text, diff --git a/common/rma_auth.c b/common/rma_auth.c index 09539c537b..e2dcc4dea8 100644 --- a/common/rma_auth.c +++ b/common/rma_auth.c @@ -23,7 +23,7 @@ #include "tpm_registers.h" #include "tpm_vendor_cmds.h" #ifdef CONFIG_RMA_AUTH_USE_P256 -#include "trng.h" +#include "dcrypto.h" #endif #include "util.h" @@ -114,7 +114,7 @@ static void hash_buffer(void *dest, size_t dest_size, * @secet - array to return the X coordinate of the product of the server * public key multiplied by our private key. */ -static void p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES], +static int p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES], uint8_t secret[P256_NBYTES]) { uint8_t buf[SHA256_DIGEST_SIZE]; @@ -123,7 +123,8 @@ static void p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES], p256_int pk_y; /* Get some noise for private key. */ - rand_bytes(buf, sizeof(buf)); + if (!fips_rand_bytes(buf, sizeof(buf))) + return EC_ERROR_HW_INTERNAL; /* * By convention with the RMA server the Y coordinate of the Cr50 @@ -164,6 +165,7 @@ static void p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES], /* Wipe out the private key just in case. */ always_memset(&d, 0, sizeof(d)); + return EC_SUCCESS; } #endif @@ -230,7 +232,8 @@ int rma_create_challenge(void) /* Calculate a new ephemeral key pair and the shared secret. */ #ifdef CONFIG_RMA_AUTH_USE_P256 - p256_get_pub_key_and_secret(c.device_pub_key, secret); + if (p256_get_pub_key_and_secret(c.device_pub_key, secret) != EC_SUCCESS) + return EC_ERROR_UNKNOWN; #endif #ifdef CONFIG_CURVE25519 X25519_keypair(c.device_pub_key, temp); |