diff options
author | Yicheng Li <yichengli@chromium.org> | 2019-06-11 13:39:33 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-21 00:08:38 +0000 |
commit | 03f7c5caeb89fb707cc78565b2aec81100ee2f39 (patch) | |
tree | 29e6b4327ccca5baab4fa985d6f745891f3a64c5 /common | |
parent | f6c19aec0dbbf42091b494ad9ccb4916ac7e6951 (diff) | |
download | chrome-ec-03f7c5caeb89fb707cc78565b2aec81100ee2f39.tar.gz |
fpsensor: Move HKDF code to helper functions
Move HKDF extract and HKDF expand code to two helper functions.
This is in preparation for future change to implement positive
match secret.
BRANCH=nocturne
BUG=chromium:927095
TEST=ran unittests, including unit test for derive_encryption_key()
TEST=tested enrollment, matching and multifinger on DUT nocturne
Change-Id: Ia7c67ef8339a3617b0177334ba824b4c805047c8
Signed-off-by: Yicheng Li <yichengli@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1641962
Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Reviewed-by: Nicolas Norvez <norvez@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/fpsensor/fpsensor_crypto.c | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/common/fpsensor/fpsensor_crypto.c b/common/fpsensor/fpsensor_crypto.c index 7e31e3f923..3a5a8b251c 100644 --- a/common/fpsensor/fpsensor_crypto.c +++ b/common/fpsensor/fpsensor_crypto.c @@ -16,17 +16,9 @@ #error "fpsensor requires AES, AES_GCM and ROLLBACK_SECRET_SIZE" #endif -int derive_encryption_key(uint8_t *out_key, const uint8_t *salt) +static int get_ikm(uint8_t *ikm) { int ret; - uint8_t key_buf[SHA256_DIGEST_SIZE]; - uint8_t prk[SHA256_DIGEST_SIZE]; - uint8_t message[sizeof(user_id) + 1]; - uint8_t ikm[CONFIG_ROLLBACK_SECRET_SIZE + sizeof(tpm_seed)]; - - BUILD_ASSERT(SBP_ENC_KEY_LEN <= SHA256_DIGEST_SIZE); - BUILD_ASSERT(SBP_ENC_KEY_LEN <= CONFIG_ROLLBACK_SECRET_SIZE); - BUILD_ASSERT(sizeof(user_id) == SHA256_DIGEST_SIZE); if (!fp_tpm_seed_is_set()) { CPRINTS("Seed hasn't been set."); @@ -48,11 +40,66 @@ int derive_encryption_key(uint8_t *out_key, const uint8_t *salt) */ memcpy(ikm + CONFIG_ROLLBACK_SECRET_SIZE, tpm_seed, sizeof(tpm_seed)); + return EC_RES_SUCCESS; +} + +static void hkdf_extract(uint8_t *prk, const uint8_t *salt, size_t salt_size, + const uint8_t *ikm, size_t ikm_size) +{ /* * Derive a key with the "extract" step of HKDF * https://tools.ietf.org/html/rfc5869#section-2.2 */ - hmac_SHA256(prk, salt, FP_CONTEXT_SALT_BYTES, ikm, sizeof(ikm)); + hmac_SHA256(prk, salt, salt_size, ikm, ikm_size); +} + +static int hkdf_expand_one_step(uint8_t *out_key, size_t out_key_size, + uint8_t *prk, size_t prk_size, + uint8_t *info, size_t info_size) +{ + uint8_t key_buf[SHA256_DIGEST_SIZE]; + uint8_t message_buf[SHA256_DIGEST_SIZE + 1]; + + if (out_key_size > SHA256_DIGEST_SIZE) { + CPRINTS("Deriving key material longer than SHA256_DIGEST_SIZE " + "requires more steps of HKDF expand."); + return EC_RES_ERROR; + } + + if (info_size > SHA256_DIGEST_SIZE) { + CPRINTS("Info size too big for HKDF."); + return EC_RES_ERROR; + } + + memcpy(message_buf, info, info_size); + /* 1 step, set the counter byte to 1. */ + message_buf[info_size] = 0x01; + hmac_SHA256(key_buf, prk, prk_size, message_buf, info_size + 1); + + memcpy(out_key, key_buf, out_key_size); + memset(key_buf, 0, sizeof(key_buf)); + + return EC_RES_SUCCESS; +} + +int derive_encryption_key(uint8_t *out_key, const uint8_t *salt) +{ + int ret; + uint8_t ikm[CONFIG_ROLLBACK_SECRET_SIZE + sizeof(tpm_seed)]; + uint8_t prk[SHA256_DIGEST_SIZE]; + + BUILD_ASSERT(SBP_ENC_KEY_LEN <= SHA256_DIGEST_SIZE); + BUILD_ASSERT(SBP_ENC_KEY_LEN <= CONFIG_ROLLBACK_SECRET_SIZE); + BUILD_ASSERT(sizeof(user_id) == SHA256_DIGEST_SIZE); + + ret = get_ikm(ikm); + if (ret != EC_RES_SUCCESS) { + CPRINTS("Failed to get IKM: %d", ret); + return EC_RES_ERROR; + } + + /* "Extract step of HKDF. */ + hkdf_extract(prk, salt, FP_CONTEXT_SALT_BYTES, ikm, sizeof(ikm)); memset(ikm, 0, sizeof(ikm)); /* @@ -60,16 +107,11 @@ int derive_encryption_key(uint8_t *out_key, const uint8_t *salt) * (user_id in our case) is exactly SHA256_DIGEST_SIZE. * https://tools.ietf.org/html/rfc5869#section-2.3 */ - memcpy(message, user_id, sizeof(user_id)); - /* 1 step, set the counter byte to 1. */ - message[sizeof(message) - 1] = 0x01; - hmac_SHA256(key_buf, prk, sizeof(prk), message, sizeof(message)); + ret = hkdf_expand_one_step(out_key, SBP_ENC_KEY_LEN, prk, sizeof(prk), + (uint8_t *)user_id, sizeof(user_id)); memset(prk, 0, sizeof(prk)); - memcpy(out_key, key_buf, SBP_ENC_KEY_LEN); - memset(key_buf, 0, sizeof(key_buf)); - - return EC_RES_SUCCESS; + return ret; } int aes_gcm_encrypt(const uint8_t *key, int key_size, |