summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorNicolas Norvez <norvez@chromium.org>2018-09-30 13:57:09 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-02 05:19:50 -0700
commiteeefb4833ad233ae81f521504578c9311bbca960 (patch)
tree313598adc206249ff754e97fde16002d90e6c9c0 /common
parent654751d6c58119102632329b10b8ddc09a279fb2 (diff)
downloadchrome-ec-eeefb4833ad233ae81f521504578c9311bbca960.tar.gz
fpsensor: add user_id to key derivation
Derive the key with HKDF, with 1 expand step to add the user_id to the key derivation process. This requires that the size of user_id is exactly SHA256_DIGEST_SIZE, which is enforced by a BUILD_ASSERT(). Also bump the template format to 2. BRANCH=nocturne BUG=b:116875889 BUG=b:73337313 TEST=enroll/unlock works as expected TEST=templates with format version 1 are rejected TEST=manually copy v2 templates between a user and another one. biod attempts to load them and they are rejected by the fpcmu as expected. Change-Id: Ie72d7c6233acb1d7e077599181b3848773783364 Signed-off-by: Nicolas Norvez <norvez@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1252458 Reviewed-by: Adam Langley <agl@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/fpsensor.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/common/fpsensor.c b/common/fpsensor.c
index 757119d648..9f70c8bd08 100644
--- a/common/fpsensor.c
+++ b/common/fpsensor.c
@@ -42,7 +42,7 @@
#define FP_MAX_FINGER_COUNT 0
#endif
#define SBP_ENC_KEY_LEN 16
-#define FP_TEMPLATE_FORMAT_VERSION 1
+#define FP_TEMPLATE_FORMAT_VERSION 2
#define FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE \
(FP_ALGORITHM_TEMPLATE_SIZE + \
sizeof(struct ec_fp_template_encryption_metadata))
@@ -347,10 +347,13 @@ static int derive_encryption_key(uint8_t *out_key, uint8_t *salt)
{
int ret;
uint8_t key_buf[SHA256_DIGEST_SIZE];
+ uint8_t prk[SHA256_DIGEST_SIZE];
uint8_t rb_secret[CONFIG_ROLLBACK_SECRET_SIZE];
+ uint8_t message[sizeof(user_id) + 1];
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 = rollback_get_secret(rb_secret);
if (ret != EC_SUCCESS) {
@@ -362,9 +365,24 @@ static int derive_encryption_key(uint8_t *out_key, uint8_t *salt)
* Derive a key with the "extract" step of HKDF
* https://tools.ietf.org/html/rfc5869#section-2.2
*/
- hmac_SHA256(key_buf, salt, FP_CONTEXT_SALT_BYTES, rb_secret,
+ hmac_SHA256(prk, salt, FP_CONTEXT_SALT_BYTES, rb_secret,
sizeof(rb_secret));
+ memset(rb_secret, 0, sizeof(rb_secret));
+
+ /*
+ * Only 1 "expand" step of HKDF since the size of the "info" context
+ * (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));
+ 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;
}