Fix warnings.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2024-08-23 13:17:51 +02:00
parent dac6407134
commit 6c74db9763
20 changed files with 225 additions and 398 deletions

View File

@@ -43,12 +43,11 @@ int cbor_large_blobs(const uint8_t *data, size_t len);
extern int cmd_read_config(); extern int cmd_read_config();
const uint8_t aaguid[16] = const uint8_t aaguid[16] = { 0x89, 0xFB, 0x94, 0xB7, 0x06, 0xC9, 0x36, 0x73, 0x9B, 0x7E, 0x30, 0x52, 0x6D, 0x96, 0x81, 0x45 }; // First 16 bytes of SHA256("Pico FIDO2")
{ 0x89, 0xFB, 0x94, 0xB7, 0x06, 0xC9, 0x36, 0x73, 0x9B, 0x7E, 0x30, 0x52, 0x6D, 0x96, 0x81, 0x45 }; // First 16 bytes of SHA256("Pico FIDO2")
const uint8_t *cbor_data = NULL; const uint8_t *cbor_data = NULL;
size_t cbor_len = 0; size_t cbor_len = 0;
uint8_t cmd = 0; uint8_t cbor_cmd = 0;
int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) { int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
if (len == 0 && cmd == CTAPHID_CBOR) { if (len == 0 && cmd == CTAPHID_CBOR) {
@@ -105,7 +104,7 @@ int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
} }
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
void cbor_thread() { void cbor_thread(void) {
card_init_core1(); card_init_core1();
while (1) { while (1) {
uint32_t m; uint32_t m;
@@ -114,7 +113,7 @@ void cbor_thread() {
if (m == EV_EXIT) { if (m == EV_EXIT) {
break; break;
} }
apdu.sw = cbor_parse(cmd, cbor_data, cbor_len); apdu.sw = cbor_parse(cbor_cmd, cbor_data, cbor_len);
if (apdu.sw == 0) { if (apdu.sw == 0) {
DEBUG_DATA(res_APDU + 1, res_APDU_size); DEBUG_DATA(res_APDU + 1, res_APDU_size);
} }
@@ -137,19 +136,14 @@ void cbor_thread() {
int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len) { int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len) {
cbor_data = data; cbor_data = data;
cbor_len = len; cbor_len = len;
cmd = last_cmd; cbor_cmd = last_cmd;
ctap_resp->init.data[0] = 0; ctap_resp->init.data[0] = 0;
res_APDU = ctap_resp->init.data + 1; res_APDU = ctap_resp->init.data + 1;
res_APDU_size = 0; res_APDU_size = 0;
return 2; // CBOR processing return 2; // CBOR processing
} }
CborError COSE_key_params(int crv, CborError COSE_key_params(int crv, int alg, mbedtls_ecp_group *grp, mbedtls_ecp_point *Q, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) {
int alg,
mbedtls_ecp_group *grp,
mbedtls_ecp_point *Q,
CborEncoder *mapEncoderParent,
CborEncoder *mapEncoder) {
CborError error = CborNoError; CborError error = CborNoError;
int kty = 1; int kty = 1;
if (crv == FIDO2_CURVE_P256 || crv == FIDO2_CURVE_P384 || crv == FIDO2_CURVE_P521 || if (crv == FIDO2_CURVE_P256 || crv == FIDO2_CURVE_P384 || crv == FIDO2_CURVE_P521 ||
@@ -216,12 +210,7 @@ CborError COSE_key_shared(mbedtls_ecdh_context *key,
CborEncoder *mapEncoderParent, CborEncoder *mapEncoderParent,
CborEncoder *mapEncoder) { CborEncoder *mapEncoder) {
int crv = mbedtls_curve_to_fido(key->ctx.mbed_ecdh.grp.id), alg = FIDO2_ALG_ECDH_ES_HKDF_256; int crv = mbedtls_curve_to_fido(key->ctx.mbed_ecdh.grp.id), alg = FIDO2_ALG_ECDH_ES_HKDF_256;
return COSE_key_params(crv, return COSE_key_params(crv, alg, &key->ctx.mbed_ecdh.grp, &key->ctx.mbed_ecdh.Q, mapEncoderParent, mapEncoder);
alg,
&key->ctx.mbed_ecdh.grp,
&key->ctx.mbed_ecdh.Q,
mapEncoderParent,
mapEncoder);
} }
CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) { CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) {
CborError error = CborNoError; CborError error = CborNoError;
@@ -234,12 +223,7 @@ CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *m
err: err:
return error; return error;
} }
CborError COSE_read_key(CborValue *f, CborError COSE_read_key(CborValue *f, int64_t *kty, int64_t *alg, int64_t *crv, CborByteString *kax, CborByteString *kay) {
int64_t *kty,
int64_t *alg,
int64_t *crv,
CborByteString *kax,
CborByteString *kay) {
int64_t kkey = 0; int64_t kkey = 0;
CborError error = CborNoError; CborError error = CborNoError;
CBOR_PARSE_MAP_START(*f, 0) CBOR_PARSE_MAP_START(*f, 0)

View File

@@ -182,7 +182,7 @@ int resetPinUvAuthToken() {
return 0; return 0;
} }
int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out) { int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out) {
if (protocol == 1) { if (protocol == 1) {
memcpy(out, in, in_len); memcpy(out, in, in_len);
return aes_encrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len); return aes_encrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len);
@@ -196,7 +196,7 @@ int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_l
return -1; return -1;
} }
int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out) { int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out) {
if (protocol == 1) { if (protocol == 1) {
memcpy(out, in, in_len); memcpy(out, in, in_len);
return aes_decrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len); return aes_decrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len);
@@ -232,12 +232,11 @@ int authenticate(uint8_t protocol,
return 0; return 0;
} }
int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, size_t len, uint8_t *sign) { int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, uint16_t len, uint8_t *sign) {
uint8_t hmac[32]; uint8_t hmac[32];
//if (paut.in_use == false) //if (paut.in_use == false)
// return -2; // return -2;
int ret = int ret = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), key, 32, data, len, hmac);
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), key, 32, data, len, hmac);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
@@ -386,18 +385,17 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
uint8_t sharedSecret[64]; uint8_t sharedSecret[64];
int ret = ecdh(pinUvAuthProtocol, &hkey.ctx.mbed_ecdh.Qp, sharedSecret); int ret = ecdh((uint8_t)pinUvAuthProtocol, &hkey.ctx.mbed_ecdh.Qp, sharedSecret);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
if (verify(pinUvAuthProtocol, sharedSecret, newPinEnc.data, newPinEnc.len, if (verify((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, pinUvAuthParam.data) != 0) {
pinUvAuthParam.data) != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
uint8_t paddedNewPin[64]; uint8_t paddedNewPin[64];
ret = decrypt(pinUvAuthProtocol, sharedSecret, newPinEnc.data, newPinEnc.len, paddedNewPin); ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, paddedNewPin);
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
if (ret != 0) { if (ret != 0) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
@@ -452,7 +450,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
uint8_t sharedSecret[64]; uint8_t sharedSecret[64];
int ret = ecdh(pinUvAuthProtocol, &hkey.ctx.mbed_ecdh.Qp, sharedSecret); int ret = ecdh((uint8_t)pinUvAuthProtocol, &hkey.ctx.mbed_ecdh.Qp, sharedSecret);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
@@ -460,8 +458,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
uint8_t tmp[80 + 32]; uint8_t tmp[80 + 32];
memcpy(tmp, newPinEnc.data, newPinEnc.len); memcpy(tmp, newPinEnc.data, newPinEnc.len);
memcpy(tmp + newPinEnc.len, pinHashEnc.data, pinHashEnc.len); memcpy(tmp + newPinEnc.len, pinHashEnc.data, pinHashEnc.len);
if (verify(pinUvAuthProtocol, sharedSecret, tmp, newPinEnc.len + pinHashEnc.len, if (verify((uint8_t)pinUvAuthProtocol, sharedSecret, tmp, (uint16_t)(newPinEnc.len + pinHashEnc.len), pinUvAuthParam.data) != 0) {
pinUvAuthParam.data) != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
@@ -472,8 +469,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
low_flash_available(); low_flash_available();
uint8_t retries = pin_data[0]; uint8_t retries = pin_data[0];
uint8_t paddedNewPin[64]; uint8_t paddedNewPin[64];
ret = ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, pinHashEnc.data, (uint16_t)pinHashEnc.len, paddedNewPin);
decrypt(pinUvAuthProtocol, sharedSecret, pinHashEnc.data, pinHashEnc.len, paddedNewPin);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
@@ -496,7 +492,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
file_put_data(ef_pin, pin_data, sizeof(pin_data)); file_put_data(ef_pin, pin_data, sizeof(pin_data));
low_flash_available(); low_flash_available();
new_pin_mismatches = 0; new_pin_mismatches = 0;
ret = decrypt(pinUvAuthProtocol, sharedSecret, newPinEnc.data, newPinEnc.len, paddedNewPin); ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, paddedNewPin);
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
if (ret != 0) { if (ret != 0) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
@@ -526,11 +522,11 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
} }
file_put_data(ef_pin, hsh, 2 + 16); file_put_data(ef_pin, hsh, 2 + 16);
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) { if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) {
uint8_t *tmp = (uint8_t *) calloc(1, file_get_size(ef_minpin)); uint8_t *tmpf = (uint8_t *) calloc(1, file_get_size(ef_minpin));
memcpy(tmp, file_get_data(ef_minpin), file_get_size(ef_minpin)); memcpy(tmpf, file_get_data(ef_minpin), file_get_size(ef_minpin));
tmp[1] = 0; tmpf[1] = 0;
file_put_data(ef_minpin, tmp, file_get_size(ef_minpin)); file_put_data(ef_minpin, tmpf, file_get_size(ef_minpin));
free(tmp); free(tmpf);
} }
low_flash_available(); low_flash_available();
resetPinUvAuthToken(); resetPinUvAuthToken();
@@ -569,7 +565,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
uint8_t sharedSecret[64]; uint8_t sharedSecret[64];
int ret = ecdh(pinUvAuthProtocol, &hkey.ctx.mbed_ecdh.Qp, sharedSecret); int ret = ecdh((uint8_t)pinUvAuthProtocol, &hkey.ctx.mbed_ecdh.Qp, sharedSecret);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
@@ -580,9 +576,8 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
file_put_data(ef_pin, pin_data, sizeof(pin_data)); file_put_data(ef_pin, pin_data, sizeof(pin_data));
low_flash_available(); low_flash_available();
uint8_t retries = pin_data[0]; uint8_t retries = pin_data[0];
uint8_t paddedNewPin[64], poff = (pinUvAuthProtocol - 1) * IV_SIZE; uint8_t paddedNewPin[64], poff = ((uint8_t)pinUvAuthProtocol - 1) * IV_SIZE;
ret = ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, pinHashEnc.data, (uint16_t)pinHashEnc.len, paddedNewPin);
decrypt(pinUvAuthProtocol, sharedSecret, pinHashEnc.data, pinHashEnc.len, paddedNewPin);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
@@ -614,7 +609,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
if (subcommand == 0x05) { if (subcommand == 0x05) {
permissions = CTAP_PERMISSION_MC | CTAP_PERMISSION_GA; permissions = CTAP_PERMISSION_MC | CTAP_PERMISSION_GA;
} }
paut.permissions = permissions; paut.permissions = (uint8_t)permissions;
if (rpId.present == true) { if (rpId.present == true) {
mbedtls_sha256((uint8_t *) rpId.data, rpId.len, paut.rp_id_hash, 0); mbedtls_sha256((uint8_t *) rpId.data, rpId.len, paut.rp_id_hash, 0);
paut.has_rp_id = true; paut.has_rp_id = true;
@@ -623,7 +618,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
paut.has_rp_id = false; paut.has_rp_id = false;
} }
uint8_t pinUvAuthToken_enc[32 + IV_SIZE]; uint8_t pinUvAuthToken_enc[32 + IV_SIZE];
encrypt(pinUvAuthProtocol, sharedSecret, paut.data, 32, pinUvAuthToken_enc); encrypt((uint8_t)pinUvAuthProtocol, sharedSecret, paut.data, 32, pinUvAuthToken_enc);
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1)); CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x02)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x02));
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, pinUvAuthToken_enc, 32 + poff)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, pinUvAuthToken_enc, 32 + poff));
@@ -646,6 +641,6 @@ err:
} }
return error; return error;
} }
res_APDU_size = resp_size; res_APDU_size = (uint16_t)resp_size;
return 0; return 0;
} }

View File

@@ -39,7 +39,8 @@ int cbor_config(const uint8_t *data, size_t len) {
CborByteString pinUvAuthParam = { 0 }, vendorAutCt = { 0 }; CborByteString pinUvAuthParam = { 0 }, vendorAutCt = { 0 };
CborCharString minPinLengthRPIDs[32] = { 0 }; CborCharString minPinLengthRPIDs[32] = { 0 };
size_t resp_size = 0, raw_subpara_len = 0, minPinLengthRPIDs_len = 0; size_t resp_size = 0, raw_subpara_len = 0, minPinLengthRPIDs_len = 0;
CborEncoder encoder, mapEncoder; CborEncoder encoder;
//CborEncoder mapEncoder;
uint8_t *raw_subpara = NULL; uint8_t *raw_subpara = NULL;
const bool *forceChangePin = NULL; const bool *forceChangePin = NULL;
@@ -118,13 +119,9 @@ int cbor_config(const uint8_t *data, size_t len) {
uint8_t *verify_payload = (uint8_t *) calloc(1, 32 + 1 + 1 + raw_subpara_len); uint8_t *verify_payload = (uint8_t *) calloc(1, 32 + 1 + 1 + raw_subpara_len);
memset(verify_payload, 0xff, 32); memset(verify_payload, 0xff, 32);
verify_payload[32] = 0x0d; verify_payload[32] = 0x0d;
verify_payload[33] = subcommand; verify_payload[33] = (uint8_t)subcommand;
memcpy(verify_payload + 34, raw_subpara, raw_subpara_len); memcpy(verify_payload + 34, raw_subpara, raw_subpara_len);
error = verify(pinUvAuthProtocol, error = verify((uint8_t)pinUvAuthProtocol, paut.data, verify_payload, (uint16_t)(32 + 1 + 1 + raw_subpara_len), pinUvAuthParam.data);
paut.data,
verify_payload,
32 + 1 + 1 + raw_subpara_len,
pinUvAuthParam.data);
free(verify_payload); free(verify_payload);
if (error != CborNoError) { if (error != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
@@ -165,14 +162,7 @@ int cbor_config(const uint8_t *data, size_t len) {
random_gen(NULL, key_dev_enc, 12); random_gen(NULL, key_dev_enc, 12);
mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_init(&chatx);
mbedtls_chachapoly_setkey(&chatx, vendorAutCt.data); mbedtls_chachapoly_setkey(&chatx, vendorAutCt.data);
ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, file_get_size(ef_keydev), key_dev_enc, NULL, 0, file_get_data(ef_keydev), key_dev_enc + 12, key_dev_enc + 12 + file_get_size(ef_keydev));
file_get_size(ef_keydev),
key_dev_enc,
NULL,
0,
file_get_data(ef_keydev),
key_dev_enc + 12,
key_dev_enc + 12 + file_get_size(ef_keydev));
mbedtls_chachapoly_free(&chatx); mbedtls_chachapoly_free(&chatx);
if (ret != 0) { if (ret != 0) {
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
@@ -207,16 +197,13 @@ int cbor_config(const uint8_t *data, size_t len) {
if (file_has_data(ef_pin) && file_get_data(ef_pin)[1] < newMinPinLength) { if (file_has_data(ef_pin) && file_get_data(ef_pin)[1] < newMinPinLength) {
forceChangePin = ptrue; forceChangePin = ptrue;
} }
uint8_t *data = (uint8_t *) calloc(1, 2 + minPinLengthRPIDs_len * 32); uint8_t *dataf = (uint8_t *) calloc(1, 2 + minPinLengthRPIDs_len * 32);
data[0] = newMinPinLength; dataf[0] = (uint8_t)newMinPinLength;
data[1] = forceChangePin == ptrue ? 1 : 0; dataf[1] = forceChangePin == ptrue ? 1 : 0;
for (int m = 0; m < minPinLengthRPIDs_len; m++) { for (size_t m = 0; m < minPinLengthRPIDs_len; m++) {
mbedtls_sha256((uint8_t *) minPinLengthRPIDs[m].data, mbedtls_sha256((uint8_t *) minPinLengthRPIDs[m].data, minPinLengthRPIDs[m].len, dataf + 2 + m * 32, 0);
minPinLengthRPIDs[m].len,
data + 2 + m * 32,
0);
} }
file_put_data(ef_minpin, data, 2 + minPinLengthRPIDs_len * 32); file_put_data(ef_minpin, dataf, (uint16_t)(2 + minPinLengthRPIDs_len * 32));
low_flash_available(); low_flash_available();
goto err; //No return goto err; //No return
} }
@@ -227,13 +214,13 @@ int cbor_config(const uint8_t *data, size_t len) {
else { else {
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
} }
CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); //CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder));
resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); //resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1);
err: err:
CBOR_FREE_BYTE_STRING(pinUvAuthParam); CBOR_FREE_BYTE_STRING(pinUvAuthParam);
CBOR_FREE_BYTE_STRING(vendorAutCt); CBOR_FREE_BYTE_STRING(vendorAutCt);
for (int i = 0; i < minPinLengthRPIDs_len; i++) { for (size_t i = 0; i < minPinLengthRPIDs_len; i++) {
CBOR_FREE_BYTE_STRING(minPinLengthRPIDs[i]); CBOR_FREE_BYTE_STRING(minPinLengthRPIDs[i]);
} }
@@ -243,6 +230,6 @@ err:
} }
return error; return error;
} }
res_APDU_size = resp_size; res_APDU_size = (uint16_t)resp_size;
return 0; return 0;
} }

View File

@@ -122,8 +122,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0); cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0);
if (subcommand == 0x01) { if (subcommand == 0x01) {
if (verify(pinUvAuthProtocol, paut.data, (const uint8_t *) "\x01", 1, if (verify((uint8_t)pinUvAuthProtocol, paut.data, (const uint8_t *) "\x01", 1, pinUvAuthParam.data) != CborNoError) {
pinUvAuthParam.data) != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
if (is_preview == false && if (is_preview == false &&
@@ -132,7 +131,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
} }
uint8_t existing = 0; uint8_t existing = 0;
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
if (file_has_data(search_dynamic_file(EF_CRED + i))) { if (file_has_data(search_dynamic_file((uint16_t)(EF_CRED + i)))) {
existing++; existing++;
} }
} }
@@ -145,12 +144,10 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
else if (subcommand == 0x02 || subcommand == 0x03) { else if (subcommand == 0x02 || subcommand == 0x03) {
file_t *rp_ef = NULL; file_t *rp_ef = NULL;
if (subcommand == 0x02) { if (subcommand == 0x02) {
if (verify(pinUvAuthProtocol, paut.data, (const uint8_t *) "\x02", 1, if (verify((uint8_t)pinUvAuthProtocol, paut.data, (const uint8_t *) "\x02", 1, pinUvAuthParam.data) != CborNoError) {
pinUvAuthParam.data) != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
if (is_preview == false && if (is_preview == false && (!(paut.permissions & CTAP_PERMISSION_CM) || paut.has_rp_id == true)) {
(!(paut.permissions & CTAP_PERMISSION_CM) || paut.has_rp_id == true)) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
rp_counter = 1; rp_counter = 1;
@@ -163,7 +160,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
} }
uint8_t skip = 0; uint8_t skip = 0;
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
file_t *tef = search_dynamic_file(EF_RP + i); file_t *tef = search_dynamic_file((uint16_t)(EF_RP + i));
if (file_has_data(tef) && *file_get_data(tef) > 0) { if (file_has_data(tef) && *file_get_data(tef) > 0) {
if (++skip == rp_counter) { if (++skip == rp_counter) {
if (rp_ef == NULL) { if (rp_ef == NULL) {
@@ -202,8 +199,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
} }
if (subcommand == 0x04) { if (subcommand == 0x04) {
*(raw_subpara - 1) = 0x04; *(raw_subpara - 1) = 0x04;
if (verify(pinUvAuthProtocol, paut.data, raw_subpara - 1, raw_subpara_len + 1, if (verify((uint8_t)pinUvAuthProtocol, paut.data, raw_subpara - 1, (uint16_t)(raw_subpara_len + 1), pinUvAuthParam.data) != CborNoError) {
pinUvAuthParam.data) != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
if (is_preview == false && if (is_preview == false &&
@@ -223,7 +219,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
file_t *cred_ef = NULL; file_t *cred_ef = NULL;
uint8_t skip = 0; uint8_t skip = 0;
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
file_t *tef = search_dynamic_file(EF_CRED + i); file_t *tef = search_dynamic_file((uint16_t)(EF_CRED + i));
if (file_has_data(tef) && memcmp(file_get_data(tef), rpIdHash.data, 32) == 0) { if (file_has_data(tef) && memcmp(file_get_data(tef), rpIdHash.data, 32) == 0) {
if (++skip == cred_counter) { if (++skip == cred_counter) {
if (cred_ef == NULL) { if (cred_ef == NULL) {
@@ -243,14 +239,13 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
} }
Credential cred = { 0 }; Credential cred = { 0 };
if (credential_load(file_get_data(cred_ef) + 32, file_get_size(cred_ef) - 32, rpIdHash.data, if (credential_load(file_get_data(cred_ef) + 32, file_get_size(cred_ef) - 32, rpIdHash.data, &cred) != 0) {
&cred) != 0) {
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
} }
mbedtls_ecdsa_context key; mbedtls_ecdsa_context key;
mbedtls_ecdsa_init(&key); mbedtls_ecdsa_init(&key);
if (fido_load_key(cred.curve, cred.id.data, &key) != 0) { if (fido_load_key((int)cred.curve, cred.id.data, &key) != 0) {
credential_free(&cred); credential_free(&cred);
mbedtls_ecdsa_free(&key); mbedtls_ecdsa_free(&key);
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
@@ -290,13 +285,11 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
} }
if (cred.userName.present == true) { if (cred.userName.present == true) {
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "name")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "name"));
CBOR_CHECK(cbor_encode_text_string(&mapEncoder2, cred.userName.data, CBOR_CHECK(cbor_encode_text_string(&mapEncoder2, cred.userName.data, cred.userName.len));
cred.userName.len));
} }
if (cred.userDisplayName.present == true) { if (cred.userDisplayName.present == true) {
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "displayName")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "displayName"));
CBOR_CHECK(cbor_encode_text_string(&mapEncoder2, cred.userDisplayName.data, CBOR_CHECK(cbor_encode_text_string(&mapEncoder2, cred.userDisplayName.data, cred.userDisplayName.len));
cred.userDisplayName.len));
} }
CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2));
@@ -331,13 +324,11 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_PROCESSING); CBOR_ERROR(CTAP2_ERR_PROCESSING);
} }
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0B)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0B));
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, largeBlobKey, CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, largeBlobKey, sizeof(largeBlobKey)));
sizeof(largeBlobKey)));
mbedtls_platform_zeroize(largeBlobKey, sizeof(largeBlobKey)); mbedtls_platform_zeroize(largeBlobKey, sizeof(largeBlobKey));
} }
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0C)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0C));
CBOR_CHECK(cbor_encode_boolean(&mapEncoder, CBOR_CHECK(cbor_encode_boolean(&mapEncoder, cred.extensions.thirdPartyPayment == ptrue));
cred.extensions.thirdPartyPayment == ptrue));
} }
else { else {
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0C)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0C));
@@ -351,8 +342,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
} }
*(raw_subpara - 1) = 0x06; *(raw_subpara - 1) = 0x06;
if (verify(pinUvAuthProtocol, paut.data, raw_subpara - 1, raw_subpara_len + 1, if (verify((uint8_t)pinUvAuthProtocol, paut.data, raw_subpara - 1, (uint16_t)(raw_subpara_len + 1), pinUvAuthParam.data) != CborNoError) {
pinUvAuthParam.data) != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
if (is_preview == false && if (is_preview == false &&
@@ -361,18 +351,15 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
file_t *ef = search_dynamic_file(EF_CRED + i); file_t *ef = search_dynamic_file((uint16_t)(EF_CRED + i));
if (file_has_data(ef) && if (file_has_data(ef) && memcmp(file_get_data(ef) + 32, credentialId.id.data, MIN(file_get_size(ef) - 32, credentialId.id.len)) == 0) {
memcmp(file_get_data(ef) + 32, credentialId.id.data,
MIN(file_get_size(ef) - 32, credentialId.id.len)) == 0) {
uint8_t *rp_id_hash = file_get_data(ef); uint8_t *rp_id_hash = file_get_data(ef);
if (delete_file(ef) != 0) { if (delete_file(ef) != 0) {
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
} }
for (int j = 0; j < MAX_RESIDENT_CREDENTIALS; j++) { for (int j = 0; j < MAX_RESIDENT_CREDENTIALS; j++) {
file_t *rp_ef = search_dynamic_file(EF_RP + j); file_t *rp_ef = search_dynamic_file((uint16_t)(EF_RP + j));
if (file_has_data(rp_ef) && if (file_has_data(rp_ef) && memcmp(file_get_data(rp_ef) + 1, rp_id_hash, 32) == 0) {
memcmp(file_get_data(rp_ef) + 1, rp_id_hash, 32) == 0) {
uint8_t *rp_data = (uint8_t *) calloc(1, file_get_size(rp_ef)); uint8_t *rp_data = (uint8_t *) calloc(1, file_get_size(rp_ef));
memcpy(rp_data, file_get_data(rp_ef), file_get_size(rp_ef)); memcpy(rp_data, file_get_data(rp_ef), file_get_size(rp_ef));
rp_data[0] -= 1; rp_data[0] -= 1;
@@ -397,8 +384,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
} }
*(raw_subpara - 1) = 0x07; *(raw_subpara - 1) = 0x07;
if (verify(pinUvAuthProtocol, paut.data, raw_subpara - 1, raw_subpara_len + 1, if (verify((uint8_t)pinUvAuthProtocol, paut.data, raw_subpara - 1, (uint16_t)(raw_subpara_len + 1), pinUvAuthParam.data) != CborNoError) {
pinUvAuthParam.data) != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
if (is_preview == false && if (is_preview == false &&
@@ -407,18 +393,14 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
file_t *ef = search_dynamic_file(EF_CRED + i); file_t *ef = search_dynamic_file((uint16_t)(EF_CRED + i));
if (file_has_data(ef) && if (file_has_data(ef) && memcmp(file_get_data(ef) + 32, credentialId.id.data, MIN(file_get_size(ef) - 32, credentialId.id.len)) == 0) {
memcmp(file_get_data(ef) + 32, credentialId.id.data,
MIN(file_get_size(ef) - 32, credentialId.id.len)) == 0) {
Credential cred = { 0 }; Credential cred = { 0 };
uint8_t *rp_id_hash = file_get_data(ef); uint8_t *rp_id_hash = file_get_data(ef);
if (credential_load(rp_id_hash + 32, file_get_size(ef) - 32, rp_id_hash, if (credential_load(rp_id_hash + 32, file_get_size(ef) - 32, rp_id_hash, &cred) != 0) {
&cred) != 0) {
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
} }
if (memcmp(user.id.data, cred.userId.data, if (memcmp(user.id.data, cred.userId.data, MIN(user.id.len, cred.userId.len)) != 0) {
MIN(user.id.len, cred.userId.len)) != 0) {
credential_free(&cred); credential_free(&cred);
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
@@ -426,8 +408,8 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
size_t newcred_len = 0; size_t newcred_len = 0;
if (credential_create(&cred.rpId, &cred.userId, &user.parent.name, if (credential_create(&cred.rpId, &cred.userId, &user.parent.name,
&user.displayName, &cred.opts, &cred.extensions, &user.displayName, &cred.opts, &cred.extensions,
cred.use_sign_count, cred.alg, cred.use_sign_count, (int)cred.alg,
cred.curve, newcred, &newcred_len) != 0) { (int)cred.curve, newcred, &newcred_len) != 0) {
credential_free(&cred); credential_free(&cred);
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
} }
@@ -453,7 +435,7 @@ err:
CBOR_FREE_BYTE_STRING(user.displayName); CBOR_FREE_BYTE_STRING(user.displayName);
CBOR_FREE_BYTE_STRING(user.parent.name); CBOR_FREE_BYTE_STRING(user.parent.name);
CBOR_FREE_BYTE_STRING(credentialId.type); CBOR_FREE_BYTE_STRING(credentialId.type);
for (int n = 0; n < credentialId.transports_len; n++) { for (size_t n = 0; n < credentialId.transports_len; n++) {
CBOR_FREE_BYTE_STRING(credentialId.transports[n]); CBOR_FREE_BYTE_STRING(credentialId.transports[n]);
} }
if (error != CborNoError) { if (error != CborNoError) {
@@ -462,6 +444,6 @@ err:
} }
return error; return error;
} }
res_APDU_size = resp_size; res_APDU_size = (uint16_t)resp_size;
return 0; return 0;
} }

View File

@@ -43,6 +43,8 @@ uint8_t *datax = NULL;
size_t lenx = 0; size_t lenx = 0;
int cbor_get_next_assertion(const uint8_t *data, size_t len) { int cbor_get_next_assertion(const uint8_t *data, size_t len) {
(void) data;
(void) len;
CborError error = CborNoError; CborError error = CborNoError;
if (credentialCounter >= numberOfCredentialsx) { if (credentialCounter >= numberOfCredentialsx) {
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
@@ -250,11 +252,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
} }
if (pinUvAuthParam.present == true) { //6.1 if (pinUvAuthParam.present == true) { //6.1
int ret = verify(pinUvAuthProtocol, int ret = verify((uint8_t)pinUvAuthProtocol, paut.data, clientDataHash.data, (uint16_t)clientDataHash.len, pinUvAuthParam.data);
paut.data,
clientDataHash.data,
clientDataHash.len,
pinUvAuthParam.data);
if (ret != CborNoError) { if (ret != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
@@ -282,15 +280,14 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
} }
if (allowList_len > 0) { if (allowList_len > 0) {
for (int e = 0; e < allowList_len; e++) { for (size_t e = 0; e < allowList_len; e++) {
if (allowList[e].type.present == false || allowList[e].id.present == false) { if (allowList[e].type.present == false || allowList[e].id.present == false) {
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
} }
if (strcmp(allowList[e].type.data, "public-key") != 0) { if (strcmp(allowList[e].type.data, "public-key") != 0) {
continue; continue;
} }
if (credential_load(allowList[e].id.data, allowList[e].id.len, rp_id_hash, if (credential_load(allowList[e].id.data, allowList[e].id.len, rp_id_hash, &creds[creds_len]) != 0) {
&creds[creds_len]) != 0) {
CBOR_FREE_BYTE_STRING(allowList[e].id); CBOR_FREE_BYTE_STRING(allowList[e].id);
credential_free(&creds[creds_len]); credential_free(&creds[creds_len]);
} }
@@ -300,17 +297,12 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
} }
} }
else { else {
for (int i = 0; for (int i = 0; i < MAX_RESIDENT_CREDENTIALS && creds_len < MAX_CREDENTIAL_COUNT_IN_LIST; i++) {
i < MAX_RESIDENT_CREDENTIALS && creds_len < MAX_CREDENTIAL_COUNT_IN_LIST; file_t *ef = search_dynamic_file((uint16_t)(EF_CRED + i));
i++) {
file_t *ef = search_dynamic_file(EF_CRED + i);
if (!file_has_data(ef) || memcmp(file_get_data(ef), rp_id_hash, 32) != 0) { if (!file_has_data(ef) || memcmp(file_get_data(ef), rp_id_hash, 32) != 0) {
continue; continue;
} }
int ret = credential_load(file_get_data(ef) + 32, int ret = credential_load(file_get_data(ef) + 32, file_get_size(ef) - 32, rp_id_hash, &creds[creds_len]);
file_get_size(ef) - 32,
rp_id_hash,
&creds[creds_len]);
if (ret != 0) { if (ret != 0) {
credential_free(&creds[creds_len]); credential_free(&creds[creds_len]);
} }
@@ -320,11 +312,10 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
} }
resident = true; resident = true;
} }
for (int i = 0; i < creds_len; i++) { for (size_t i = 0; i < creds_len; i++) {
if (creds[i].present == true) { if (creds[i].present == true) {
if (creds[i].extensions.present == true) { if (creds[i].extensions.present == true) {
if (creds[i].extensions.credProtect == CRED_PROT_UV_REQUIRED && if (creds[i].extensions.credProtect == CRED_PROT_UV_REQUIRED && !(flags & FIDO2_AUT_FLAG_UV)) {
!(flags & FIDO2_AUT_FLAG_UV)) {
credential_free(&creds[i]); credential_free(&creds[i]);
} }
else if (creds[i].extensions.credProtect == CRED_PROT_UV_OPTIONAL_WITH_LIST && else if (creds[i].extensions.credProtect == CRED_PROT_UV_OPTIONAL_WITH_LIST &&
@@ -408,7 +399,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
} }
mbedtls_ecdsa_context ekey; mbedtls_ecdsa_context ekey;
mbedtls_ecdsa_init(&ekey); mbedtls_ecdsa_init(&ekey);
int ret = fido_load_key(selcred->curve, selcred->id.data, &ekey); int ret = fido_load_key((int)selcred->curve, selcred->id.data, &ekey);
if (ret != 0) { if (ret != 0) {
if (derive_key(rp_id_hash, false, selcred->id.data, MBEDTLS_ECP_DP_SECP256R1, &ekey) != 0) { if (derive_key(rp_id_hash, false, selcred->id.data, MBEDTLS_ECP_DP_SECP256R1, &ekey) != 0) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecdsa_free(&ekey);
@@ -468,23 +459,18 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
mbedtls_ecp_point_free(&Qp); mbedtls_ecp_point_free(&Qp);
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
int ret = ecdh(hmacSecretPinUvAuthProtocol, &Qp, sharedSecret); ret = ecdh((uint8_t)hmacSecretPinUvAuthProtocol, &Qp, sharedSecret);
mbedtls_ecp_point_free(&Qp); mbedtls_ecp_point_free(&Qp);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
} }
if (verify(hmacSecretPinUvAuthProtocol, sharedSecret, salt_enc.data, salt_enc.len, if (verify((uint8_t)hmacSecretPinUvAuthProtocol, sharedSecret, salt_enc.data, (uint16_t)salt_enc.len, salt_auth.data) != 0) {
salt_auth.data) != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP2_ERR_EXTENSION_FIRST); CBOR_ERROR(CTAP2_ERR_EXTENSION_FIRST);
} }
uint8_t salt_dec[64], poff = (hmacSecretPinUvAuthProtocol - 1) * IV_SIZE; uint8_t salt_dec[64], poff = ((uint8_t)hmacSecretPinUvAuthProtocol - 1) * IV_SIZE;
ret = decrypt(hmacSecretPinUvAuthProtocol, ret = decrypt((uint8_t)hmacSecretPinUvAuthProtocol, sharedSecret, salt_enc.data, (uint16_t)salt_enc.len, salt_dec);
sharedSecret,
salt_enc.data,
salt_enc.len,
salt_dec);
if (ret != 0) { if (ret != 0) {
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
@@ -502,21 +488,11 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
crd = cred_random; crd = cred_random;
} }
uint8_t out1[64], hmac_res[80]; uint8_t out1[64], hmac_res[80];
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), crd, 32, salt_dec, 32, out1);
crd, if ((uint8_t)salt_enc.len == 64 + poff) {
32, mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), crd, 32, salt_dec + 32, 32, out1 + 32);
salt_dec,
32,
out1);
if (salt_enc.len == 64 + poff) {
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
crd,
32,
salt_dec + 32,
32,
out1 + 32);
} }
encrypt(hmacSecretPinUvAuthProtocol, sharedSecret, out1, salt_enc.len - poff, hmac_res); encrypt((uint8_t)hmacSecretPinUvAuthProtocol, sharedSecret, out1, (uint16_t)(salt_enc.len - poff), hmac_res);
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, hmac_res, salt_enc.len)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, hmac_res, salt_enc.len));
} }
if (extensions.thirdPartyPayment != NULL) { if (extensions.thirdPartyPayment != NULL) {
@@ -541,12 +517,12 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
uint8_t *pa = aut_data; uint8_t *pa = aut_data;
memcpy(pa, rp_id_hash, 32); pa += 32; memcpy(pa, rp_id_hash, 32); pa += 32;
*pa++ = flags; *pa++ = flags;
*pa++ = ctr >> 24; *pa++ = (ctr >> 24) & 0xFF;
*pa++ = ctr >> 16; *pa++ = (ctr >> 16) & 0xFF;
*pa++ = ctr >> 8; *pa++ = (ctr >> 8) & 0xFF;
*pa++ = ctr & 0xff; *pa++ = ctr & 0xFF;
memcpy(pa, ext, ext_len); pa += ext_len; memcpy(pa, ext, ext_len); pa += ext_len;
if (pa - aut_data != aut_data_len) { if ((size_t)(pa - aut_data) != aut_data_len) {
CBOR_ERROR(CTAP1_ERR_OTHER); CBOR_ERROR(CTAP1_ERR_OTHER);
} }
@@ -559,20 +535,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) { else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) {
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
ret = mbedtls_md(md, ret = mbedtls_md(md, aut_data, aut_data_len + clientDataHash.len, hash);
aut_data,
aut_data_len + clientDataHash.len,
hash);
size_t olen = 0; size_t olen = 0;
ret = mbedtls_ecdsa_write_signature(&ekey, ret = mbedtls_ecdsa_write_signature(&ekey, mbedtls_md_get_type(md), hash, mbedtls_md_get_size(md), sig, sizeof(sig), &olen, random_gen, NULL);
mbedtls_md_get_type(md),
hash,
mbedtls_md_get_size(md),
sig,
sizeof(sig),
&olen,
random_gen,
NULL);
mbedtls_ecdsa_free(&ekey); mbedtls_ecdsa_free(&ekey);
uint8_t lfields = 3; uint8_t lfields = 3;
@@ -652,10 +617,10 @@ err:
} }
} }
for (int m = 0; m < allowList_len; m++) { for (size_t m = 0; m < allowList_len; m++) {
CBOR_FREE_BYTE_STRING(allowList[m].type); CBOR_FREE_BYTE_STRING(allowList[m].type);
CBOR_FREE_BYTE_STRING(allowList[m].id); CBOR_FREE_BYTE_STRING(allowList[m].id);
for (int n = 0; n < allowList[m].transports_len; n++) { for (size_t n = 0; n < allowList[m].transports_len; n++) {
CBOR_FREE_BYTE_STRING(allowList[m].transports[n]); CBOR_FREE_BYTE_STRING(allowList[m].transports[n]);
} }
} }
@@ -668,6 +633,6 @@ err:
} }
return error; return error;
} }
res_APDU_size = resp_size; res_APDU_size = (uint16_t)resp_size;
return 0; return 0;
} }

View File

@@ -133,6 +133,6 @@ err:
if (error != CborNoError) { if (error != CborNoError) {
return -CTAP2_ERR_INVALID_CBOR; return -CTAP2_ERR_INVALID_CBOR;
} }
res_APDU_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); res_APDU_size = (uint16_t)cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1);
return 0; return 0;
} }

View File

@@ -129,13 +129,12 @@ int cbor_large_blobs(const uint8_t *data, size_t len) {
uint8_t verify_data[70] = { 0 }; uint8_t verify_data[70] = { 0 };
memset(verify_data, 0xff, 32); memset(verify_data, 0xff, 32);
verify_data[32] = 0x0C; verify_data[32] = 0x0C;
verify_data[34] = offset & 0xff; verify_data[34] = offset & 0xFF;
verify_data[35] = offset >> 8; verify_data[35] = (offset >> 8) & 0xFF;
verify_data[36] = offset >> 16; verify_data[36] = (offset >> 16) & 0xFF;
verify_data[37] = offset >> 24; verify_data[37] = (offset >> 24) & 0xFF;
mbedtls_sha256(set.data, set.len, verify_data + 38, 0); mbedtls_sha256(set.data, set.len, verify_data + 38, 0);
if (verify(pinUvAuthProtocol, paut.data, verify_data, sizeof(verify_data), if (verify((uint8_t)pinUvAuthProtocol, paut.data, verify_data, (uint16_t)sizeof(verify_data), pinUvAuthParam.data) != 0) {
pinUvAuthParam.data) != 0) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
if (!(paut.permissions & CTAP_PERMISSION_LBW)) { if (!(paut.permissions & CTAP_PERMISSION_LBW)) {
@@ -155,7 +154,7 @@ int cbor_large_blobs(const uint8_t *data, size_t len) {
if (expectedLength > 17 && memcmp(sha, temp_lba + expectedLength - 16, 16) != 0) { if (expectedLength > 17 && memcmp(sha, temp_lba + expectedLength - 16, 16) != 0) {
CBOR_ERROR(CTAP2_ERR_INTEGRITY_FAILURE); CBOR_ERROR(CTAP2_ERR_INTEGRITY_FAILURE);
} }
file_put_data(ef_largeblob, temp_lba, expectedLength); file_put_data(ef_largeblob, temp_lba, (uint16_t)expectedLength);
low_flash_available(); low_flash_available();
} }
goto err; goto err;
@@ -168,6 +167,6 @@ err:
if (error != CborNoError) { if (error != CborNoError) {
return -CTAP2_ERR_INVALID_CBOR; return -CTAP2_ERR_INVALID_CBOR;
} }
res_APDU_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); res_APDU_size = (uint16_t)cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1);
return 0; return 0;
} }

View File

@@ -192,7 +192,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
} }
for (int i = 0; i < pubKeyCredParams_len; i++) { for (unsigned int i = 0; i < pubKeyCredParams_len; i++) {
if (pubKeyCredParams[i].type.present == false) { if (pubKeyCredParams[i].type.present == false) {
CBOR_ERROR(CTAP2_ERR_INVALID_CBOR); CBOR_ERROR(CTAP2_ERR_INVALID_CBOR);
} }
@@ -229,7 +229,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
// CBOR_ERROR(CTAP2_ERR_CBOR_UNEXPECTED_TYPE); // CBOR_ERROR(CTAP2_ERR_CBOR_UNEXPECTED_TYPE);
//} //}
if (curve > 0 && alg == 0) { if (curve > 0 && alg == 0) {
alg = pubKeyCredParams[i].alg; alg = (int)pubKeyCredParams[i].alg;
} }
} }
if (curve <= 0) { if (curve <= 0) {
@@ -259,11 +259,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
//Unfinished. See 6.1.2.9 //Unfinished. See 6.1.2.9
} }
if (pinUvAuthParam.present == true) { //11.1 if (pinUvAuthParam.present == true) { //11.1
int ret = verify(pinUvAuthProtocol, int ret = verify((uint8_t)pinUvAuthProtocol, paut.data, clientDataHash.data, (uint16_t)clientDataHash.len, pinUvAuthParam.data);
paut.data,
clientDataHash.data,
clientDataHash.len,
pinUvAuthParam.data);
if (ret != CborNoError) { if (ret != CborNoError) {
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
} }
@@ -283,11 +279,11 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
} }
} }
for (int e = 0; e < excludeList_len; e++) { //12.1 for (size_t e = 0; e < excludeList_len; e++) { //12.1
if (excludeList[e].type.present == false || excludeList[e].id.present == false) { if (excludeList[e].type.present == false || excludeList[e].id.present == false) {
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
} }
if (strcmp(excludeList[e].type.data, "public-key") != 0) { if (strcmp(excludeList[e].type.data, (char *)"public-key") != 0) {
continue; continue;
} }
Credential ecred; Credential ecred;
@@ -412,17 +408,17 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
uint8_t *pa = aut_data; uint8_t *pa = aut_data;
memcpy(pa, rp_id_hash, 32); pa += 32; memcpy(pa, rp_id_hash, 32); pa += 32;
*pa++ = flags; *pa++ = flags;
*pa++ = ctr >> 24; *pa++ = (ctr >> 24) & 0xFF;
*pa++ = ctr >> 16; *pa++ = (ctr >> 16) & 0xFF;
*pa++ = ctr >> 8; *pa++ = (ctr >> 8) & 0xFF;
*pa++ = ctr & 0xff; *pa++ = ctr & 0xFF;
memcpy(pa, aaguid, 16); pa += 16; memcpy(pa, aaguid, 16); pa += 16;
*pa++ = cred_id_len >> 8; *pa++ = ((uint16_t)cred_id_len >> 8) & 0xFF;
*pa++ = cred_id_len & 0xff; *pa++ = (uint16_t)cred_id_len & 0xFF;
memcpy(pa, cred_id, cred_id_len); pa += cred_id_len; memcpy(pa, cred_id, cred_id_len); pa += (uint16_t)cred_id_len;
memcpy(pa, cbor_buf, rs); pa += rs; memcpy(pa, cbor_buf, rs); pa += (uint16_t)rs;
memcpy(pa, ext, ext_len); pa += ext_len; memcpy(pa, ext, ext_len); pa += (uint16_t)ext_len;
if (pa - aut_data != aut_data_len) { if ((size_t)(pa - aut_data) != aut_data_len) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecdsa_free(&ekey);
CBOR_ERROR(CTAP1_ERR_OTHER); CBOR_ERROR(CTAP1_ERR_OTHER);
} }
@@ -436,10 +432,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) { else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) {
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
ret = mbedtls_md(md, ret = mbedtls_md(md, aut_data, aut_data_len + clientDataHash.len, hash);
aut_data,
aut_data_len + clientDataHash.len,
hash);
bool self_attestation = true; bool self_attestation = true;
if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) { if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) {
@@ -449,15 +442,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
self_attestation = false; self_attestation = false;
} }
ret = mbedtls_ecdsa_write_signature(&ekey, ret = mbedtls_ecdsa_write_signature(&ekey, mbedtls_md_get_type(md), hash, mbedtls_md_get_size(md), sig, sizeof(sig), &olen, random_gen, NULL);
mbedtls_md_get_type(md),
hash,
mbedtls_md_get_size(md),
sig,
sizeof(sig),
&olen,
random_gen,
NULL);
mbedtls_ecdsa_free(&ekey); mbedtls_ecdsa_free(&ekey);
uint8_t largeBlobKey[32]; uint8_t largeBlobKey[32];
@@ -469,9 +454,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
} }
cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0); cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0);
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, extensions.largeBlobKey == ptrue && options.rk == ptrue ? 5 : 4));
extensions.largeBlobKey == ptrue &&
options.rk == ptrue ? 5 : 4));
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01));
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder, "packed")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder, "packed"));
@@ -479,11 +462,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, aut_data, aut_data_len)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, aut_data, aut_data_len));
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x03)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x03));
CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, self_attestation == false || is_nitrokey ? 3 : 2));
self_attestation == false || is_nitrokey ? 3 : 2));
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg"));
CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, self_attestation || is_nitrokey ? -alg : -FIDO2_ALG_ES256));
self_attestation || is_nitrokey ? -alg : -FIDO2_ALG_ES256));
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "sig")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "sig"));
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, sig, olen)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, sig, olen));
if (self_attestation == false || is_nitrokey) { if (self_attestation == false || is_nitrokey) {
@@ -497,8 +478,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
} }
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "x5c")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "x5c"));
CBOR_CHECK(cbor_encoder_create_array(&mapEncoder2, &arrEncoder, 1)); CBOR_CHECK(cbor_encoder_create_array(&mapEncoder2, &arrEncoder, 1));
CBOR_CHECK(cbor_encode_byte_string(&arrEncoder, file_get_data(ef_cert), CBOR_CHECK(cbor_encode_byte_string(&arrEncoder, file_get_data(ef_cert), file_get_size(ef_cert)));
file_get_size(ef_cert)));
CBOR_CHECK(cbor_encoder_close_container(&mapEncoder2, &arrEncoder)); CBOR_CHECK(cbor_encoder_close_container(&mapEncoder2, &arrEncoder));
} }
CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2));
@@ -530,14 +510,14 @@ err:
CBOR_FREE_BYTE_STRING(user.id); CBOR_FREE_BYTE_STRING(user.id);
CBOR_FREE_BYTE_STRING(user.displayName); CBOR_FREE_BYTE_STRING(user.displayName);
CBOR_FREE_BYTE_STRING(user.parent.name); CBOR_FREE_BYTE_STRING(user.parent.name);
for (int n = 0; n < pubKeyCredParams_len; n++) { for (size_t n = 0; n < pubKeyCredParams_len; n++) {
CBOR_FREE_BYTE_STRING(pubKeyCredParams[n].type); CBOR_FREE_BYTE_STRING(pubKeyCredParams[n].type);
} }
for (int m = 0; m < excludeList_len; m++) { for (size_t m = 0; m < excludeList_len; m++) {
CBOR_FREE_BYTE_STRING(excludeList[m].type); CBOR_FREE_BYTE_STRING(excludeList[m].type);
CBOR_FREE_BYTE_STRING(excludeList[m].id); CBOR_FREE_BYTE_STRING(excludeList[m].id);
for (int n = 0; n < excludeList[m].transports_len; n++) { for (size_t n = 0; n < excludeList[m].transports_len; n++) {
CBOR_FREE_BYTE_STRING(excludeList[m].transports[n]); CBOR_FREE_BYTE_STRING(excludeList[m].transports[n]);
} }
} }
@@ -550,6 +530,6 @@ err:
} }
return error; return error;
} }
res_APDU_size = resp_size; res_APDU_size = (uint16_t)resp_size;
return 0; return 0;
} }

View File

@@ -121,7 +121,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
} }
uint8_t zeros[32]; uint8_t zeros[32];
memset(zeros, 0, sizeof(zeros)); memset(zeros, 0, sizeof(zeros));
file_put_data(ef_keydev_enc, vendorParam.data, vendorParam.len); file_put_data(ef_keydev_enc, vendorParam.data, (uint16_t)vendorParam.len);
file_put_data(ef_keydev, zeros, file_get_size(ef_keydev)); // Overwrite ef with 0 file_put_data(ef_keydev, zeros, file_get_size(ef_keydev)); // Overwrite ef with 0
file_put_data(ef_keydev, NULL, 0); // Set ef to 0 bytes file_put_data(ef_keydev, NULL, 0); // Set ef to 0 bytes
low_flash_available(); low_flash_available();
@@ -223,14 +223,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
size_t keyenc_len = file_get_size(ef_keydev_enc); size_t keyenc_len = file_get_size(ef_keydev_enc);
mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_init(&chatx);
mbedtls_chachapoly_setkey(&chatx, vendorParam.data); mbedtls_chachapoly_setkey(&chatx, vendorParam.data);
ret = mbedtls_chachapoly_auth_decrypt(&chatx, ret = mbedtls_chachapoly_auth_decrypt(&chatx, sizeof(keydev_dec), keyenc, NULL, 0, keyenc + keyenc_len - 16, keyenc + 12, keydev_dec);
sizeof(keydev_dec),
keyenc,
NULL,
0,
keyenc + keyenc_len - 16,
keyenc + 12,
keydev_dec);
mbedtls_chachapoly_free(&chatx); mbedtls_chachapoly_free(&chatx);
if (ret != 0) { if (ret != 0) {
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
@@ -243,10 +236,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
uint8_t buffer[1024]; uint8_t buffer[1024];
mbedtls_ecdsa_context ekey; mbedtls_ecdsa_context ekey;
mbedtls_ecdsa_init(&ekey); mbedtls_ecdsa_init(&ekey);
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, file_get_data(ef_keydev), file_get_size(ef_keydev));
&ekey,
file_get_data(ef_keydev),
file_get_size(ef_keydev));
if (ret != 0) { if (ret != 0) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecdsa_free(&ekey);
CBOR_ERROR(CTAP2_ERR_PROCESSING); CBOR_ERROR(CTAP2_ERR_PROCESSING);
@@ -290,7 +280,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
} }
file_t *ef_ee_ea = search_by_fid(EF_EE_DEV_EA, NULL, SPECIFY_EF); file_t *ef_ee_ea = search_by_fid(EF_EE_DEV_EA, NULL, SPECIFY_EF);
if (ef_ee_ea) { if (ef_ee_ea) {
file_put_data(ef_ee_ea, vendorParam.data, vendorParam.len); file_put_data(ef_ee_ea, vendorParam.data, (uint16_t)vendorParam.len);
} }
low_flash_available(); low_flash_available();
goto err; goto err;
@@ -312,7 +302,7 @@ err:
} }
return error; return error;
} }
res_APDU_size = resp_size; res_APDU_size = (uint16_t)resp_size;
return 0; return 0;
} }

View File

@@ -65,36 +65,27 @@ int cmd_authenticate() {
resp->flags = 0; resp->flags = 0;
resp->flags |= P1(apdu) == CTAP_AUTH_ENFORCE ? CTAP_AUTH_FLAG_TUP : 0x0; resp->flags |= P1(apdu) == CTAP_AUTH_ENFORCE ? CTAP_AUTH_FLAG_TUP : 0x0;
uint32_t ctr = get_sign_counter(); uint32_t ctr = get_sign_counter();
resp->ctr[0] = ctr >> 24; resp->ctr[0] = (ctr >> 24) & 0xFF;
resp->ctr[1] = ctr >> 16; resp->ctr[1] = (ctr >> 16) & 0xFF;
resp->ctr[2] = ctr >> 8; resp->ctr[2] = (ctr >> 8) & 0xFF;
resp->ctr[3] = ctr & 0xff; resp->ctr[3] = ctr & 0xFF;
uint8_t hash[32], sig_base[CTAP_APPID_SIZE + 1 + 4 + CTAP_CHAL_SIZE]; uint8_t hash[32], sig_base[CTAP_APPID_SIZE + 1 + 4 + CTAP_CHAL_SIZE];
memcpy(sig_base, req->appId, CTAP_APPID_SIZE); memcpy(sig_base, req->appId, CTAP_APPID_SIZE);
memcpy(sig_base + CTAP_APPID_SIZE, &resp->flags, sizeof(uint8_t)); memcpy(sig_base + CTAP_APPID_SIZE, &resp->flags, sizeof(uint8_t));
memcpy(sig_base + CTAP_APPID_SIZE + 1, resp->ctr, 4); memcpy(sig_base + CTAP_APPID_SIZE + 1, resp->ctr, 4);
memcpy(sig_base + CTAP_APPID_SIZE + 1 + 4, req->chal, CTAP_CHAL_SIZE); memcpy(sig_base + CTAP_APPID_SIZE + 1 + 4, req->chal, CTAP_CHAL_SIZE);
ret = ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), sig_base, sizeof(sig_base), hash);
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), sig_base, sizeof(sig_base), hash);
if (ret != 0) { if (ret != 0) {
mbedtls_ecdsa_free(&key); mbedtls_ecdsa_free(&key);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
size_t olen = 0; size_t olen = 0;
ret = mbedtls_ecdsa_write_signature(&key, ret = mbedtls_ecdsa_write_signature(&key, MBEDTLS_MD_SHA256, hash, 32, (uint8_t *) resp->sig, CTAP_MAX_EC_SIG_SIZE, &olen, random_gen, NULL);
MBEDTLS_MD_SHA256,
hash,
32,
(uint8_t *) resp->sig,
CTAP_MAX_EC_SIG_SIZE,
&olen,
random_gen,
NULL);
mbedtls_ecdsa_free(&key); mbedtls_ecdsa_free(&key);
if (ret != 0) { if (ret != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = 1 + 4 + olen; res_APDU_size = 1 + 4 + (uint16_t)olen;
ctr++; ctr++;
file_put_data(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); file_put_data(ef_counter, (uint8_t *) &ctr, sizeof(ctr));

View File

@@ -50,9 +50,7 @@ int u2f_unload() {
return CCID_OK; return CCID_OK;
} }
const uint8_t *bogus_firefox = const uint8_t *bogus_firefox = (const uint8_t *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
(const uint8_t *)
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint8_t *bogus_chrome = (const uint8_t *) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; const uint8_t *bogus_chrome = (const uint8_t *) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
extern int ctap_error(uint8_t error); extern int ctap_error(uint8_t error);
@@ -84,33 +82,20 @@ int cmd_register() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
size_t olen = 0; size_t olen = 0;
ret = ret = mbedtls_ecp_point_write_binary(&key.grp, &key.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, (uint8_t *) &resp->pubKey, CTAP_EC_POINT_SIZE);
mbedtls_ecp_point_write_binary(&key.grp,
&key.Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&olen,
(uint8_t *) &resp->pubKey,
CTAP_EC_POINT_SIZE);
mbedtls_ecdsa_free(&key); mbedtls_ecdsa_free(&key);
if (ret != 0) { if (ret != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
size_t ef_certdev_size = file_get_size(ef_certdev); uint16_t ef_certdev_size = file_get_size(ef_certdev);
memcpy(resp->keyHandleCertSig + KEY_HANDLE_LEN, file_get_data(ef_certdev), ef_certdev_size); memcpy(resp->keyHandleCertSig + KEY_HANDLE_LEN, file_get_data(ef_certdev), ef_certdev_size);
uint8_t hash[32], uint8_t hash[32], sign_base[1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE + KEY_HANDLE_LEN + CTAP_EC_POINT_SIZE];
sign_base[1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE + KEY_HANDLE_LEN + CTAP_EC_POINT_SIZE];
sign_base[0] = CTAP_REGISTER_HASH_ID; sign_base[0] = CTAP_REGISTER_HASH_ID;
memcpy(sign_base + 1, req->appId, CTAP_APPID_SIZE); memcpy(sign_base + 1, req->appId, CTAP_APPID_SIZE);
memcpy(sign_base + 1 + CTAP_APPID_SIZE, req->chal, CTAP_CHAL_SIZE); memcpy(sign_base + 1 + CTAP_APPID_SIZE, req->chal, CTAP_CHAL_SIZE);
memcpy(sign_base + 1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE, resp->keyHandleCertSig, memcpy(sign_base + 1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE, resp->keyHandleCertSig, KEY_HANDLE_LEN);
KEY_HANDLE_LEN); memcpy(sign_base + 1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE + KEY_HANDLE_LEN, (uint8_t *) &resp->pubKey, CTAP_EC_POINT_SIZE);
memcpy(sign_base + 1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE + KEY_HANDLE_LEN, ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), sign_base, sizeof(sign_base), hash);
(uint8_t *) &resp->pubKey,
CTAP_EC_POINT_SIZE);
ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
sign_base,
sizeof(sign_base),
hash);
if (ret != 0) { if (ret != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
@@ -120,21 +105,12 @@ int cmd_register() {
mbedtls_ecdsa_free(&key); mbedtls_ecdsa_free(&key);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
ret = mbedtls_ecdsa_write_signature(&key, ret = mbedtls_ecdsa_write_signature(&key,MBEDTLS_MD_SHA256, hash, 32, (uint8_t *) resp->keyHandleCertSig + KEY_HANDLE_LEN + ef_certdev_size, CTAP_MAX_EC_SIG_SIZE, &olen, random_gen, NULL);
MBEDTLS_MD_SHA256,
hash,
32,
(uint8_t *) resp->keyHandleCertSig + KEY_HANDLE_LEN + ef_certdev_size,
CTAP_MAX_EC_SIG_SIZE,
&olen,
random_gen,
NULL);
mbedtls_ecdsa_free(&key); mbedtls_ecdsa_free(&key);
if (ret != 0) { if (ret != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = sizeof(CTAP_REGISTER_RESP) - sizeof(resp->keyHandleCertSig) + KEY_HANDLE_LEN + res_APDU_size = sizeof(CTAP_REGISTER_RESP) - sizeof(resp->keyHandleCertSig) + KEY_HANDLE_LEN + ef_certdev_size + (uint16_t)olen;
ef_certdev_size + olen;
return SW_OK(); return SW_OK();
} }

View File

@@ -20,6 +20,6 @@
int cmd_version() { int cmd_version() {
memcpy(res_APDU, "U2F_V2", strlen("U2F_V2")); memcpy(res_APDU, "U2F_V2", strlen("U2F_V2"));
res_APDU_size = strlen("U2F_V2"); res_APDU_size = (uint16_t)strlen("U2F_V2");
return SW_OK(); return SW_OK();
} }

View File

@@ -273,7 +273,7 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *
credential_free(&cred); credential_free(&cred);
return ret; return ret;
} }
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (uint16_t i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
file_t *ef = search_dynamic_file(EF_CRED + i); file_t *ef = search_dynamic_file(EF_CRED + i);
Credential rcred = { 0 }; Credential rcred = { 0 };
if (!file_has_data(ef)) { if (!file_has_data(ef)) {
@@ -290,8 +290,7 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *
credential_free(&rcred); credential_free(&rcred);
continue; continue;
} }
if (memcmp(rcred.userId.data, cred.userId.data, if (memcmp(rcred.userId.data, cred.userId.data, MIN(rcred.userId.len, cred.userId.len)) == 0) {
MIN(rcred.userId.len, cred.userId.len)) == 0) {
sloti = i; sloti = i;
credential_free(&rcred); credential_free(&rcred);
new_record = false; new_record = false;
@@ -305,13 +304,13 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *
uint8_t *data = (uint8_t *) calloc(1, cred_id_len + 32); uint8_t *data = (uint8_t *) calloc(1, cred_id_len + 32);
memcpy(data, rp_id_hash, 32); memcpy(data, rp_id_hash, 32);
memcpy(data + 32, cred_id, cred_id_len); memcpy(data + 32, cred_id, cred_id_len);
file_t *ef = file_new(EF_CRED + sloti); file_t *ef = file_new((uint16_t)(EF_CRED + sloti));
file_put_data(ef, data, cred_id_len + 32); file_put_data(ef, data, (uint16_t)cred_id_len + 32);
free(data); free(data);
if (new_record == true) { //increase rps if (new_record == true) { //increase rps
sloti = -1; sloti = -1;
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) { for (uint16_t i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
ef = search_dynamic_file(EF_RP + i); ef = search_dynamic_file(EF_RP + i);
if (!file_has_data(ef)) { if (!file_has_data(ef)) {
if (sloti == -1) { if (sloti == -1) {
@@ -327,7 +326,7 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *
if (sloti == -1) { if (sloti == -1) {
return -1; return -1;
} }
ef = search_dynamic_file(EF_RP + sloti); ef = search_dynamic_file((uint16_t)(EF_RP + sloti));
if (file_has_data(ef)) { if (file_has_data(ef)) {
data = (uint8_t *) calloc(1, file_get_size(ef)); data = (uint8_t *) calloc(1, file_get_size(ef));
memcpy(data, file_get_data(ef), file_get_size(ef)); memcpy(data, file_get_data(ef), file_get_size(ef));
@@ -336,12 +335,12 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *
free(data); free(data);
} }
else { else {
ef = file_new(EF_RP + sloti); ef = file_new((uint16_t)(EF_RP + sloti));
data = (uint8_t *) calloc(1, 1 + 32 + cred.rpId.len); data = (uint8_t *) calloc(1, 1 + 32 + cred.rpId.len);
data[0] = 1; data[0] = 1;
memcpy(data + 1, rp_id_hash, 32); memcpy(data + 1, rp_id_hash, 32);
memcpy(data + 1 + 32, cred.rpId.data, cred.rpId.len); memcpy(data + 1 + 32, cred.rpId.data, cred.rpId.len);
file_put_data(ef, data, 1 + 32 + cred.rpId.len); file_put_data(ef, data, (uint16_t)(1 + 32 + cred.rpId.len));
free(data); free(data);
} }
} }

View File

@@ -18,16 +18,9 @@
#ifndef _CTAP_H_ #ifndef _CTAP_H_
#define _CTAP_H_ #define _CTAP_H_
#ifdef _MSC_VER // Windows
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
#else
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@@ -260,7 +260,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
if (cinfo->bit_size % 8 != 0) { if (cinfo->bit_size % 8 != 0) {
outk[0] >>= 8 - (cinfo->bit_size % 8); outk[0] >>= 8 - (cinfo->bit_size % 8);
} }
r = mbedtls_ecp_read_key(curve, key, outk, ceil((float) cinfo->bit_size / 8)); r = mbedtls_ecp_read_key(curve, key, outk, (size_t)ceil((float) cinfo->bit_size / 8));
mbedtls_platform_zeroize(outk, sizeof(outk)); mbedtls_platform_zeroize(outk, sizeof(outk));
if (r != 0) { if (r != 0) {
return r; return r;
@@ -291,7 +291,7 @@ int scan_files() {
if (ret != CCID_OK) { if (ret != CCID_OK) {
return ret; return ret;
} }
ret = file_put_data(ef_keydev, kdata, key_size); ret = file_put_data(ef_keydev, kdata, (uint16_t)key_size);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
if (ret != CCID_OK) { if (ret != CCID_OK) {
@@ -324,7 +324,7 @@ int scan_files() {
if (ret <= 0) { if (ret <= 0) {
return ret; return ret;
} }
file_put_data(ef_certdev, cert + sizeof(cert) - ret, ret); file_put_data(ef_certdev, cert + sizeof(cert) - ret, (uint16_t)ret);
} }
} }
else { else {

View File

@@ -53,16 +53,8 @@ extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve);
extern int mbedtls_curve_to_fido(mbedtls_ecp_group_id id); extern int mbedtls_curve_to_fido(mbedtls_ecp_group_id id);
extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecdsa_context *key); extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecdsa_context *key);
extern int load_keydev(uint8_t *key); extern int load_keydev(uint8_t *key);
extern int encrypt(uint8_t protocol, extern int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out);
const uint8_t *key, extern int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out);
const uint8_t *in,
size_t in_len,
uint8_t *out);
extern int decrypt(uint8_t protocol,
const uint8_t *key,
const uint8_t *in,
size_t in_len,
uint8_t *out);
extern int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret); extern int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret);
#define FIDO2_ALG_ES256 -7 //ECDSA-SHA256 P256 #define FIDO2_ALG_ES256 -7 //ECDSA-SHA256 P256
@@ -136,10 +128,6 @@ typedef struct pinUvAuthToken {
extern uint32_t user_present_time_limit; extern uint32_t user_present_time_limit;
extern pinUvAuthToken_t paut; extern pinUvAuthToken_t paut;
extern int verify(uint8_t protocol, extern int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, uint16_t len, uint8_t *sign);
const uint8_t *key,
const uint8_t *data,
size_t len,
uint8_t *sign);
#endif //_FIDO_H #endif //_FIDO_H

View File

@@ -36,7 +36,7 @@ int man_select(app_t *a, uint8_t force) {
a->process_apdu = man_process_apdu; a->process_apdu = man_process_apdu;
a->unload = man_unload; a->unload = man_unload;
sprintf((char *) res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR); sprintf((char *) res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR);
res_APDU_size = strlen((char *) res_APDU); res_APDU_size = (uint16_t)strlen((char *) res_APDU);
apdu.ne = res_APDU_size; apdu.ne = res_APDU_size;
if (force) { if (force) {
scan_all(); scan_all();
@@ -116,7 +116,7 @@ int man_get_config() {
memcpy(res_APDU + res_APDU_size, file_get_data(ef), file_get_size(ef)); memcpy(res_APDU + res_APDU_size, file_get_data(ef), file_get_size(ef));
res_APDU_size += file_get_size(ef); res_APDU_size += file_get_size(ef);
} }
res_APDU[0] = res_APDU_size - 1; res_APDU[0] = (uint8_t)(res_APDU_size - 1);
return 0; return 0;
} }
@@ -130,7 +130,7 @@ int cmd_write_config() {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
file_t *ef = file_new(EF_DEV_CONF); file_t *ef = file_new(EF_DEV_CONF);
file_put_data(ef, apdu.data + 1, apdu.nc - 1); file_put_data(ef, apdu.data + 1, (uint16_t)(apdu.nc - 1));
low_flash_available(); low_flash_available();
return SW_OK(); return SW_OK();
} }

View File

@@ -115,7 +115,7 @@ int oath_unload() {
file_t *find_oath_cred(const uint8_t *name, size_t name_len) { file_t *find_oath_cred(const uint8_t *name, size_t name_len) {
for (int i = 0; i < MAX_OATH_CRED; i++) { for (int i = 0; i < MAX_OATH_CRED; i++) {
file_t *ef = search_dynamic_file(EF_OATH_CRED + i); file_t *ef = search_dynamic_file((uint16_t)(EF_OATH_CRED + i));
asn1_ctx_t ctxi, ef_tag = { 0 }; asn1_ctx_t ctxi, ef_tag = { 0 };
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
if (file_has_data(ef) && asn1_find_tag(&ctxi, TAG_NAME, &ef_tag) == true && ef_tag.len == name_len && memcmp(ef_tag.data, name, name_len) == 0) { if (file_has_data(ef) && asn1_find_tag(&ctxi, TAG_NAME, &ef_tag) == true && ef_tag.len == name_len && memcmp(ef_tag.data, name, name_len) == 0) {
@@ -130,7 +130,7 @@ int cmd_put() {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
} }
asn1_ctx_t ctxi, key = { 0 }, name = { 0 }, imf = { 0 }; asn1_ctx_t ctxi, key = { 0 }, name = { 0 }, imf = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) { if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -154,15 +154,15 @@ int cmd_put() {
} }
file_t *ef = find_oath_cred(name.data, name.len); file_t *ef = find_oath_cred(name.data, name.len);
if (file_has_data(ef)) { if (file_has_data(ef)) {
file_put_data(ef, apdu.data, apdu.nc); file_put_data(ef, apdu.data, (uint16_t)apdu.nc);
low_flash_available(); low_flash_available();
} }
else { else {
for (int i = 0; i < MAX_OATH_CRED; i++) { for (int i = 0; i < MAX_OATH_CRED; i++) {
file_t *ef = search_dynamic_file(EF_OATH_CRED + i); file_t *tef = search_dynamic_file((uint16_t)(EF_OATH_CRED + i));
if (!file_has_data(ef)) { if (!file_has_data(tef)) {
ef = file_new(EF_OATH_CRED + i); tef = file_new((uint16_t)(EF_OATH_CRED + i));
file_put_data(ef, apdu.data, apdu.nc); file_put_data(tef, apdu.data, (uint16_t)apdu.nc);
low_flash_available(); low_flash_available();
return SW_OK(); return SW_OK();
} }
@@ -178,7 +178,7 @@ int cmd_delete() {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
} }
asn1_ctx_t ctxi, ctxo = { 0 }; asn1_ctx_t ctxi, ctxo = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_NAME, &ctxo) == true) { if (asn1_find_tag(&ctxi, TAG_NAME, &ctxo) == true) {
file_t *ef = find_oath_cred(ctxo.data, ctxo.len); file_t *ef = find_oath_cred(ctxo.data, ctxo.len);
if (ef) { if (ef) {
@@ -213,7 +213,7 @@ int cmd_set_code() {
return SW_OK(); return SW_OK();
} }
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 }; asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) { if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -254,7 +254,7 @@ int cmd_reset() {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
for (int i = 0; i < MAX_OATH_CRED; i++) { for (int i = 0; i < MAX_OATH_CRED; i++) {
file_t *ef = search_dynamic_file(EF_OATH_CRED + i); file_t *ef = search_dynamic_file((uint16_t)(EF_OATH_CRED + i));
if (file_has_data(ef)) { if (file_has_data(ef)) {
delete_file(ef); delete_file(ef);
} }
@@ -271,13 +271,13 @@ int cmd_list() {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
} }
for (int i = 0; i < MAX_OATH_CRED; i++) { for (int i = 0; i < MAX_OATH_CRED; i++) {
file_t *ef = search_dynamic_file(EF_OATH_CRED + i); file_t *ef = search_dynamic_file((uint16_t)(EF_OATH_CRED + i));
if (file_has_data(ef)) { if (file_has_data(ef)) {
asn1_ctx_t ctxi, key = { 0 }, name = { 0 }; asn1_ctx_t ctxi, key = { 0 }, name = { 0 };
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == true && asn1_find_tag(&ctxi, TAG_KEY, &key) == true) { if (asn1_find_tag(&ctxi, TAG_NAME, &name) == true && asn1_find_tag(&ctxi, TAG_KEY, &key) == true) {
res_APDU[res_APDU_size++] = TAG_NAME_LIST; res_APDU[res_APDU_size++] = TAG_NAME_LIST;
res_APDU[res_APDU_size++] = name.len + 1; res_APDU[res_APDU_size++] = (uint8_t)(name.len + 1);
res_APDU[res_APDU_size++] = key.data[0]; res_APDU[res_APDU_size++] = key.data[0];
memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len; memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len;
} }
@@ -289,7 +289,7 @@ int cmd_list() {
int cmd_validate() { int cmd_validate() {
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 }; asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) { if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -328,11 +328,7 @@ int cmd_validate() {
return SW_OK(); return SW_OK();
} }
int calculate_oath(uint8_t truncate, int calculate_oath(uint8_t truncate, const uint8_t *key, size_t key_len, const uint8_t *chal, size_t chal_len) {
const uint8_t *key,
size_t key_len,
const uint8_t *chal,
size_t chal_len) {
const mbedtls_md_info_t *md_info = get_oath_md_info(key[0]); const mbedtls_md_info_t *md_info = get_oath_md_info(key[0]);
if (md_info == NULL) { if (md_info == NULL) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
@@ -353,9 +349,9 @@ int calculate_oath(uint8_t truncate,
res_APDU[res_APDU_size++] = hmac[offset + 3]; res_APDU[res_APDU_size++] = hmac[offset + 3];
} }
else { else {
res_APDU[res_APDU_size++] = hmac_size + 1; res_APDU[res_APDU_size++] = (uint8_t)(hmac_size + 1);
res_APDU[res_APDU_size++] = key[1]; res_APDU[res_APDU_size++] = key[1];
memcpy(res_APDU + res_APDU_size, hmac, hmac_size); res_APDU_size += hmac_size; memcpy(res_APDU + res_APDU_size, hmac, hmac_size); res_APDU_size += (uint16_t)hmac_size;
} }
apdu.ne = res_APDU_size; apdu.ne = res_APDU_size;
return CCID_OK; return CCID_OK;
@@ -369,7 +365,7 @@ int cmd_calculate() {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
} }
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }; asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) { if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -400,32 +396,30 @@ int cmd_calculate() {
} }
if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) {
uint64_t v = uint64_t v =
((uint64_t) chal.data[0] << ((uint64_t) chal.data[0] << 56) |
56) | ((uint64_t) chal.data[1] << 48) |
((uint64_t) chal.data[1] << ((uint64_t) chal.data[2] << 40) |
48) | ((uint64_t) chal.data[3] << 32) |
((uint64_t) chal.data[2] << ((uint64_t) chal.data[4] << 24) |
40) | ((uint64_t) chal.data[5] << 16) |
((uint64_t) chal.data[3] << ((uint64_t) chal.data[6] << 8) |
32) | (uint64_t) chal.data[7];
((uint64_t) chal.data[4] <<
24) | ((uint64_t) chal.data[5] << 16) | ((uint64_t) chal.data[6] << 8) | (uint64_t) chal.data[7];
size_t ef_size = file_get_size(ef); size_t ef_size = file_get_size(ef);
v++; v++;
uint8_t *tmp = (uint8_t *) calloc(1, ef_size); uint8_t *tmp = (uint8_t *) calloc(1, ef_size);
memcpy(tmp, file_get_data(ef), ef_size); memcpy(tmp, file_get_data(ef), ef_size);
asn1_ctx_t ctxt; asn1_ctx_t ctxt;
asn1_ctx_init(tmp, ef_size, &ctxt); asn1_ctx_init(tmp, (uint16_t)ef_size, &ctxt);
asn1_find_tag(&ctxt, TAG_IMF, &chal); asn1_find_tag(&ctxt, TAG_IMF, &chal);
chal.data[0] = v >> 56; chal.data[0] = (v >> 56) & 0xFF;
chal.data[1] = v >> 48; chal.data[1] = (v >> 48) & 0xFF;
chal.data[2] = v >> 40; chal.data[2] = (v >> 40) & 0xFF;
chal.data[3] = v >> 32; chal.data[3] = (v >> 32) & 0xFF;
chal.data[4] = v >> 24; chal.data[4] = (v >> 24) & 0xFF;
chal.data[5] = v >> 16; chal.data[5] = (v >> 16) & 0xFF;
chal.data[6] = v >> 8; chal.data[6] = (v >> 8) & 0xFF;
chal.data[7] = v & 0xff; chal.data[7] = v & 0xff;
file_put_data(ef, tmp, ef_size); file_put_data(ef, tmp, (uint16_t)ef_size);
low_flash_available(); low_flash_available();
free(tmp); free(tmp);
} }
@@ -435,7 +429,7 @@ int cmd_calculate() {
int cmd_calculate_all() { int cmd_calculate_all() {
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, prop = { 0 }; asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, prop = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (P2(apdu) != 0x0 && P2(apdu) != 0x1) { if (P2(apdu) != 0x0 && P2(apdu) != 0x1) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
@@ -447,17 +441,17 @@ int cmd_calculate_all() {
} }
res_APDU_size = 0; res_APDU_size = 0;
for (int i = 0; i < MAX_OATH_CRED; i++) { for (int i = 0; i < MAX_OATH_CRED; i++) {
file_t *ef = search_dynamic_file(EF_OATH_CRED + i); file_t *ef = search_dynamic_file((uint16_t)(EF_OATH_CRED + i));
if (file_has_data(ef)) { if (file_has_data(ef)) {
const uint8_t *ef_data = file_get_data(ef); const uint8_t *ef_data = file_get_data(ef);
size_t ef_len = file_get_size(ef); size_t ef_len = file_get_size(ef);
asn1_ctx_t ctxe; asn1_ctx_t ctxe;
asn1_ctx_init((uint8_t *)ef_data, ef_len, &ctxe); asn1_ctx_init((uint8_t *)ef_data, (uint16_t)ef_len, &ctxe);
if (asn1_find_tag(&ctxe, TAG_NAME, &name) == false || asn1_find_tag(&ctxe, TAG_KEY, &key) == false) { if (asn1_find_tag(&ctxe, TAG_NAME, &name) == false || asn1_find_tag(&ctxe, TAG_KEY, &key) == false) {
continue; continue;
} }
res_APDU[res_APDU_size++] = TAG_NAME; res_APDU[res_APDU_size++] = TAG_NAME;
res_APDU[res_APDU_size++] = name.len; res_APDU[res_APDU_size++] = (uint8_t)name.len;
memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len; memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len;
if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) {
res_APDU[res_APDU_size++] = TAG_NO_RESPONSE; res_APDU[res_APDU_size++] = TAG_NO_RESPONSE;
@@ -494,7 +488,7 @@ int cmd_set_otp_pin() {
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
} }
asn1_ctx_t ctxi, pw = { 0 }; asn1_ctx_t ctxi, pw = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) { if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -512,7 +506,7 @@ int cmd_change_otp_pin() {
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
} }
asn1_ctx_t ctxi, pw = { 0 }, new_pw = { 0 }; asn1_ctx_t ctxi, pw = { 0 }, new_pw = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) { if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -537,7 +531,7 @@ int cmd_verify_otp_pin() {
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
} }
asn1_ctx_t ctxi, pw = { 0 }; asn1_ctx_t ctxi, pw = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) { if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
} }
@@ -561,7 +555,7 @@ int cmd_verify_otp_pin() {
int cmd_verify_hotp() { int cmd_verify_hotp() {
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, code = { 0 }; asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, code = { 0 };
asn1_ctx_init(apdu.data, apdu.nc, &ctxi); asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
uint32_t code_int = 0; uint32_t code_int = 0;
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) { if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
return SW_INCORRECT_PARAMS(); return SW_INCORRECT_PARAMS();
@@ -600,7 +594,8 @@ int cmd_verify_hotp() {
if (res_int != code_int) { if (res_int != code_int) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
res_APDU_size = apdu.ne = 0; res_APDU_size = 0;
apdu.ne = 0;
return SW_OK(); return SW_OK();
} }

View File

@@ -96,6 +96,7 @@
static uint8_t config_seq = { 1 }; static uint8_t config_seq = { 1 };
PACK(
typedef struct otp_config { typedef struct otp_config {
uint8_t fixed_data[FIXED_SIZE]; uint8_t fixed_data[FIXED_SIZE];
uint8_t uid[UID_SIZE]; uint8_t uid[UID_SIZE];
@@ -107,9 +108,9 @@ typedef struct otp_config {
uint8_t cfg_flags; uint8_t cfg_flags;
uint8_t rfu[2]; uint8_t rfu[2];
uint16_t crc; uint16_t crc;
} __attribute__((packed)) otp_config_t; }) otp_config_t;
static const size_t otp_config_size = sizeof(otp_config_t); #define otp_config_size sizeof(otp_config_t)
uint16_t otp_status(); uint16_t otp_status();
int otp_process_apdu(); int otp_process_apdu();
@@ -151,7 +152,7 @@ int otp_select(app_t *a, uint8_t force) {
uint8_t modhex_tab[] = uint8_t modhex_tab[] =
{ 'c', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'r', 't', 'u', 'v' }; { 'c', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'r', 't', 'u', 'v' };
int encode_modhex(const uint8_t *in, size_t len, uint8_t *out) { int encode_modhex(const uint8_t *in, size_t len, uint8_t *out) {
for (int l = 0; l < len; l++) { for (size_t l = 0; l < len; l++) {
*out++ = modhex_tab[in[l] >> 4]; *out++ = modhex_tab[in[l] >> 4];
*out++ = modhex_tab[in[l] & 0xf]; *out++ = modhex_tab[in[l] & 0xf];
} }
@@ -162,7 +163,7 @@ extern void scan_all();
void init_otp() { void init_otp() {
if (scanned == false) { if (scanned == false) {
scan_all(); scan_all();
for (int i = 0; i < 2; i++) { for (uint8_t i = 0; i < 2; i++) {
file_t *ef = search_dynamic_file(EF_OTP_SLOT1 + i); file_t *ef = search_dynamic_file(EF_OTP_SLOT1 + i);
uint8_t *data = file_get_data(ef); uint8_t *data = file_get_data(ef);
otp_config_t *otp_config = (otp_config_t *) data; otp_config_t *otp_config = (otp_config_t *) data;
@@ -331,6 +332,8 @@ int otp_button_pressed(uint8_t slot) {
low_flash_available(); low_flash_available();
} }
} }
#else
(void) slot;
#endif #endif
return 0; return 0;
} }