Loading credential if it belongs to U2F.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -52,24 +52,7 @@ int cmd_authenticate() {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
if (P1(apdu) == CTAP_AUTH_CHECK_ONLY) {
|
||||
for (int i = 0; i < KEY_PATH_ENTRIES; i++) {
|
||||
uint32_t k = *(uint32_t *)&req->keyHandle[i*sizeof(uint32_t)];
|
||||
if (!(k & 0x80000000)) {
|
||||
mbedtls_ecdsa_free(&key);
|
||||
return SW_WRONG_DATA();
|
||||
}
|
||||
}
|
||||
uint8_t hmac[32], d[32];
|
||||
ret = mbedtls_ecp_write_key(&key, d, sizeof(d));
|
||||
mbedtls_ecdsa_free(&key);
|
||||
if (ret != 0)
|
||||
return SW_WRONG_DATA();
|
||||
uint8_t key_base[CTAP_APPID_SIZE + KEY_PATH_LEN];
|
||||
memcpy(key_base, req->appId, CTAP_APPID_SIZE);
|
||||
memcpy(key_base + CTAP_APPID_SIZE, req->keyHandle, KEY_PATH_LEN);
|
||||
ret = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), d, 32, key_base, sizeof(key_base), hmac);
|
||||
mbedtls_platform_zeroize(d, sizeof(d));
|
||||
if (memcmp(req->keyHandle + KEY_PATH_LEN, hmac, sizeof(hmac)) != 0)
|
||||
if (verify_key(req->appId, req->keyHandle, &key) != 0)
|
||||
return SW_WRONG_DATA();
|
||||
return SW_CONDITIONS_NOT_SATISFIED();
|
||||
}
|
||||
|
||||
@@ -104,14 +104,17 @@ int credential_create(CborCharString *rpId, CborByteString *userId, CborCharStri
|
||||
|
||||
int credential_load(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash, Credential *cred) {
|
||||
int ret = 0;
|
||||
CborError error;
|
||||
uint8_t *copy_cred_id = (uint8_t *)calloc(1, cred_id_len);
|
||||
memcpy(copy_cred_id, cred_id, cred_id_len);
|
||||
ret = credential_verify(copy_cred_id, cred_id_len, rp_id_hash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (ret != 0) { // U2F?
|
||||
if (cred_id_len != KEY_HANDLE_LEN || verify_key(rp_id_hash, cred_id, NULL) != 0)
|
||||
CBOR_ERROR(CTAP2_ERR_INVALID_CREDENTIAL);
|
||||
}
|
||||
else {
|
||||
CborParser parser;
|
||||
CborValue map;
|
||||
CborError error;
|
||||
memset(cred, 0, sizeof(Credential));
|
||||
cred->curve = FIDO2_CURVE_P256;
|
||||
cred->alg = FIDO2_ALG_ES256;
|
||||
@@ -152,6 +155,7 @@ int credential_load(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *r
|
||||
CBOR_ADVANCE(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
cred->id.present = true;
|
||||
cred->id.data = (uint8_t *)calloc(1, cred_id_len);
|
||||
memcpy(cred->id.data, cred_id, cred_id_len);
|
||||
|
||||
@@ -124,6 +124,36 @@ int load_keydev(uint8_t *key) {
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *key) {
|
||||
for (int i = 0; i < KEY_PATH_ENTRIES; i++) {
|
||||
uint32_t k = *(uint32_t *)&keyHandle[i*sizeof(uint32_t)];
|
||||
if (!(k & 0x80000000)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
mbedtls_ecdsa_context ctx;
|
||||
if (key == NULL) {
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
key = &ctx;
|
||||
if (derive_key(appId, false, (uint8_t *)keyHandle, MBEDTLS_ECP_DP_SECP256R1, &ctx) != 0) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
uint8_t hmac[32], d[32];
|
||||
int ret = mbedtls_ecp_write_key(key, d, sizeof(d));
|
||||
if (key == NULL)
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
if (ret != 0)
|
||||
return -2;
|
||||
uint8_t key_base[CTAP_APPID_SIZE + KEY_PATH_LEN];
|
||||
memcpy(key_base, appId, CTAP_APPID_SIZE);
|
||||
memcpy(key_base + CTAP_APPID_SIZE, keyHandle, KEY_PATH_LEN);
|
||||
ret = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), d, 32, key_base, sizeof(key_base), hmac);
|
||||
mbedtls_platform_zeroize(d, sizeof(d));
|
||||
return memcmp(keyHandle + KEY_PATH_LEN, hmac, sizeof(hmac));
|
||||
}
|
||||
|
||||
int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int curve, mbedtls_ecdsa_context *key) {
|
||||
uint8_t outk[64] = {0};
|
||||
int r = 0;
|
||||
@@ -131,8 +161,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
|
||||
if ((r = load_keydev(outk)) != CCID_OK)
|
||||
return r;
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
||||
for (int i = 0; i < KEY_PATH_ENTRIES; i++)
|
||||
{
|
||||
for (int i = 0; i < KEY_PATH_ENTRIES; i++) {
|
||||
if (new_key == true) {
|
||||
uint32_t val = 0;
|
||||
random_gen(NULL, (uint8_t *) &val, sizeof(val));
|
||||
@@ -140,8 +169,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
|
||||
memcpy(&key_handle[i*sizeof(uint32_t)], &val, sizeof(uint32_t));
|
||||
}
|
||||
r = mbedtls_hkdf(md_info, &key_handle[i * sizeof(uint32_t)], sizeof(uint32_t), outk, 32, outk + 32, 32, outk, sizeof(outk));
|
||||
if (r != 0)
|
||||
{
|
||||
if (r != 0) {
|
||||
mbedtls_platform_zeroize(outk, sizeof(outk));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
extern int scan_files(bool);
|
||||
extern int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int, mbedtls_ecdsa_context *key);
|
||||
extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *);
|
||||
extern bool wait_button_pressed();
|
||||
extern CTAPHID_FRAME *ctap_req, *ctap_resp;
|
||||
extern void init_fido(bool);
|
||||
|
||||
Reference in New Issue
Block a user