summaryrefslogtreecommitdiff
path: root/test/fpsensor_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/fpsensor_crypto.c')
-rw-r--r--test/fpsensor_crypto.c643
1 files changed, 0 insertions, 643 deletions
diff --git a/test/fpsensor_crypto.c b/test/fpsensor_crypto.c
deleted file mode 100644
index d0fd92cf7c..0000000000
--- a/test/fpsensor_crypto.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <stdbool.h>
-
-#include "common.h"
-#include "ec_commands.h"
-#include "fpsensor_crypto.h"
-#include "fpsensor_state.h"
-#include "mock/fpsensor_state_mock.h"
-#include "mock/rollback_mock.h"
-#include "mock/timer_mock.h"
-#include "test_util.h"
-#include "util.h"
-
-static const uint8_t fake_positive_match_salt[] = {
- 0x04, 0x1f, 0x5a, 0xac, 0x5f, 0x79, 0x10, 0xaf,
- 0x04, 0x1d, 0x46, 0x3a, 0x5f, 0x08, 0xee, 0xcb,
-};
-
-static const uint8_t fake_user_id[] = {
- 0x28, 0xb5, 0x5a, 0x55, 0x57, 0x1b, 0x26, 0x88,
- 0xce, 0xc5, 0xd1, 0xfe, 0x1d, 0x58, 0x5b, 0x94,
- 0x51, 0xa2, 0x60, 0x49, 0x9f, 0xea, 0xb1, 0xea,
- 0xf7, 0x04, 0x2f, 0x0b, 0x20, 0xa5, 0x93, 0x64,
-};
-
-/*
- * |expected_positive_match_secret_for_empty_user_id| is obtained by running
- * BoringSSL locally.
- * From https://boringssl.googlesource.com/boringssl
- * commit 365b7a0fcbf273b1fa704d151059e419abd6cfb8
- *
- * Steps to reproduce:
- *
- * Open boringssl/crypto/hkdf/hkdf_test.cc
- * Add the following case to static const HKDFTestVector kTests[]
- *
- * // test positive match secret
- * {
- * EVP_sha256,
- * {
- * // IKM:
- * // fake_rollback_secret
- * [ ***Copy 32 octets of fake_rollback_secret here*** ]
- * // fake_tpm_seed
- * [ ***Copy 32 octets of fake_tpm_seed here*** ]
- * }, 64,
- * {
- * // fake_positive_match_salt
- * [ ***Copy 16 octets of fake_positive_match_salt here*** ]
- * }, 16,
- * {
- * // Info:
- * // "positive_match_secret for user "
- * 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65,
- * 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73,
- * 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, 0x66, 0x6f,
- * 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20,
- * // user_id
- * [ ***Type 32 octets of 0x00 here*** ]
- * }, 63,
- * { // Expected PRK:
- * 0xc2, 0xff, 0x50, 0x2d, 0xb1, 0x7e, 0x87, 0xb1,
- * 0x25, 0x36, 0x3a, 0x88, 0xe1, 0xdb, 0x4f, 0x98,
- * 0x22, 0xb5, 0x66, 0x8c, 0xab, 0xb7, 0xc7, 0x5e,
- * 0xd7, 0x56, 0xbe, 0xde, 0x82, 0x3f, 0xd0, 0x62,
- * }, 32,
- * 32, { // 32 = L = FP_POSITIVE_MATCH_SECRET_BYTES
- * // Expected positive match secret:
- * [ ***Copy 32 octets of expected positive_match_secret here*** ]
- * }
- * },
- *
- * Then from boringssl/ execute:
- * mkdir build
- * cd build
- * cmake ..
- * make
- * cd ..
- * go run util/all_tests.go
- */
-static const uint8_t expected_positive_match_secret_for_empty_user_id[] = {
- 0x8d, 0xc4, 0x5b, 0xdf, 0x55, 0x1e, 0xa8, 0x72,
- 0xd6, 0xdd, 0xa1, 0x4c, 0xb8, 0xa1, 0x76, 0x2b,
- 0xde, 0x38, 0xd5, 0x03, 0xce, 0xe4, 0x74, 0x51,
- 0x63, 0x6c, 0x6a, 0x26, 0xa9, 0xb7, 0xfa, 0x68,
-};
-
-/*
- * Same as |expected_positive_match_secret_for_empty_user_id| but use
- * |fake_user_id| instead of all-zero user_id.
- */
-static const uint8_t expected_positive_match_secret_for_fake_user_id[] = {
- 0x0d, 0xf5, 0xac, 0x7c, 0xad, 0x37, 0x0a, 0x66,
- 0x2f, 0x71, 0xf6, 0xc6, 0xca, 0x8a, 0x41, 0x69,
- 0x8a, 0xd3, 0xcf, 0x0b, 0xc4, 0x5a, 0x5f, 0x4d,
- 0x54, 0xeb, 0x7b, 0xad, 0x5d, 0x1b, 0xbe, 0x30,
-};
-
-static int test_hkdf_expand_raw(const uint8_t *prk, size_t prk_size,
- const uint8_t *info, size_t info_size,
- const uint8_t *expected_okm, size_t okm_size)
-{
- uint8_t actual_okm[okm_size];
-
- TEST_ASSERT(hkdf_expand(actual_okm, okm_size, prk, prk_size,
- info, info_size) == EC_SUCCESS);
- TEST_ASSERT_ARRAY_EQ(expected_okm, actual_okm, okm_size);
- return EC_SUCCESS;
-}
-
-test_static int test_hkdf_expand(void)
-{
- /* Test vectors in https://tools.ietf.org/html/rfc5869#appendix-A */
- static const uint8_t prk1[] = {
- 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
- 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
- 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
- 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5,
- };
- static const uint8_t info1[] = {
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9,
- };
- static const uint8_t expected_okm1[] = {
- 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
- 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
- 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
- 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
- 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
- 0x58, 0x65,
- };
- static const uint8_t prk2[] = {
- 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a,
- 0x06, 0x10, 0x4c, 0x9c, 0xeb, 0x35, 0xb4, 0x5c,
- 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
- 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44,
- };
- static const uint8_t info2[] = {
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
- };
- static const uint8_t expected_okm2[] = {
- 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
- 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
- 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
- 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
- 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
- 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
- 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
- 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
- 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
- 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
- 0x1d, 0x87,
- };
- static const uint8_t prk3[] = {
- 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
- 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
- 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
- 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04,
- };
- static const uint8_t expected_okm3[] = {
- 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
- 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
- 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
- 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
- 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
- 0x96, 0xc8,
- };
- static uint8_t unused_output[SHA256_DIGEST_SIZE] = { 0 };
-
- TEST_ASSERT(test_hkdf_expand_raw(prk1, sizeof(prk1), info1,
- sizeof(info1), expected_okm1,
- sizeof(expected_okm1))
- == EC_SUCCESS);
- TEST_ASSERT(test_hkdf_expand_raw(prk2, sizeof(prk2), info2,
- sizeof(info2), expected_okm2,
- sizeof(expected_okm2))
- == EC_SUCCESS);
- TEST_ASSERT(test_hkdf_expand_raw(prk3, sizeof(prk3), NULL, 0,
- expected_okm3, sizeof(expected_okm3))
- == EC_SUCCESS);
-
- TEST_ASSERT(hkdf_expand(NULL, sizeof(unused_output), prk1,
- sizeof(prk1), info1, sizeof(info1))
- == EC_ERROR_INVAL);
- TEST_ASSERT(hkdf_expand(unused_output, sizeof(unused_output),
- NULL, sizeof(prk1), info1, sizeof(info1))
- == EC_ERROR_INVAL);
- TEST_ASSERT(hkdf_expand(unused_output, sizeof(unused_output),
- prk1, sizeof(prk1), NULL, sizeof(info1))
- == EC_ERROR_INVAL);
- /* Info size too long. */
- TEST_ASSERT(hkdf_expand(unused_output, sizeof(unused_output),
- prk1, sizeof(prk1), info1, 1024)
- == EC_ERROR_INVAL);
- /* OKM size too big. */
- TEST_ASSERT(hkdf_expand(unused_output, 256 * SHA256_DIGEST_SIZE,
- prk1, sizeof(prk1), info1, sizeof(info1))
- == EC_ERROR_INVAL);
- return EC_SUCCESS;
-}
-
-test_static int test_derive_encryption_key_failure_seed_not_set(void)
-{
- static uint8_t unused_key[SBP_ENC_KEY_LEN];
- static const uint8_t unused_salt[FP_CONTEXT_ENCRYPTION_SALT_BYTES]
- = { 0 };
-
- /* GIVEN that the TPM seed is not set. */
- if (fp_tpm_seed_is_set()) {
- ccprintf("%s:%s(): this test should be executed before setting"
- " TPM seed.\n",
- __FILE__, __func__);
- return -1;
- }
-
- /* THEN derivation will fail. */
- TEST_ASSERT(derive_encryption_key(unused_key, unused_salt) ==
- EC_ERROR_ACCESS_DENIED);
-
- return EC_SUCCESS;
-}
-
-static int test_derive_encryption_key_raw(const uint32_t *user_id_,
- const uint8_t *salt,
- const uint8_t *expected_key)
-{
- uint8_t key[SBP_ENC_KEY_LEN];
- int rv;
-
- /*
- * |user_id| is a global variable used as "info" in HKDF expand
- * in derive_encryption_key().
- */
- memcpy(user_id, user_id_, sizeof(user_id));
- rv = derive_encryption_key(key, salt);
-
- TEST_ASSERT(rv == EC_SUCCESS);
- TEST_ASSERT_ARRAY_EQ(key, expected_key, sizeof(key));
-
- memset(user_id, 0, sizeof(user_id));
-
- return EC_SUCCESS;
-}
-
-test_static int test_derive_encryption_key(void)
-{
- /*
- * These vectors are obtained by choosing the salt and the user_id
- * (used as "info" in HKDF), and running boringSSL's HKDF
- * (https://boringssl.googlesource.com/boringssl/+/c0b4c72b6d4c6f4828a373ec454bd646390017d4/crypto/hkdf/)
- * locally to get the output key. The IKM used in the run is the
- * concatenation of |fake_rollback_secret| and |fake_tpm_seed|.
- */
- static const uint32_t user_id1[] = {
- 0x608b1b0b, 0xe10d3d24, 0x0bbbe4e6, 0x807b36d9,
- 0x2a1f8abc, 0xea38104a, 0x562d9431, 0x64d721c5,
- };
-
- static const uint8_t salt1[] = {
- 0xd0, 0x88, 0x34, 0x15, 0xc0, 0xfa, 0x8e, 0x22,
- 0x9f, 0xb4, 0xd5, 0xa9, 0xee, 0xd3, 0x15, 0x19,
- };
-
- static const uint8_t key1[] = {
- 0xdb, 0x49, 0x6e, 0x1b, 0x67, 0x8a, 0x35, 0xc6,
- 0xa0, 0x9d, 0xb6, 0xa0, 0x13, 0xf4, 0x21, 0xb3,
- };
-
- static const uint32_t user_id2[] = {
- 0x2546a2ca, 0xf1891f7a, 0x44aad8b8, 0x0d6aac74,
- 0x6a4ab846, 0x9c279796, 0x5a72eae1, 0x8276d2a3,
- };
-
- static const uint8_t salt2[] = {
- 0x72, 0x6b, 0xc1, 0xe4, 0x64, 0xd4, 0xff, 0xa2,
- 0x5a, 0xac, 0x5b, 0x0b, 0x06, 0x67, 0xe1, 0x53,
- };
-
- static const uint8_t key2[] = {
- 0x8d, 0x53, 0xaf, 0x4c, 0x96, 0xa2, 0xee, 0x46,
- 0x9c, 0xe2, 0xe2, 0x6f, 0xe6, 0x66, 0x3d, 0x3a,
- };
-
- /*
- * GIVEN that the TPM seed is set, and reading the rollback secret will
- * succeed.
- */
- TEST_ASSERT(fp_tpm_seed_is_set() &&
- !mock_ctrl_rollback.get_secret_fail);
-
- /* THEN the derivation will succeed. */
- TEST_ASSERT(test_derive_encryption_key_raw(user_id1, salt1, key1) ==
- EC_SUCCESS);
-
- TEST_ASSERT(test_derive_encryption_key_raw(user_id2, salt2, key2) ==
- EC_SUCCESS);
-
- return EC_SUCCESS;
-}
-
-test_static int test_derive_encryption_key_failure_rollback_fail(void)
-{
- static uint8_t unused_key[SBP_ENC_KEY_LEN];
- static const uint8_t unused_salt[FP_CONTEXT_ENCRYPTION_SALT_BYTES]
- = { 0 };
-
- /* GIVEN that reading the rollback secret will fail. */
- mock_ctrl_rollback.get_secret_fail = true;
- /* THEN the derivation will fail. */
- TEST_ASSERT(derive_encryption_key(unused_key, unused_salt) ==
- EC_ERROR_HW_INTERNAL);
-
- /* GIVEN that reading the rollback secret will succeed. */
- mock_ctrl_rollback.get_secret_fail = false;
- /* GIVEN that the TPM seed has been set. */
- TEST_ASSERT(fp_tpm_seed_is_set());
- /* THEN the derivation will succeed. */
- TEST_ASSERT(derive_encryption_key(unused_key, unused_salt) ==
- EC_SUCCESS);
-
- return EC_SUCCESS;
-}
-
-test_static int test_derive_positive_match_secret_fail_seed_not_set(void)
-{
- static uint8_t output[FP_POSITIVE_MATCH_SECRET_BYTES];
-
- /* GIVEN that seed is not set. */
- TEST_ASSERT(!fp_tpm_seed_is_set());
- /* THEN EVEN IF the encryption salt is not trivial. */
- TEST_ASSERT(!bytes_are_trivial(fake_positive_match_salt,
- sizeof(fake_positive_match_salt)));
-
- /* Deriving positive match secret will fail. */
- TEST_ASSERT(derive_positive_match_secret(output,
- fake_positive_match_salt)
- == EC_ERROR_ACCESS_DENIED);
-
- return EC_SUCCESS;
-
-}
-
-test_static int test_derive_new_pos_match_secret(void)
-{
- static uint8_t output[FP_POSITIVE_MATCH_SECRET_BYTES];
-
- /* First, for empty user_id. */
- memset(user_id, 0, sizeof(user_id));
-
- /* GIVEN that the encryption salt is not trivial. */
- TEST_ASSERT(!bytes_are_trivial(fake_positive_match_salt,
- sizeof(fake_positive_match_salt)));
- /*
- * GIVEN that the TPM seed is set, and reading the rollback secret will
- * succeed.
- */
- TEST_ASSERT(
- fp_tpm_seed_is_set() && !mock_ctrl_rollback.get_secret_fail);
-
- /* GIVEN that the salt is not trivial. */
- TEST_ASSERT(!bytes_are_trivial(fake_positive_match_salt,
- sizeof(fake_positive_match_salt)));
-
- /* THEN the derivation will succeed. */
- TEST_ASSERT(derive_positive_match_secret(output,
- fake_positive_match_salt)
- == EC_SUCCESS);
- TEST_ASSERT_ARRAY_EQ(
- output,
- expected_positive_match_secret_for_empty_user_id,
- sizeof(expected_positive_match_secret_for_empty_user_id));
-
- /* Now change the user_id to be non-trivial. */
- memcpy(user_id, fake_user_id, sizeof(fake_user_id));
- TEST_ASSERT(derive_positive_match_secret(output,
- fake_positive_match_salt)
- == EC_SUCCESS);
- TEST_ASSERT_ARRAY_EQ(
- output,
- expected_positive_match_secret_for_fake_user_id,
- sizeof(expected_positive_match_secret_for_fake_user_id));
- memset(user_id, 0, sizeof(user_id));
-
- return EC_SUCCESS;
-}
-
-test_static int test_derive_positive_match_secret_fail_rollback_fail(void)
-{
- static uint8_t output[FP_POSITIVE_MATCH_SECRET_BYTES];
-
- /* GIVEN that reading secret from anti-rollback block will fail. */
- mock_ctrl_rollback.get_secret_fail = true;
- /* THEN EVEN IF the encryption salt is not trivial. */
- TEST_ASSERT(!bytes_are_trivial(fake_positive_match_salt,
- sizeof(fake_positive_match_salt)));
-
- /* Deriving positive match secret will fail. */
- TEST_ASSERT(derive_positive_match_secret(output,
- fake_positive_match_salt)
- == EC_ERROR_HW_INTERNAL);
- mock_ctrl_rollback.get_secret_fail = false;
-
- return EC_SUCCESS;
-}
-
-test_static int test_derive_positive_match_secret_fail_salt_trivial(void)
-{
- static uint8_t output[FP_POSITIVE_MATCH_SECRET_BYTES];
-
- /* GIVEN that the salt is trivial. */
- static const uint8_t salt[FP_CONTEXT_ENCRYPTION_SALT_BYTES] = { 0 };
-
- /* THEN deriving positive match secret will fail. */
- TEST_ASSERT(derive_positive_match_secret(output, salt)
- == EC_ERROR_INVAL);
- return EC_SUCCESS;
-}
-
-static int test_enable_positive_match_secret_once(
- struct positive_match_secret_state *dumb_state)
-{
- const int8_t kIndexToEnable = 0;
- timestamp_t now = get_time();
-
- TEST_ASSERT(fp_enable_positive_match_secret(
- kIndexToEnable, dumb_state) == EC_SUCCESS);
- TEST_ASSERT(dumb_state->template_matched == kIndexToEnable);
- TEST_ASSERT(dumb_state->readable);
- TEST_ASSERT(dumb_state->deadline.val == now.val + (5 * SECOND));
-
- return EC_SUCCESS;
-}
-
-test_static int test_enable_positive_match_secret(void)
-{
- struct positive_match_secret_state dumb_state = {
- .template_matched = FP_NO_SUCH_TEMPLATE,
- .readable = false,
- .deadline.val = 0,
- };
-
- TEST_ASSERT(test_enable_positive_match_secret_once(&dumb_state)
- == EC_SUCCESS);
-
- /* Trying to enable again before reading secret should fail. */
- TEST_ASSERT(fp_enable_positive_match_secret(0, &dumb_state) ==
- EC_ERROR_UNKNOWN);
- TEST_ASSERT(dumb_state.template_matched == FP_NO_SUCH_TEMPLATE);
- TEST_ASSERT(!dumb_state.readable);
- TEST_ASSERT(dumb_state.deadline.val == 0);
-
- return EC_SUCCESS;
-}
-
-test_static int test_disable_positive_match_secret(void)
-{
- struct positive_match_secret_state dumb_state = {
- .template_matched = FP_NO_SUCH_TEMPLATE,
- .readable = false,
- .deadline.val = 0,
- };
-
- TEST_ASSERT(test_enable_positive_match_secret_once(&dumb_state)
- == EC_SUCCESS);
-
- fp_disable_positive_match_secret(&dumb_state);
- TEST_ASSERT(dumb_state.template_matched == FP_NO_SUCH_TEMPLATE);
- TEST_ASSERT(!dumb_state.readable);
- TEST_ASSERT(dumb_state.deadline.val == 0);
-
- return EC_SUCCESS;
-}
-
-test_static int test_command_read_match_secret(void)
-{
- int rv;
- struct ec_params_fp_read_match_secret params;
- struct ec_response_fp_read_match_secret resp;
- timestamp_t now = get_time();
-
- /* For empty user_id. */
- memset(user_id, 0, sizeof(user_id));
-
- /* Invalid finger index should be rejected. */
- params.fgr = FP_NO_SUCH_TEMPLATE;
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), NULL, 0);
- TEST_ASSERT(rv == EC_RES_INVALID_PARAM);
- params.fgr = FP_MAX_FINGER_COUNT;
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), NULL, 0);
- TEST_ASSERT(rv == EC_RES_INVALID_PARAM);
-
- memset(&resp, 0, sizeof(resp));
- /* GIVEN that finger index is valid. */
- params.fgr = 0;
-
- /* GIVEN that positive match secret is enabled. */
- fp_enable_positive_match_secret(params.fgr,
- &positive_match_secret_state);
-
- /* GIVEN that salt is non-trivial. */
- memcpy(fp_positive_match_salt[0], fake_positive_match_salt,
- sizeof(fp_positive_match_salt[0]));
- /* THEN reading positive match secret should succeed. */
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), &resp, sizeof(resp));
- if (rv != EC_RES_SUCCESS) {
- ccprintf("%s:%s(): rv = %d\n", __FILE__, __func__, rv);
- return -1;
- }
- /* AND the readable bit should be cleared after the read. */
- TEST_ASSERT(positive_match_secret_state.readable == false);
-
- TEST_ASSERT_ARRAY_EQ(
- resp.positive_match_secret,
- expected_positive_match_secret_for_empty_user_id,
- sizeof(expected_positive_match_secret_for_empty_user_id));
-
- /*
- * Now try reading secret again.
- * EVEN IF the deadline has not passed.
- */
- positive_match_secret_state.deadline.val = now.val + 1 * SECOND;
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), NULL, 0);
- /*
- * This time the command should fail because the
- * fp_pos_match_secret_readable bit is cleared when the secret was read
- * the first time.
- */
- TEST_ASSERT(rv == EC_RES_ACCESS_DENIED);
-
- return EC_SUCCESS;
-}
-
-test_static int test_command_read_match_secret_wrong_finger(void)
-{
- int rv;
- struct ec_params_fp_read_match_secret params;
-
- /* GIVEN that the finger is not the matched or enrolled finger. */
- params.fgr = 0;
- /*
- * GIVEN that positive match secret is enabled for a different
- * finger.
- */
- fp_enable_positive_match_secret(params.fgr + 1,
- &positive_match_secret_state);
-
- /* Reading secret will fail. */
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), NULL, 0);
- TEST_ASSERT(rv == EC_RES_ACCESS_DENIED);
- return EC_SUCCESS;
-}
-
-test_static int test_command_read_match_secret_timeout(void)
-{
- int rv;
- struct ec_params_fp_read_match_secret params;
-
- params.fgr = 0;
- /* GIVEN that the read is too late. */
- fp_enable_positive_match_secret(params.fgr,
- &positive_match_secret_state);
- set_time(positive_match_secret_state.deadline);
-
- /* EVEN IF encryption salt is non-trivial. */
- memcpy(fp_positive_match_salt[0], fake_positive_match_salt,
- sizeof(fp_positive_match_salt[0]));
- /* Reading secret will fail. */
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), NULL, 0);
- TEST_ASSERT(rv == EC_RES_TIMEOUT);
- return EC_SUCCESS;
-}
-
-test_static int test_command_read_match_secret_unreadable(void)
-{
- int rv;
- struct ec_params_fp_read_match_secret params;
-
- params.fgr = 0;
- /* GIVEN that the readable bit is not set. */
- fp_enable_positive_match_secret(params.fgr,
- &positive_match_secret_state);
- positive_match_secret_state.readable = false;
-
- /* EVEN IF the finger is just matched. */
- TEST_ASSERT(positive_match_secret_state.template_matched
- == params.fgr);
-
- /* EVEN IF encryption salt is non-trivial. */
- memcpy(fp_positive_match_salt[0], fake_positive_match_salt,
- sizeof(fp_positive_match_salt[0]));
- /* Reading secret will fail. */
- rv = test_send_host_command(EC_CMD_FP_READ_MATCH_SECRET, 0, &params,
- sizeof(params), NULL, 0);
- TEST_ASSERT(rv == EC_RES_ACCESS_DENIED);
- return EC_SUCCESS;
-}
-
-void run_test(int argc, char **argv)
-{
- RUN_TEST(test_hkdf_expand);
- RUN_TEST(test_derive_encryption_key_failure_seed_not_set);
- RUN_TEST(test_derive_positive_match_secret_fail_seed_not_set);
-
- /*
- * Set the TPM seed here because it can only be set once and cannot be
- * cleared.
- */
- ASSERT(fpsensor_state_mock_set_tpm_seed(default_fake_tpm_seed) ==
- EC_SUCCESS);
-
- /* The following test requires TPM seed to be already set. */
- RUN_TEST(test_derive_encryption_key);
- RUN_TEST(test_derive_encryption_key_failure_rollback_fail);
- RUN_TEST(test_derive_new_pos_match_secret);
- RUN_TEST(test_derive_positive_match_secret_fail_rollback_fail);
- RUN_TEST(test_derive_positive_match_secret_fail_salt_trivial);
- RUN_TEST(test_enable_positive_match_secret);
- RUN_TEST(test_disable_positive_match_secret);
- RUN_TEST(test_command_read_match_secret);
- RUN_TEST(test_command_read_match_secret_wrong_finger);
- RUN_TEST(test_command_read_match_secret_timeout);
- RUN_TEST(test_command_read_match_secret_unreadable);
- test_print_result();
-}