summaryrefslogtreecommitdiff
path: root/common/fpsensor
diff options
context:
space:
mode:
authorYicheng Li <yichengli@chromium.org>2019-06-11 16:46:36 -0700
committerCommit Bot <commit-bot@chromium.org>2019-10-08 02:31:05 +0000
commit762f51eeca42b906e220418188b751b99ae7182d (patch)
treea68400455dfc3ed3925034e2ad1e98a96191a6ab /common/fpsensor
parent0df7fdbf07a7d64a13416dc28e1a7538907216c5 (diff)
downloadchrome-ec-762f51eeca42b906e220418188b751b99ae7182d.tar.gz
fpsensor: Prepare derivation of positive match secret.
Implement derivation of positive match secret for a template. This derivation will be used when biod sends a command to ask for positive match secret and the secret readable bit is set. Also add unit tests for this derivation. BRANCH=nocturne BUG=chromium:927095 TEST=make -j buildall TEST=tested enrollment, matching and multifinger on DUT nocturne Change-Id: Ife477a98573284f69c5fb07e814d9a3d09f92127 Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1639440 Reviewed-by: Nicolas Norvez <norvez@chromium.org>
Diffstat (limited to 'common/fpsensor')
-rw-r--r--common/fpsensor/fpsensor_crypto.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/common/fpsensor/fpsensor_crypto.c b/common/fpsensor/fpsensor_crypto.c
index b7c5ea7260..4a2b31c411 100644
--- a/common/fpsensor/fpsensor_crypto.c
+++ b/common/fpsensor/fpsensor_crypto.c
@@ -139,6 +139,50 @@ int hkdf_expand(uint8_t *out_key, size_t L, const uint8_t *prk,
#undef HASH_LEN
}
+int derive_positive_match_secret(uint8_t *output,
+ const uint8_t *input_positive_match_salt)
+{
+ int ret;
+ uint8_t ikm[CONFIG_ROLLBACK_SECRET_SIZE + sizeof(tpm_seed)];
+ uint8_t prk[SHA256_DIGEST_SIZE];
+ static const char info_prefix[] = "positive_match_secret for user ";
+ uint8_t info[sizeof(info_prefix) - 1 + sizeof(user_id)];
+
+ if (bytes_are_trivial(input_positive_match_salt,
+ FP_POSITIVE_MATCH_SALT_BYTES)) {
+ CPRINTS("Failed to derive positive match secret: "
+ "salt bytes are trivial.");
+ return EC_ERROR_INVAL;
+ }
+
+ ret = get_ikm(ikm);
+ if (ret != EC_SUCCESS) {
+ CPRINTS("Failed to get IKM: %d", ret);
+ return ret;
+ }
+
+ /* "Extract" step of HKDF. */
+ hkdf_extract(prk, input_positive_match_salt,
+ FP_POSITIVE_MATCH_SALT_BYTES, ikm, sizeof(ikm));
+ always_memset(ikm, 0, sizeof(ikm));
+
+ memcpy(info, info_prefix, strlen(info_prefix));
+ memcpy(info + strlen(info_prefix), user_id, sizeof(user_id));
+
+ /* "Expand" step of HKDF. */
+ ret = hkdf_expand(output, FP_POSITIVE_MATCH_SECRET_BYTES, prk,
+ sizeof(prk), info, sizeof(info));
+ always_memset(prk, 0, sizeof(prk));
+
+ /* Check that secret is not full of 0x00 or 0xff. */
+ if (bytes_are_trivial(output, FP_POSITIVE_MATCH_SECRET_BYTES)) {
+ CPRINTS("Failed to derive positive match secret: "
+ "derived secret bytes are trivial.");
+ ret = EC_ERROR_HW_INTERNAL;
+ }
+ return ret;
+}
+
int derive_encryption_key(uint8_t *out_key, const uint8_t *salt)
{
int ret;