summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYicheng Li <yichengli@chromium.org>2019-05-20 15:20:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-28 21:11:20 -0700
commit325d65d3b08903e7bd3c70d14875cc1dfbf1686d (patch)
tree17b15c01f43f40a658c947602efd742bdbdcc5a2
parent0d73e46eb36455652eafcf7583f4dd8112472b92 (diff)
downloadchrome-ec-325d65d3b08903e7bd3c70d14875cc1dfbf1686d.tar.gz
fpsensor: move hardware-independent code to fpsensor_state.c
Split common/fpsensor.c so that it contains only hardware-dependent code, and put hardware-independent code to common/fpsensor_state.c. This facilitates unit testing of hardware-independent code. BRANCH=nocturne BUG=chromium:952275 TEST=ran unittests Change-Id: I0c050c7affa83e7cb935e2b657b2823cafe4c35f Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1625774 Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Nicolas Norvez <norvez@chromium.org>
-rw-r--r--common/build.mk2
-rw-r--r--common/fpsensor.c166
-rw-r--r--common/fpsensor_state.c156
-rw-r--r--include/fpsensor_state.h96
4 files changed, 255 insertions, 165 deletions
diff --git a/common/build.mk b/common/build.mk
index 88b384bc51..3e08cab72d 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -150,7 +150,7 @@ common-$(CONFIG_WIRELESS)+=wireless.o
common-$(HAS_TASK_CHIPSET)+=chipset.o
common-$(HAS_TASK_CONSOLE)+=console.o console_output.o uart_buffering.o
common-$(CONFIG_CMD_MEM)+=memory_commands.o
-common-$(HAS_TASK_FPSENSOR)+=fpsensor.o
+common-$(HAS_TASK_FPSENSOR)+=fpsensor.o fpsensor_state.o
common-$(HAS_TASK_HOSTCMD)+=host_command.o ec_features.o
common-$(HAS_TASK_PDCMD)+=host_command_pd.o
common-$(HAS_TASK_KEYSCAN)+=keyboard_scan.o
diff --git a/common/fpsensor.c b/common/fpsensor.c
index 703c1f0984..ca7f25cb19 100644
--- a/common/fpsensor.c
+++ b/common/fpsensor.c
@@ -11,6 +11,7 @@
#include "console.h"
#include "ec_commands.h"
#include "fpsensor.h"
+#include "fpsensor_state.h"
#include "gpio.h"
#include "host_command.h"
#include "link_defs.h"
@@ -30,55 +31,8 @@
#error "fpsensor requires AES, AES_GCM, ROLLBACK_SECRET_SIZE and RNG"
#endif
-#if defined(HAVE_PRIVATE) && !defined(TEST_BUILD)
-#define HAVE_FP_PRIVATE_DRIVER
-#define PRIV_HEADER(header) STRINGIFY(header)
-#include PRIV_HEADER(FP_SENSOR_PRIVATE)
-#else
-#define FP_SENSOR_IMAGE_SIZE 0
-#define FP_SENSOR_RES_X 0
-#define FP_SENSOR_RES_Y 0
-#define FP_ALGORITHM_TEMPLATE_SIZE 0
-#define FP_MAX_FINGER_COUNT 0
-#endif
-#define SBP_ENC_KEY_LEN 16
-#define FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE \
- (FP_ALGORITHM_TEMPLATE_SIZE + \
- sizeof(struct ec_fp_template_encryption_metadata))
-
-/* if no special memory regions are defined, fallback on regular SRAM */
-#ifndef FP_FRAME_SECTION
-#define FP_FRAME_SECTION
-#endif
-#ifndef FP_TEMPLATE_SECTION
-#define FP_TEMPLATE_SECTION
-#endif
-
-/* Last acquired frame (aligned as it is used by arbitrary binary libraries) */
-static uint8_t fp_buffer[FP_SENSOR_IMAGE_SIZE] FP_FRAME_SECTION __aligned(4);
-/* Fingers templates for the current user */
-static uint8_t fp_template[FP_MAX_FINGER_COUNT][FP_ALGORITHM_TEMPLATE_SIZE]
- FP_TEMPLATE_SECTION;
-/* Encryption/decryption buffer */
-/* TODO: On-the-fly encryption/decryption without a dedicated buffer */
-/*
- * Store the encryption metadata at the beginning of the buffer containing the
- * ciphered data.
- */
-static uint8_t fp_enc_buffer[FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE]
- FP_TEMPLATE_SECTION;
-/* Number of used templates */
-static uint32_t templ_valid;
-/* Bitmap of the templates with local modifications */
-static uint32_t templ_dirty;
-/* Current user ID */
-static uint32_t user_id[FP_CONTEXT_USERID_WORDS];
/* Ready to encrypt a template. */
static timestamp_t encryption_deadline;
-/* Part of the IKM used to derive encryption keys received from the TPM. */
-static uint8_t tpm_seed[FP_CONTEXT_TPM_BYTES];
-/* Flag indicating whether the seed has been initialised or not. */
-static int fp_tpm_seed_is_set;
#define CPRINTF(format, args...) cprintf(CC_FP, format, ## args)
#define CPRINTS(format, args...) cprints(CC_FP, format, ## args)
@@ -88,10 +42,6 @@ static int fp_tpm_seed_is_set;
#define FP_SENSOR_IMAGE_OFFSET 0
#endif
-/* Events for the FPSENSOR task */
-#define TASK_EVENT_SENSOR_IRQ TASK_EVENT_CUSTOM_BIT(0)
-#define TASK_EVENT_UPDATE_CONFIG TASK_EVENT_CUSTOM_BIT(1)
-
#define FP_MODE_ANY_CAPTURE (FP_MODE_CAPTURE | FP_MODE_ENROLL_IMAGE | \
FP_MODE_MATCH)
#define FP_MODE_ANY_DETECT_FINGER (FP_MODE_FINGER_DOWN | FP_MODE_FINGER_UP | \
@@ -101,9 +51,6 @@ static int fp_tpm_seed_is_set;
/* Delay between 2 s of the sensor to detect finger removal */
#define FINGER_POLLING_DELAY (100*MSEC)
-static uint32_t fp_events;
-static uint32_t sensor_mode;
-
/* Timing statistics. */
static uint32_t capture_time_us;
static uint32_t matching_time_us;
@@ -112,9 +59,6 @@ static timestamp_t overall_t0;
static uint8_t timestamps_invalid;
static int8_t template_matched;
-/* Forward declaration of static function */
-static void fp_clear_context(void);
-
BUILD_ASSERT(sizeof(struct ec_fp_template_encryption_metadata) % 4 == 0);
/* Interrupt line from the fingerprint sensor */
@@ -363,7 +307,7 @@ static int derive_encryption_key(uint8_t *out_key, uint8_t *salt)
BUILD_ASSERT(SBP_ENC_KEY_LEN <= CONFIG_ROLLBACK_SECRET_SIZE);
BUILD_ASSERT(sizeof(user_id) == SHA256_DIGEST_SIZE);
- if (!fp_tpm_seed_is_set) {
+ if (!fp_tpm_seed_is_set()) {
CPRINTS("Seed hasn't been set.");
return EC_RES_ERROR;
}
@@ -407,35 +351,6 @@ static int derive_encryption_key(uint8_t *out_key, uint8_t *salt)
return EC_RES_SUCCESS;
}
-static void fp_clear_finger_context(int idx)
-{
- memset(fp_template[idx], 0, sizeof(fp_template[0]));
-}
-
-static void fp_clear_context(void)
-{
- int idx;
-
- templ_valid = 0;
- templ_dirty = 0;
- memset(fp_buffer, 0, sizeof(fp_buffer));
- memset(fp_enc_buffer, 0, sizeof(fp_enc_buffer));
- memset(user_id, 0, sizeof(user_id));
- for (idx = 0; idx < FP_MAX_FINGER_COUNT; idx++)
- fp_clear_finger_context(idx);
- /* TODO maybe shutdown and re-init the private libraries ? */
-}
-
-static int fp_get_next_event(uint8_t *out)
-{
- uint32_t event_out = atomic_read_clear(&fp_events);
-
- memcpy(out, &event_out, sizeof(event_out));
-
- return sizeof(event_out);
-}
-DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_FINGERPRINT, fp_get_next_event);
-
static int fp_command_passthru(struct host_cmd_handler_args *args)
{
const struct ec_params_fp_passthru *params = args->params;
@@ -468,51 +383,6 @@ static int fp_command_passthru(struct host_cmd_handler_args *args)
}
DECLARE_HOST_COMMAND(EC_CMD_FP_PASSTHRU, fp_command_passthru, EC_VER_MASK(0));
-static int validate_fp_mode(const uint32_t mode)
-{
- uint32_t capture_type = FP_CAPTURE_TYPE(mode);
- uint32_t algo_mode = mode & ~FP_MODE_CAPTURE_TYPE_MASK;
- uint32_t cur_mode = sensor_mode;
-
- if (capture_type >= FP_CAPTURE_TYPE_MAX)
- return EC_ERROR_INVAL;
-
- if (algo_mode & ~FP_VALID_MODES)
- return EC_ERROR_INVAL;
-
- /* Don't allow sensor reset if any other mode is
- * set (including FP_MODE_RESET_SENSOR itself). */
- if (mode & FP_MODE_RESET_SENSOR) {
- if (cur_mode & FP_VALID_MODES)
- return EC_ERROR_INVAL;
- }
-
- return EC_SUCCESS;
-}
-
-static int fp_command_mode(struct host_cmd_handler_args *args)
-{
- const struct ec_params_fp_mode *p = args->params;
- struct ec_response_fp_mode *r = args->response;
- int ret;
-
- ret = validate_fp_mode(p->mode);
- if (ret != EC_SUCCESS) {
- CPRINTS("Invalid FP mode 0x%x", p->mode);
- return EC_RES_INVALID_PARAM;
- }
-
- if (!(p->mode & FP_MODE_DONT_CHANGE)) {
- sensor_mode = p->mode;
- task_set_event(TASK_ID_FPSENSOR, TASK_EVENT_UPDATE_CONFIG, 0);
- }
-
- r->mode = sensor_mode;
- args->response_size = sizeof(*r);
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_FP_MODE, fp_command_mode, EC_VER_MASK(0));
-
static int fp_command_info(struct host_cmd_handler_args *args)
{
struct ec_response_fp_info *r = args->response;
@@ -791,38 +661,6 @@ static int fp_command_template(struct host_cmd_handler_args *args)
}
DECLARE_HOST_COMMAND(EC_CMD_FP_TEMPLATE, fp_command_template, EC_VER_MASK(0));
-static int fp_command_context(struct host_cmd_handler_args *args)
-{
- const struct ec_params_fp_context *params = args->params;
-
- fp_clear_context();
-
- memcpy(user_id, params->userid, sizeof(user_id));
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_FP_CONTEXT, fp_command_context, EC_VER_MASK(0));
-
-static int fp_command_tpm_seed(struct host_cmd_handler_args *args)
-{
- const struct ec_params_fp_seed *params = args->params;
-
- if (params->struct_version != FP_TEMPLATE_FORMAT_VERSION) {
- CPRINTS("Invalid seed format %d", params->struct_version);
- return EC_RES_INVALID_PARAM;
- }
-
- if (fp_tpm_seed_is_set) {
- CPRINTS("Seed has already been set.");
- return EC_RES_ACCESS_DENIED;
- }
- memcpy(tpm_seed, params->seed, sizeof(tpm_seed));
- fp_tpm_seed_is_set = 1;
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_FP_SEED, fp_command_tpm_seed, EC_VER_MASK(0));
-
#ifdef CONFIG_CMD_FPSENSOR_DEBUG
/* --- Debug console commands --- */
diff --git a/common/fpsensor_state.c b/common/fpsensor_state.c
new file mode 100644
index 0000000000..c9beeb1f82
--- /dev/null
+++ b/common/fpsensor_state.c
@@ -0,0 +1,156 @@
+/* Copyright 2017 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 "common.h"
+#include "ec_commands.h"
+#include "fpsensor.h"
+#include "fpsensor_state.h"
+#include "host_command.h"
+#include "system.h"
+#include "task.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_FP, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_FP, format, ## args)
+
+/* Last acquired frame (aligned as it is used by arbitrary binary libraries) */
+uint8_t fp_buffer[FP_SENSOR_IMAGE_SIZE] FP_FRAME_SECTION __aligned(4);
+/* Fingers templates for the current user */
+uint8_t fp_template[FP_MAX_FINGER_COUNT][FP_ALGORITHM_TEMPLATE_SIZE]
+ FP_TEMPLATE_SECTION;
+/* Encryption/decryption buffer */
+/* TODO: On-the-fly encryption/decryption without a dedicated buffer */
+/*
+ * Store the encryption metadata at the beginning of the buffer containing the
+ * ciphered data.
+ */
+uint8_t fp_enc_buffer[FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE]
+ FP_TEMPLATE_SECTION;
+/* Number of used templates */
+uint32_t templ_valid;
+/* Bitmap of the templates with local modifications */
+uint32_t templ_dirty;
+/* Current user ID */
+uint32_t user_id[FP_CONTEXT_USERID_WORDS];
+/* Part of the IKM used to derive encryption keys received from the TPM. */
+uint8_t tpm_seed[FP_CONTEXT_TPM_BYTES];
+/* Flag indicating whether the seed has been initialised or not. */
+static int fp_tpm_seed_set;
+
+uint32_t fp_events;
+
+uint32_t sensor_mode;
+
+void fp_clear_finger_context(int idx)
+{
+ memset(fp_template[idx], 0, sizeof(fp_template[0]));
+}
+
+void fp_clear_context(void)
+{
+ int idx;
+
+ templ_valid = 0;
+ templ_dirty = 0;
+ memset(fp_buffer, 0, sizeof(fp_buffer));
+ memset(fp_enc_buffer, 0, sizeof(fp_enc_buffer));
+ memset(user_id, 0, sizeof(user_id));
+ for (idx = 0; idx < FP_MAX_FINGER_COUNT; idx++)
+ fp_clear_finger_context(idx);
+ /* TODO maybe shutdown and re-init the private libraries ? */
+}
+
+int fp_get_next_event(uint8_t *out)
+{
+ uint32_t event_out = atomic_read_clear(&fp_events);
+
+ memcpy(out, &event_out, sizeof(event_out));
+
+ return sizeof(event_out);
+}
+DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_FINGERPRINT, fp_get_next_event);
+
+static int fp_command_tpm_seed(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_fp_seed *params = args->params;
+
+ if (params->struct_version != FP_TEMPLATE_FORMAT_VERSION) {
+ CPRINTS("Invalid seed format %d", params->struct_version);
+ return EC_RES_INVALID_PARAM;
+ }
+
+ if (fp_tpm_seed_set) {
+ CPRINTS("Seed has already been set.");
+ return EC_RES_ACCESS_DENIED;
+ }
+ memcpy(tpm_seed, params->seed, sizeof(tpm_seed));
+ fp_tpm_seed_set = 1;
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_FP_SEED, fp_command_tpm_seed, EC_VER_MASK(0));
+
+int fp_tpm_seed_is_set(void)
+{
+ return fp_tpm_seed_set;
+}
+
+static int validate_fp_mode(const uint32_t mode)
+{
+ uint32_t capture_type = FP_CAPTURE_TYPE(mode);
+ uint32_t algo_mode = mode & ~FP_MODE_CAPTURE_TYPE_MASK;
+ uint32_t cur_mode = sensor_mode;
+
+ if (capture_type >= FP_CAPTURE_TYPE_MAX)
+ return EC_ERROR_INVAL;
+
+ if (algo_mode & ~FP_VALID_MODES)
+ return EC_ERROR_INVAL;
+
+ /* Don't allow sensor reset if any other mode is
+ * set (including FP_MODE_RESET_SENSOR itself).
+ */
+ if (mode & FP_MODE_RESET_SENSOR) {
+ if (cur_mode & FP_VALID_MODES)
+ return EC_ERROR_INVAL;
+ }
+
+ return EC_SUCCESS;
+}
+
+static int fp_command_mode(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_fp_mode *p = args->params;
+ struct ec_response_fp_mode *r = args->response;
+ int ret;
+
+ ret = validate_fp_mode(p->mode);
+ if (ret != EC_SUCCESS) {
+ CPRINTS("Invalid FP mode 0x%x", p->mode);
+ return EC_RES_INVALID_PARAM;
+ }
+
+ if (!(p->mode & FP_MODE_DONT_CHANGE)) {
+ sensor_mode = p->mode;
+ task_set_event(TASK_ID_FPSENSOR, TASK_EVENT_UPDATE_CONFIG, 0);
+ }
+
+ r->mode = sensor_mode;
+ args->response_size = sizeof(*r);
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_FP_MODE, fp_command_mode, EC_VER_MASK(0));
+
+static int fp_command_context(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_fp_context *params = args->params;
+
+ fp_clear_context();
+
+ memcpy(user_id, params->userid, sizeof(user_id));
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_FP_CONTEXT, fp_command_context, EC_VER_MASK(0));
diff --git a/include/fpsensor_state.h b/include/fpsensor_state.h
new file mode 100644
index 0000000000..3033ec19b4
--- /dev/null
+++ b/include/fpsensor_state.h
@@ -0,0 +1,96 @@
+/* Copyright 2017 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.
+ */
+
+/* Fingerprint sensor interface */
+
+#ifndef __CROS_EC_FPSENSOR_STATE_H
+#define __CROS_EC_FPSENSOR_STATE_H
+
+#include <stdint.h>
+#include "common.h"
+#include "ec_commands.h"
+#include "link_defs.h"
+
+/* if no special memory regions are defined, fallback on regular SRAM */
+#ifndef FP_FRAME_SECTION
+#define FP_FRAME_SECTION
+#endif
+#ifndef FP_TEMPLATE_SECTION
+#define FP_TEMPLATE_SECTION
+#endif
+
+#if defined(HAVE_PRIVATE) && !defined(TEST_BUILD)
+#define HAVE_FP_PRIVATE_DRIVER
+#define PRIV_HEADER(header) STRINGIFY(header)
+#include PRIV_HEADER(FP_SENSOR_PRIVATE)
+#else
+#define FP_SENSOR_IMAGE_SIZE 0
+#define FP_SENSOR_RES_X 0
+#define FP_SENSOR_RES_Y 0
+#define FP_ALGORITHM_TEMPLATE_SIZE 0
+#define FP_MAX_FINGER_COUNT 0
+#endif
+#define SBP_ENC_KEY_LEN 16
+#define FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE \
+ (FP_ALGORITHM_TEMPLATE_SIZE + \
+ sizeof(struct ec_fp_template_encryption_metadata))
+
+/* Events for the FPSENSOR task */
+#define TASK_EVENT_SENSOR_IRQ TASK_EVENT_CUSTOM_BIT(0)
+#define TASK_EVENT_UPDATE_CONFIG TASK_EVENT_CUSTOM_BIT(1)
+
+/* --- Global variables defined in fpsensor_state.c --- */
+
+/* Last acquired frame (aligned as it is used by arbitrary binary libraries) */
+extern uint8_t fp_buffer[FP_SENSOR_IMAGE_SIZE];
+/* Fingers templates for the current user */
+extern uint8_t fp_template[FP_MAX_FINGER_COUNT][FP_ALGORITHM_TEMPLATE_SIZE];
+/* Encryption/decryption buffer */
+/* TODO: On-the-fly encryption/decryption without a dedicated buffer */
+/*
+ * Store the encryption metadata at the beginning of the buffer containing the
+ * ciphered data.
+ */
+extern uint8_t fp_enc_buffer[FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE];
+/* Number of used templates */
+extern uint32_t templ_valid;
+/* Bitmap of the templates with local modifications */
+extern uint32_t templ_dirty;
+/* Current user ID */
+extern uint32_t user_id[FP_CONTEXT_USERID_WORDS];
+/* Part of the IKM used to derive encryption keys received from the TPM. */
+extern uint8_t tpm_seed[FP_CONTEXT_TPM_BYTES];
+
+extern uint32_t fp_events;
+
+extern uint32_t sensor_mode;
+
+/*
+ * Clear one fingerprint template.
+ *
+ * @param idx the index of the template to clear.
+ */
+void fp_clear_finger_context(int idx);
+
+/*
+ * Clear all fingerprint templates associated with the current user id.
+ */
+void fp_clear_context(void);
+
+/*
+ * Get the next FP event.
+ *
+ * @param out the pointer to the output event.
+ */
+int fp_get_next_event(uint8_t *out);
+
+/*
+ * Check if FP TPM seed has been set.
+ *
+ * @return 1 if the seed has been set, 0 otherwise.
+ */
+int fp_tpm_seed_is_set(void);
+
+#endif /* __CROS_EC_FPSENSOR_STATE_H */