diff options
Diffstat (limited to 'board/cr50/dcrypto/u2f_impl.h')
-rw-r--r-- | board/cr50/dcrypto/u2f_impl.h | 229 |
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 */ |