summaryrefslogtreecommitdiff
path: root/board/cr50/dcrypto/u2f_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'board/cr50/dcrypto/u2f_impl.h')
-rw-r--r--board/cr50/dcrypto/u2f_impl.h229
1 files changed, 229 insertions, 0 deletions
diff --git a/board/cr50/dcrypto/u2f_impl.h b/board/cr50/dcrypto/u2f_impl.h
new file mode 100644
index 0000000000..7f0f10ef36
--- /dev/null
+++ b/board/cr50/dcrypto/u2f_impl.h
@@ -0,0 +1,229 @@
+/* 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.
+ */
+
+/* U2F implementation-specific callbacks and parameters. */
+
+#ifndef __CROS_EC_U2F_IMPL_H
+#define __CROS_EC_U2F_IMPL_H
+
+#include "common.h"
+#include "dcrypto.h"
+#include "u2f.h"
+
+/* ---- platform cryptography hooks ---- */
+
+/* ---- non-volatile U2F state, shared with common code ---- */
+struct u2f_state {
+ /* G2F key gen seed. */
+ uint32_t salt[8];
+ /* HMAC key for U2F key handle authentication. */
+ uint32_t hmac_key[SHA256_DIGEST_SIZE / sizeof(uint32_t)];
+ /* Stored DRBG entropy. */
+ uint32_t drbg_entropy[16];
+ size_t drbg_entropy_size;
+};
+
+/* Make sure common declaration is compatible. */
+BUILD_ASSERT(U2F_EC_KEY_SIZE == P256_NBYTES);
+BUILD_ASSERT(sizeof(struct u2f_ec_point) == U2F_EC_POINT_SIZE);
+
+BUILD_ASSERT(sizeof(struct u2f_key_handle_v0) <= U2F_MAX_KH_SIZE);
+BUILD_ASSERT(sizeof(struct u2f_key_handle_v0) == U2F_V0_KH_SIZE);
+
+BUILD_ASSERT(sizeof(struct u2f_key_handle_v1) <= U2F_MAX_KH_SIZE);
+BUILD_ASSERT(sizeof(struct u2f_key_handle_v1) == U2F_V1_KH_SIZE);
+
+
+BUILD_ASSERT(sizeof(union u2f_key_handle_variant) <= U2F_MAX_KH_SIZE);
+
+/**
+ * Create or update DRBG entropy in U2F state. Used when changing ownership
+ * to cryptographically discard previously generated keys.
+ *
+ * @param state u2f state to update
+ *
+ * @return EC_SUCCESS if successful
+ */
+enum ec_error_list u2f_generate_drbg_entropy(struct u2f_state *state);
+
+/**
+ * Create or update HMAC key in U2F state. Used when changing ownership to
+ * cryptographically discard previously generated keys.
+ *
+ * @param state u2f state to update
+ *
+ * @return EC_SUCCESS if successful
+ */
+enum ec_error_list u2f_generate_hmac_key(struct u2f_state *state);
+
+/**
+ * Create or update G2F secret in U2F state.
+ *
+ * @param state u2f state to update
+ *
+ * @return EC_SUCCESS if successful
+ */
+enum ec_error_list u2f_generate_g2f_secret(struct u2f_state *state);
+
+/**
+ * Create a randomized key handle for specified origin, user secret.
+ * Generate associated signing key.
+ *
+ * @param state initialized u2f state
+ * @param origin pointer to origin id
+ * @param user pointer to user secret
+ * @param authTimeSecretHash authentication time secret
+ * @param kh output key handle header
+ * @param kh_version - key handle version to generate
+ * @param pubKey - generated public key
+ *
+ * @return EC_SUCCESS if successful
+ */
+enum ec_error_list u2f_generate(const struct u2f_state *state,
+ const uint8_t *user, const uint8_t *origin,
+ const uint8_t *authTimeSecretHash,
+ union u2f_key_handle_variant *kh,
+ uint8_t kh_version,
+ struct u2f_ec_point *pubKey);
+
+/**
+ * Create a randomized key handle for specified origin, user secret.
+ * Generate associated signing key.
+ *
+ * @param state initialized u2f state
+ * @param kh output key handle header
+ * @param kh_version - key handle version to generate
+ * @param origin pointer to origin id
+ * @param user pointer to user secret
+ * @param authTimeSecretHash pointer to user's authentication secret.
+ * can be set to NULL if authorization_hmac check is not needed.
+ * @param r - generated part of signature
+ * @param s - generated part of signature
+ *
+ * @return EC_SUCCESS if a valid key pair was created
+ * EC_ACCESS_DENIED if key handle can't authenticated
+ */
+enum ec_error_list u2f_sign(const struct u2f_state *state,
+ const union u2f_key_handle_variant *kh,
+ uint8_t kh_version, const uint8_t *user,
+ const uint8_t *origin,
+ const uint8_t *authTimeSecretHash,
+ const uint8_t *hash, struct u2f_signature *sig);
+
+/**
+ * Verify that key handle matches provided origin, user and user's
+ * authentication secret and was created on this device (signed with
+ * U2F state HMAC key).
+ *
+ * @param state initialized u2f state
+ * @param kh input key handle
+ * @param kh_version - key handle version to verify
+ * @param user pointer to user secret
+ * @param origin pointer to origin id
+ * @param authTimeSecretHash pointer to user's authentication secret.
+ * can be set to NULL if authorization_hmac check is not needed.
+ *
+ * @return EC_SUCCESS if handle can be authenticated
+ */
+enum ec_error_list u2f_authorize_keyhandle(const struct u2f_state *state,
+ const union u2f_key_handle_variant *kh,
+ uint8_t kh_version, const uint8_t *user,
+ const uint8_t *origin,
+ const uint8_t *authTimeSecretHash);
+
+/**
+ * Gets the x509 certificate for the attestation key pair returned
+ * by g2f_individual_keypair().
+ *
+ * @param state U2F state parameters
+ * @param serial Device serial number
+ * @param buf pointer to a buffer that must be at least
+ *
+ * G2F_ATTESTATION_CERT_MAX_LEN bytes.
+ * @return size of certificate written to buf, 0 on error.
+ */
+size_t g2f_attestation_cert_serial(const struct u2f_state *state,
+ const uint8_t *serial, uint8_t *buf);
+
+/**
+ * Verify that provided key handle and public key match.
+ * @param state U2F state parameters
+ * @param key_handle key handle
+ * @param kh_version key handle version (0 - legacy, 1 - versioned)
+ * @param user pointer to user secret
+ * @param origin pointer to origin id
+ * @param authTimeSecretHash pointer to user's authentication secret.
+ * can be set to NULL if authorization_hmac check is not needed.
+ * @param public_key pointer to public key point (big endian)
+ * @param data data to sign
+ * @param data_size data size in bytes
+ *
+ * @param r part of generated signature
+ * @param s part of generated signature
+ *
+ * @return EC_SUCCESS if public key matches key handle,
+ * (r,s) set to valid signature
+ * EC_ACCESS_DENIED if key handle can't authenticated
+ */
+enum ec_error_list u2f_attest(const struct u2f_state *state,
+ const union u2f_key_handle_variant *kh,
+ uint8_t kh_version, const uint8_t *user,
+ const uint8_t *origin,
+ const uint8_t *authTimeSecretHash,
+ const struct u2f_ec_point *public_key,
+ const uint8_t *data, size_t data_size,
+ struct u2f_signature *sig);
+
+
+/**
+ *
+ * Board U2F key management part implemented.
+ *
+ */
+
+/**
+ * Get the current u2f state from the board.
+ *
+ * @return pointer to static state if successful, NULL otherwise
+ */
+struct u2f_state *u2f_get_state(void);
+
+/**
+ * Try to load U2F keys or create if failed.
+ *
+ * @param state - buffer for state to load/create
+ * @param force_create - if true, always create all keys
+ *
+ * @return true if state is properly initialized and will persist in flash.
+ */
+bool u2f_load_or_create_state(struct u2f_state *state, bool force_create);
+
+/***
+ * Generates and persists to nvram a new seed that will be used to
+ * derive kek in future calls to u2f_gen_kek().
+ *
+ * @param commit whether to commit nvram changes before returning.
+ * @return EC_SUCCESS if seed was successfully created
+ * (and persisted if requested).
+ */
+enum ec_error_list u2f_gen_kek_seed(int commit);
+
+/**
+ * Zeroize U2F keys. Can be used to switch to FIPS-compliant path by
+ * destroying old keys.
+ *
+ * @return true if state is properly initialized and will persist in flash.
+ */
+enum ec_error_list u2f_zeroize_keys(void);
+
+/**
+ * Update keys to a newer (FIPS-compliant) version if needed. Do nothing if
+ * keys are already updated.
+ *
+ * @return EC_SUCCESS or error code.
+ */
+enum ec_error_list u2f_update_keys(void);
+
+#endif /* __CROS_EC_U2F_IMPL_H */