summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorYicheng Li <yichengli@chromium.org>2019-06-11 13:39:33 -0700
committerCommit Bot <commit-bot@chromium.org>2019-06-21 00:08:38 +0000
commit03f7c5caeb89fb707cc78565b2aec81100ee2f39 (patch)
tree29e6b4327ccca5baab4fa985d6f745891f3a64c5 /common
parentf6c19aec0dbbf42091b494ad9ccb4916ac7e6951 (diff)
downloadchrome-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.c78
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,