summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorYicheng Li <yichengli@chromium.org>2019-06-14 18:21:17 -0700
committerCommit Bot <commit-bot@chromium.org>2019-10-09 03:43:59 +0000
commit83e0848263313dbdaf10ebc887dea548faaf251a (patch)
tree9e5175d0fdee0265ef0d96fc6705fded4917c246 /test
parent635f21d41c095f138cb711118a7866fcd0b5bcc4 (diff)
downloadchrome-ec-83e0848263313dbdaf10ebc887dea548faaf251a.tar.gz
fpsensor: Implement command to read positive_match_secret.
Add EC command to read positive_match_secret on match success. If the attempt to read is 5 seconds after the match, the read is not allowed (the readable bit for positive match secret is cleared). Test that the command can read the data correctly and can read for each finger only once. Test that attempt to read secret after deadline will be rejected. BRANCH=nocturne BUG=chromium:927095 TEST=make buildall TEST=tested enrollment, matching and multifinger on DUT nocturne TEST=tested that if biod requests to download template and secret for a finger that's not currently matched, reading secret will fail. Change-Id: Idc734c6392d271e2aaee1cddf7c2c5b81b727b4a Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1679372 Reviewed-by: Nicolas Norvez <norvez@chromium.org>
Diffstat (limited to 'test')
-rw-r--r--test/fpsensor.c176
-rw-r--r--test/fpsensor.mocklist3
2 files changed, 177 insertions, 2 deletions
diff --git a/test/fpsensor.c b/test/fpsensor.c
index b31aa3b259..962295afbf 100644
--- a/test/fpsensor.c
+++ b/test/fpsensor.c
@@ -8,6 +8,7 @@
#include "fpsensor_crypto.h"
#include "fpsensor_state.h"
#include "host_command.h"
+#include "mock/timer_mock.h"
#include "test_util.h"
#include "util.h"
@@ -38,7 +39,8 @@ static const uint8_t fake_user_id[] = {
};
/*
- * |expected_positive_match_secret| is obtained by running BoringSSL locally.
+ * |expected_positive_match_secret_for_empty_user_id| is obtained by running
+ * BoringSSL locally.
* From https://boringssl.googlesource.com/boringssl
* commit 365b7a0fcbf273b1fa704d151059e419abd6cfb8
*
@@ -601,6 +603,172 @@ test_static int test_fp_set_sensor_mode(void)
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,
+ };
+ timestamp_t now = get_time();
+
+ TEST_ASSERT(fp_enable_positive_match_secret(0, &dumb_state) ==
+ EC_SUCCESS);
+ TEST_ASSERT(dumb_state.template_matched == 0);
+ TEST_ASSERT(dumb_state.readable == true);
+ TEST_ASSERT(dumb_state.deadline.val == now.val + (5 * SECOND));
+
+ /* 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 == false);
+ 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;
+
+ TEST_ASSERT(fp_enable_positive_match_secret(0, &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 == false);
+ 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();
+
+ /* 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(void)
{
/* These are independent of global state. */
@@ -622,6 +790,12 @@ void run_test(void)
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();
}
diff --git a/test/fpsensor.mocklist b/test/fpsensor.mocklist
index 9bed932526..9ddc52a0d1 100644
--- a/test/fpsensor.mocklist
+++ b/test/fpsensor.mocklist
@@ -4,4 +4,5 @@
*/
#define CONFIG_TEST_MOCK_LIST \
- MOCK(FPSENSOR)
+ MOCK(FPSENSOR) \
+ MOCK(TIMER)