summaryrefslogtreecommitdiff
path: root/board/cr50/dcrypto/u2f.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/cr50/dcrypto/u2f.c')
-rw-r--r--board/cr50/dcrypto/u2f.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/board/cr50/dcrypto/u2f.c b/board/cr50/dcrypto/u2f.c
index e8f6584c69..414a8fe41a 100644
--- a/board/cr50/dcrypto/u2f.c
+++ b/board/cr50/dcrypto/u2f.c
@@ -158,6 +158,7 @@ static enum ec_error_list u2f_origin_user_key_pair(
struct drbg_ctx drbg;
size_t key_handle_size = 0;
uint8_t *key_handle = NULL;
+ enum dcrypto_result result;
if (kh_version == 0) {
key_handle_size = sizeof(struct u2f_key_handle_v0);
@@ -205,8 +206,12 @@ static enum ec_error_list u2f_origin_user_key_pair(
hmac_drbg_generate(&drbg, key_seed, sizeof(key_seed), dev_salt,
P256_NBYTES);
}
- if (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, key_seed))
+ result = DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, key_seed);
+
+ if (result == DCRYPTO_RETRY)
return EC_ERROR_TRY_AGAIN;
+ else if (result != DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
#ifdef CR50_DEV_U2F_VERBOSE
ccprintf("user private key %ph\n", HEX_BUF(d, sizeof(*d)));
@@ -418,7 +423,8 @@ enum ec_error_list u2f_sign(const struct u2f_state *state,
/* Sign. */
hmac_drbg_init_rfc6979(&ctx, &origin_d, &h);
- result = (dcrypto_p256_ecdsa_sign(&ctx, &origin_d, &h, &r, &s) != 0) ?
+ result = (dcrypto_p256_ecdsa_sign(&ctx, &origin_d, &h, &r, &s) ==
+ DCRYPTO_OK) ?
EC_SUCCESS :
EC_ERROR_HW_INTERNAL;
@@ -443,10 +449,11 @@ enum ec_error_list u2f_sign(const struct u2f_state *state,
static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
p256_int *pk_x, p256_int *pk_y)
{
- uint32_t buf[SHA256_DIGEST_WORDS];
+ struct sha256_digest buf;
+ enum dcrypto_result result;
/* Incorporate HIK & diversification constant. */
- if (!app_hw_device_id(U2F_ATTEST, state->salt, buf))
+ if (!app_hw_device_id(U2F_ATTEST, state->salt, buf.b32))
return false;
/* Check that U2F state is valid. */
@@ -455,14 +462,19 @@ static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
if (state->drbg_entropy_size != 64) {
/* Generate unbiased private key (non-FIPS path). */
- while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
- (uint8_t *)buf)) {
- struct sha256_ctx sha;
-
- SHA256_hw_init(&sha);
- SHA256_update(&sha, buf, sizeof(buf));
- memcpy(buf, SHA256_final(&sha), sizeof(buf));
- }
+ do {
+ result = DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
+ buf.b8);
+ switch (result) {
+ case DCRYPTO_OK:
+ break;
+ case DCRYPTO_RETRY:
+ SHA256_hw_hash(buf.b8, sizeof(buf), &buf);
+ break;
+ default: /* Any other result is error. */
+ return false;
+ }
+ } while (result != DCRYPTO_OK);
} else {
struct drbg_ctx drbg;
uint8_t key_candidate[P256_NBYTES];
@@ -480,10 +492,14 @@ static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
* Additional data = constant coming from HW.
*/
hmac_drbg_generate(&drbg, key_candidate,
- sizeof(key_candidate), buf,
+ sizeof(key_candidate), buf.b32,
sizeof(buf));
- } while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
- key_candidate));
+ result = DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
+ key_candidate);
+ } while (result == DCRYPTO_RETRY);
+
+ if (result != DCRYPTO_OK)
+ return false;
}
return true;
@@ -554,7 +570,8 @@ enum ec_error_list u2f_attest(const struct u2f_state *state,
/* Sign over the response w/ the attestation key. */
hmac_drbg_init_rfc6979(&dr_ctx, &d, &h);
- result = (dcrypto_p256_ecdsa_sign(&dr_ctx, &d, &h, &r, &s) != 0) ?
+ result = (dcrypto_p256_ecdsa_sign(&dr_ctx, &d, &h, &r, &s) ==
+ DCRYPTO_OK) ?
EC_SUCCESS :
EC_ERROR_HW_INTERNAL;
p256_clear(&d);