Skip to content

Commit

Permalink
calculated large blob key
Browse files Browse the repository at this point in the history
  • Loading branch information
z4yx committed Oct 18, 2023
1 parent 14a6567 commit 0327e26
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 5 deletions.
1 change: 0 additions & 1 deletion applets/ctap/ctap-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ typedef struct {
user_entity user;
bool deleted;
bool has_large_blob_key;
uint8_t large_blob_key[LARGE_BLOB_KEY_SIZE];
uint8_t cred_blob_len;
uint8_t cred_blob[MAX_CRED_BLOB_LENGTH];
} __packed CTAP_discoverable_credential;
Expand Down
19 changes: 15 additions & 4 deletions applets/ctap/ctap.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,6 @@ static uint8_t ctap_make_credential(CborEncoder *encoder, uint8_t *params, size_
memcpy(&dc.credential_id, data_buf + 55, sizeof(dc.credential_id));
memcpy(&dc.user, &mc.user, sizeof(user_entity)); // c
dc.has_large_blob_key = mc.ext_large_blob_key;
if (dc.has_large_blob_key) random_buffer(dc.large_blob_key, LARGE_BLOB_KEY_SIZE);
dc.cred_blob_len = 0;
if (mc.ext_has_cred_blob && mc.ext_cred_blob_len <= MAX_CRED_BLOB_LENGTH) {
dc.cred_blob_len = mc.ext_cred_blob_len;
Expand Down Expand Up @@ -704,9 +703,13 @@ static uint8_t ctap_make_credential(CborEncoder *encoder, uint8_t *params, size_
CHECK_CBOR_RET(ret);

if (mc.ext_large_blob_key) {
uint8_t *large_blob_key = dc.cred_blob; // reuse buffer
static_assert(LARGE_BLOB_KEY_SIZE <= MAX_CRED_BLOB_LENGTH, "Reuse buffer");
ret = make_large_blob_key(dc.credential_id.nonce, large_blob_key);
CHECK_CBOR_RET(ret);
ret = cbor_encode_int(&map, MC_RESP_LARGE_BLOB_KEY);
CHECK_CBOR_RET(ret);
ret = cbor_encode_byte_string(&map, dc.large_blob_key, LARGE_BLOB_KEY_SIZE);
ret = cbor_encode_byte_string(&map, large_blob_key, LARGE_BLOB_KEY_SIZE);
CHECK_CBOR_RET(ret);
}

Expand Down Expand Up @@ -1157,9 +1160,13 @@ static uint8_t ctap_get_assertion(CborEncoder *encoder, uint8_t *params, size_t
}

if (dc.has_large_blob_key) {
uint8_t *large_blob_key = dc.cred_blob; // reuse buffer
static_assert(LARGE_BLOB_KEY_SIZE <= MAX_CRED_BLOB_LENGTH, "Reuse buffer");
ret = make_large_blob_key(dc.credential_id.nonce, large_blob_key);
CHECK_CBOR_RET(ret);
ret = cbor_encode_int(&map, GA_RESP_LARGE_BLOB_KEY);
CHECK_CBOR_RET(ret);
ret = cbor_encode_byte_string(&map, dc.large_blob_key, LARGE_BLOB_KEY_SIZE);
ret = cbor_encode_byte_string(&map, large_blob_key, LARGE_BLOB_KEY_SIZE);
CHECK_CBOR_RET(ret);
}

Expand Down Expand Up @@ -1810,9 +1817,13 @@ static uint8_t ctap_credential_management(CborEncoder *encoder, const uint8_t *p
ret = cbor_encode_int(&map, dc.credential_id.nonce[CREDENTIAL_NONCE_CP_POS]);
CHECK_CBOR_RET(ret);
if (dc.has_large_blob_key) {
uint8_t *large_blob_key = dc.cred_blob; // reuse buffer
static_assert(LARGE_BLOB_KEY_SIZE <= MAX_CRED_BLOB_LENGTH, "Reuse buffer");
ret = make_large_blob_key(dc.credential_id.nonce, large_blob_key);
CHECK_CBOR_RET(ret);
ret = cbor_encode_int(&map, CM_RESP_LARGE_BLOB_KEY);
CHECK_CBOR_RET(ret);
ret = cbor_encode_byte_string(&map, dc.large_blob_key, LARGE_BLOB_KEY_SIZE);
ret = cbor_encode_byte_string(&map, large_blob_key, LARGE_BLOB_KEY_SIZE);
CHECK_CBOR_RET(ret);
}
ret = cbor_encoder_close_container(encoder, &map);
Expand Down
16 changes: 16 additions & 0 deletions applets/ctap/secret.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,19 @@ int make_hmac_secret_output(uint8_t *nonce, uint8_t *salt, uint8_t len, uint8_t
if (len == 64) hmac_sha256(hmac_buf, HE_KEY_SIZE, salt + 32, 32, output + 32);
return 0;
}

int make_large_blob_key(uint8_t *nonce, uint8_t *output) {
static_assert(LARGE_BLOB_KEY_SIZE == HE_KEY_SIZE, "Reuse buffer");
// use hmac-sha256(transform(HE_KEY), credential_id::nonce) as LargeBlobKey
int err = read_he_key(output);
if (err < 0) return err;

// make it different from hmac extension key
output[0] ^= output[1];
output[1] ^= output[2];
output[HE_KEY_SIZE-2] ^= output[0];
output[HE_KEY_SIZE-1] ^= output[3];

hmac_sha256(output, HE_KEY_SIZE, nonce, CREDENTIAL_NONCE_SIZE, output);
return 0;
}
1 change: 1 addition & 0 deletions applets/ctap/secret.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@ int verify_pin_hash(uint8_t *buf);
int get_pin_retries(void);
int set_pin_retries(uint8_t ctr);
int make_hmac_secret_output(uint8_t *nonce, uint8_t *salt, uint8_t len, uint8_t *output, bool uv);
int make_large_blob_key(uint8_t *nonce, uint8_t *output);

#endif // CANOKEY_CORE_FIDO2_SECRET_H_

0 comments on commit 0327e26

Please sign in to comment.