diff options
Diffstat (limited to 'board/cr50/dcrypto/u2f.c')
-rw-r--r-- | board/cr50/dcrypto/u2f.c | 49 |
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); |