summaryrefslogtreecommitdiff
path: root/board/cr50/u2f_state_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/cr50/u2f_state_load.c')
-rw-r--r--board/cr50/u2f_state_load.c198
1 files changed, 0 insertions, 198 deletions
diff --git a/board/cr50/u2f_state_load.c b/board/cr50/u2f_state_load.c
deleted file mode 100644
index a1c8927dab..0000000000
--- a/board/cr50/u2f_state_load.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* Copyright 2021 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 "console.h"
-#include "new_nvmem.h"
-#include "nvmem.h"
-#include "nvmem_vars.h"
-#include "tpm_nvmem_ops.h"
-#include "tpm_vendor_cmds.h"
-#include "u2f_impl.h"
-#include "util.h"
-
-/* For test/u2f.c we provide a mock-up implementation of u2f_get_state(). */
-#ifndef U2F_TEST
-static const uint8_t k_salt = NVMEM_VAR_G2F_SALT;
-static const uint8_t k_salt_deprecated = NVMEM_VAR_U2F_SALT;
-
-#define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ##args)
-
-bool u2f_load_or_create_state(struct u2f_state *state, bool force_create)
-{
- bool g2f_secret_was_created = false;
-
- const struct tuple *t_salt = NULL;
-
- t_salt = getvar(&k_salt, sizeof(k_salt));
-
- if (force_create && t_salt) {
- /* Remove k_salt variable first. */
- freevar(t_salt);
- setvar(&k_salt, sizeof(k_salt), NULL, 0);
- t_salt = NULL;
- }
-
- /* Load or create G2F secret. */
- if (!t_salt) {
- g2f_secret_was_created = true;
- if (u2f_generate_g2f_secret(state) != EC_SUCCESS)
- return false;
-
- /* Delete the old salt if present, no-op if not. */
- if (setvar(&k_salt_deprecated, sizeof(k_salt_deprecated), NULL,
- 0) != EC_SUCCESS)
- return false;
- if (setvar(&k_salt, sizeof(k_salt),
- (const uint8_t *)state->salt,
- sizeof(state->salt)) != EC_SUCCESS)
- return false;
- } else {
- memcpy(state->salt, tuple_val(t_salt), sizeof(state->salt));
- freevar(t_salt);
- }
-
- /* Load or create HMAC key. Force creation if G2F wasn't loaded. */
- if (g2f_secret_was_created ||
- read_tpm_nvmem_hidden(TPM_HIDDEN_U2F_KEK, sizeof(state->hmac_key),
- state->hmac_key) != TPM_READ_SUCCESS) {
- if (u2f_generate_hmac_key(state) != EC_SUCCESS)
- return false;
-
- if (write_tpm_nvmem_hidden(
- TPM_HIDDEN_U2F_KEK, sizeof(state->hmac_key),
- state->hmac_key, 1 /* commit */) == TPM_WRITE_FAIL)
- return false;
- }
-
- /* Load or create DRBG entropy. Force creation if G2F wasn't loaded. */
- state->drbg_entropy_size = read_tpm_nvmem_size(TPM_HIDDEN_U2F_KH_SALT);
-
- if (g2f_secret_was_created ||
- ((state->drbg_entropy_size != sizeof(state->drbg_entropy)) &&
- (state->drbg_entropy_size != 32)) ||
- (read_tpm_nvmem_hidden(TPM_HIDDEN_U2F_KH_SALT,
- state->drbg_entropy_size,
- state->drbg_entropy) != TPM_READ_SUCCESS)) {
-
- if (u2f_generate_drbg_entropy(state) != EC_SUCCESS)
- return false;
-
- /**
- * We are in the inconsistent state with only G2F valid.
- * This could be a result of very old platform being updated.
- * In such case continue to use old, non FIPS path which is
- * indicated by 'old' DRBG entropy size.
- *
- * Note, that if keys weren't properly created all at once it
- * will continue in non-FIPS mode until keys are deleted and
- * properly created again.
- */
- if (!g2f_secret_was_created)
- state->drbg_entropy_size = 32;
-
- if (write_tpm_nvmem_hidden(TPM_HIDDEN_U2F_KH_SALT,
- state->drbg_entropy_size,
- state->drbg_entropy,
- 1 /* commit */) == TPM_WRITE_FAIL) {
- state->drbg_entropy_size = 0;
- return false;
- }
- }
-
- /**
- * If we loaded G2F secrets, but failed to load U2F secrets, it means
- * we should continue in non FIPS mode until all keys will be recreated
- * properly.
- *
- * On first run after update:
- * 1. Load G2F key
- * 2. Failed or succeeded to load HMAC. Failing at this point means
- * DRBG load will also fail.
- * 3. Failed to load DRBG, created DRBG with size = 32 as
- * g2f_secret_was_created == false
- *
- * On subsequent runs it will load DRBG size == 32 until keys would be
- * removed and recreated.
- */
-
- return true;
-}
-
-/**
- * Get the current u2f state from the board.
- */
-static bool u2f_state_loaded;
-static struct u2f_state u2f_state;
-
-struct u2f_state *u2f_get_state(void)
-{
- if (!u2f_state_loaded)
- u2f_state_loaded = u2f_load_or_create_state(&u2f_state, false);
-
- return u2f_state_loaded ? &u2f_state : NULL;
-}
-
-enum ec_error_list u2f_gen_kek_seed(int commit)
-{
- struct u2f_state *state = u2f_get_state();
-
- if (!state)
- return EC_ERROR_UNKNOWN;
-
- if (!u2f_generate_hmac_key(state))
- return EC_ERROR_HW_INTERNAL;
-
- if (write_tpm_nvmem_hidden(TPM_HIDDEN_U2F_KEK, sizeof(state->hmac_key),
- state->hmac_key, commit) == TPM_WRITE_FAIL)
- return EC_ERROR_UNKNOWN;
-
- return EC_SUCCESS;
-}
-
-/* Can't include TPM2 headers, so just define constant locally. */
-#define HR_NV_INDEX (1U << 24)
-
-enum ec_error_list u2f_zeroize_keys(void)
-{
- const uint32_t u2fobjs[] = { TPM_HIDDEN_U2F_KEK | HR_NV_INDEX,
- TPM_HIDDEN_U2F_KH_SALT | HR_NV_INDEX, 0 };
-
- enum ec_error_list result1, result2;
-
- /* Delete NVMEM_VAR_G2F_SALT. */
- result1 = setvar(&k_salt, sizeof(k_salt), NULL, 0);
-
- /* Remove U2F keys and wipe all deleted objects. */
- result2 = nvmem_erase_tpm_data_selective(u2fobjs);
-
- always_memset(&u2f_state, 0, sizeof(u2f_state));
- u2f_state_loaded = false;
- if ((result1 == EC_SUCCESS) && (result2 != EC_SUCCESS))
- result1 = result2;
-
- return result1;
-}
-
-enum ec_error_list u2f_update_keys(void)
-{
- struct u2f_state *state = u2f_get_state();
- enum ec_error_list result = EC_SUCCESS;
-
- /* if we couldn't load state or state is not representing new keys */
- if (!state || state->drbg_entropy_size != sizeof(state->drbg_entropy)) {
- result = u2f_zeroize_keys();
- /* Force creation of new keys. */
- u2f_state_loaded = u2f_load_or_create_state(&u2f_state, true);
-
- /* try to load again */
- state = u2f_get_state();
- }
- if (!state || state->drbg_entropy_size != sizeof(state->drbg_entropy))
- result = EC_ERROR_HW_INTERNAL;
-
- return result;
-}
-
-#endif /* U2F_TEST */