summaryrefslogtreecommitdiff
path: root/common/fpsensor/fpsensor_state.c
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2019-05-29 18:17:09 -0700
committerCommit Bot <commit-bot@chromium.org>2019-06-05 17:29:12 +0000
commitb41026d4f3bcddc97cac280bbc2e2865f5a3ec10 (patch)
treee3136bd758a6879e12e375d5a956fc5a2b9c39fb /common/fpsensor/fpsensor_state.c
parentb00dac4bf4d1727bb1e334269133d60c430a131a (diff)
downloadchrome-ec-b41026d4f3bcddc97cac280bbc2e2865f5a3ec10.tar.gz
Move fingerprint files to their own directory
We will be adding more files in the future, so this declutters the common directory. It also lets us add a separate OWNERS file. BRANCH=none BUG=chromium:968518 TEST=make buildall -j Change-Id: I22c08851fe2d5fbdb5beff8cc72a68618c85fb0e Signed-off-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1637440 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common/fpsensor/fpsensor_state.c')
-rw-r--r--common/fpsensor/fpsensor_state.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/common/fpsensor/fpsensor_state.c b/common/fpsensor/fpsensor_state.c
new file mode 100644
index 0000000000..c9beeb1f82
--- /dev/null
+++ b/common/fpsensor/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));