Merge branch 'development' into eddsa
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
VERSION_MAJOR="5"
|
VERSION_MAJOR="5"
|
||||||
VERSION_MINOR="4"
|
VERSION_MINOR="6"
|
||||||
|
|
||||||
rm -rf release/*
|
rm -rf release/*
|
||||||
cd build_release
|
cd build_release
|
||||||
@@ -17,6 +17,7 @@ for board in adafruit_feather_rp2040 \
|
|||||||
eetree_gamekit_rp2040 \
|
eetree_gamekit_rp2040 \
|
||||||
garatronic_pybstick26_rp2040 \
|
garatronic_pybstick26_rp2040 \
|
||||||
melopero_shake_rp2040 \
|
melopero_shake_rp2040 \
|
||||||
|
nullbits_bit_c_pro \
|
||||||
pico \
|
pico \
|
||||||
pico_w \
|
pico_w \
|
||||||
pimoroni_badger2040 \
|
pimoroni_badger2040 \
|
||||||
@@ -31,6 +32,7 @@ for board in adafruit_feather_rp2040 \
|
|||||||
pimoroni_servo2040 \
|
pimoroni_servo2040 \
|
||||||
pimoroni_tiny2040 \
|
pimoroni_tiny2040 \
|
||||||
pimoroni_tiny2040_2mb \
|
pimoroni_tiny2040_2mb \
|
||||||
|
pololu_3pi_2040_robot \
|
||||||
seeed_xiao_rp2040 \
|
seeed_xiao_rp2040 \
|
||||||
solderparty_rp2040_stamp \
|
solderparty_rp2040_stamp \
|
||||||
solderparty_rp2040_stamp_carrier \
|
solderparty_rp2040_stamp_carrier \
|
||||||
|
|||||||
@@ -129,10 +129,16 @@ int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CborError COSE_key_params(int crv, int alg, mbedtls_ecp_group *grp, mbedtls_ecp_point *Q, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) {
|
CborError COSE_key_params(int crv,
|
||||||
|
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 || crv == FIDO2_CURVE_P256K1) {
|
if (crv == FIDO2_CURVE_P256 || crv == FIDO2_CURVE_P384 || crv == FIDO2_CURVE_P521 ||
|
||||||
|
crv == FIDO2_CURVE_P256K1) {
|
||||||
kty = 2;
|
kty = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +168,8 @@ CborError COSE_key_params(int crv, int alg, mbedtls_ecp_group *grp, mbedtls_ecp_
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
CBOR_CHECK(mbedtls_ecp_point_write_binary(grp, Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, pkey, sizeof(pkey)));
|
CBOR_CHECK(mbedtls_ecp_point_write_binary(grp, Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, pkey,
|
||||||
|
sizeof(pkey)));
|
||||||
CBOR_CHECK(cbor_encode_byte_string(mapEncoder, pkey, olen));
|
CBOR_CHECK(cbor_encode_byte_string(mapEncoder, pkey, olen));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +177,8 @@ CborError COSE_key_params(int crv, int alg, mbedtls_ecp_group *grp, mbedtls_ecp_
|
|||||||
err:
|
err:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
CborError COSE_key(mbedtls_ecp_keypair *key, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) {
|
CborError COSE_key(mbedtls_ecp_keypair *key, CborEncoder *mapEncoderParent,
|
||||||
|
CborEncoder *mapEncoder) {
|
||||||
int crv = mbedtls_curve_to_fido(key->grp.id), alg = 0;
|
int crv = mbedtls_curve_to_fido(key->grp.id), alg = 0;
|
||||||
if (key->grp.id == MBEDTLS_ECP_DP_SECP256R1) {
|
if (key->grp.id == MBEDTLS_ECP_DP_SECP256R1) {
|
||||||
alg = FIDO2_ALG_ES256;
|
alg = FIDO2_ALG_ES256;
|
||||||
@@ -192,9 +200,16 @@ CborError COSE_key(mbedtls_ecp_keypair *key, CborEncoder *mapEncoderParent, Cbor
|
|||||||
}
|
}
|
||||||
return COSE_key_params(crv, alg, &key->grp, &key->Q, mapEncoderParent, mapEncoder);
|
return COSE_key_params(crv, alg, &key->grp, &key->Q, mapEncoderParent, mapEncoder);
|
||||||
}
|
}
|
||||||
CborError COSE_key_shared(mbedtls_ecdh_context *key, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) {
|
CborError COSE_key_shared(mbedtls_ecdh_context *key,
|
||||||
|
CborEncoder *mapEncoderParent,
|
||||||
|
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, alg, &key->ctx.mbed_ecdh.grp, &key->ctx.mbed_ecdh.Q, mapEncoderParent, mapEncoder);
|
return COSE_key_params(crv,
|
||||||
|
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;
|
||||||
@@ -207,7 +222,12 @@ CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *m
|
|||||||
err:
|
err:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
CborError COSE_read_key(CborValue *f, int64_t *kty, int64_t *alg, int64_t *crv, CborByteString *kax, CborByteString *kay) {
|
CborError COSE_read_key(CborValue *f,
|
||||||
|
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)
|
||||||
|
|||||||
@@ -336,7 +336,8 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
|
|||||||
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, cred.extensions.thirdPartyPayment == ptrue));
|
CBOR_CHECK(cbor_encode_boolean(&mapEncoder,
|
||||||
|
cred.extensions.thirdPartyPayment == ptrue));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0C));
|
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0C));
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
CBOR_FIELD_GET_BYTES(clientDataHash, 1);
|
CBOR_FIELD_GET_BYTES(clientDataHash, 1);
|
||||||
}
|
}
|
||||||
else if (val_u == 0x02) { // rp
|
else if (val_u == 0x02) { // rp
|
||||||
CBOR_PARSE_MAP_START(_f1, 2) {
|
CBOR_PARSE_MAP_START(_f1, 2)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_KEY_TEXT(2);
|
CBOR_FIELD_GET_KEY_TEXT(2);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_TEXT(2, "id", rp.id);
|
CBOR_FIELD_KEY_TEXT_VAL_TEXT(2, "id", rp.id);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_TEXT(2, "name", rp.parent.name);
|
CBOR_FIELD_KEY_TEXT_VAL_TEXT(2, "name", rp.parent.name);
|
||||||
@@ -73,7 +74,8 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
CBOR_PARSE_MAP_END(_f1, 2);
|
CBOR_PARSE_MAP_END(_f1, 2);
|
||||||
}
|
}
|
||||||
else if (val_u == 0x03) { // user
|
else if (val_u == 0x03) { // user
|
||||||
CBOR_PARSE_MAP_START(_f1, 2) {
|
CBOR_PARSE_MAP_START(_f1, 2)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_KEY_TEXT(2);
|
CBOR_FIELD_GET_KEY_TEXT(2);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BYTES(2, "id", user.id);
|
CBOR_FIELD_KEY_TEXT_VAL_BYTES(2, "id", user.id);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_TEXT(2, "name", user.parent.name);
|
CBOR_FIELD_KEY_TEXT_VAL_TEXT(2, "name", user.parent.name);
|
||||||
@@ -83,9 +85,11 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
CBOR_PARSE_MAP_END(_f1, 2);
|
CBOR_PARSE_MAP_END(_f1, 2);
|
||||||
}
|
}
|
||||||
else if (val_u == 0x04) { // pubKeyCredParams
|
else if (val_u == 0x04) { // pubKeyCredParams
|
||||||
CBOR_PARSE_ARRAY_START(_f1, 2) {
|
CBOR_PARSE_ARRAY_START(_f1, 2)
|
||||||
|
{
|
||||||
PublicKeyCredentialParameters *pk = &pubKeyCredParams[pubKeyCredParams_len];
|
PublicKeyCredentialParameters *pk = &pubKeyCredParams[pubKeyCredParams_len];
|
||||||
CBOR_PARSE_MAP_START(_f2, 3) {
|
CBOR_PARSE_MAP_START(_f2, 3)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_KEY_TEXT(3);
|
CBOR_FIELD_GET_KEY_TEXT(3);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_TEXT(3, "type", pk->type);
|
CBOR_FIELD_KEY_TEXT_VAL_TEXT(3, "type", pk->type);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_INT(3, "alg", pk->alg);
|
CBOR_FIELD_KEY_TEXT_VAL_INT(3, "alg", pk->alg);
|
||||||
@@ -96,14 +100,17 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
CBOR_PARSE_ARRAY_END(_f1, 2);
|
CBOR_PARSE_ARRAY_END(_f1, 2);
|
||||||
}
|
}
|
||||||
else if (val_u == 0x05) { // excludeList
|
else if (val_u == 0x05) { // excludeList
|
||||||
CBOR_PARSE_ARRAY_START(_f1, 2) {
|
CBOR_PARSE_ARRAY_START(_f1, 2)
|
||||||
|
{
|
||||||
PublicKeyCredentialDescriptor *pc = &excludeList[excludeList_len];
|
PublicKeyCredentialDescriptor *pc = &excludeList[excludeList_len];
|
||||||
CBOR_PARSE_MAP_START(_f2, 3) {
|
CBOR_PARSE_MAP_START(_f2, 3)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_KEY_TEXT(3);
|
CBOR_FIELD_GET_KEY_TEXT(3);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BYTES(3, "id", pc->id);
|
CBOR_FIELD_KEY_TEXT_VAL_BYTES(3, "id", pc->id);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_TEXT(3, "type", pc->type);
|
CBOR_FIELD_KEY_TEXT_VAL_TEXT(3, "type", pc->type);
|
||||||
if (strcmp(_fd3, "transports") == 0) {
|
if (strcmp(_fd3, "transports") == 0) {
|
||||||
CBOR_PARSE_ARRAY_START(_f3, 4) {
|
CBOR_PARSE_ARRAY_START(_f3, 4)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_TEXT(pc->transports[pc->transports_len], 4);
|
CBOR_FIELD_GET_TEXT(pc->transports[pc->transports_len], 4);
|
||||||
pc->transports_len++;
|
pc->transports_len++;
|
||||||
}
|
}
|
||||||
@@ -117,7 +124,8 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
else if (val_u == 0x06) { // extensions
|
else if (val_u == 0x06) { // extensions
|
||||||
extensions.present = true;
|
extensions.present = true;
|
||||||
CBOR_PARSE_MAP_START(_f1, 2) {
|
CBOR_PARSE_MAP_START(_f1, 2)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_KEY_TEXT(2);
|
CBOR_FIELD_GET_KEY_TEXT(2);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "hmac-secret", extensions.hmac_secret);
|
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "hmac-secret", extensions.hmac_secret);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_UINT(2, "credProtect", extensions.credProtect);
|
CBOR_FIELD_KEY_TEXT_VAL_UINT(2, "credProtect", extensions.credProtect);
|
||||||
@@ -131,7 +139,8 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
else if (val_u == 0x07) { // options
|
else if (val_u == 0x07) { // options
|
||||||
options.present = true;
|
options.present = true;
|
||||||
CBOR_PARSE_MAP_START(_f1, 2) {
|
CBOR_PARSE_MAP_START(_f1, 2)
|
||||||
|
{
|
||||||
CBOR_FIELD_GET_KEY_TEXT(2);
|
CBOR_FIELD_GET_KEY_TEXT(2);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "rk", options.rk);
|
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "rk", options.rk);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "up", options.up);
|
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "up", options.up);
|
||||||
@@ -495,7 +504,8 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
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, self_attestation || is_nitrokey ? -alg : -FIDO2_ALG_ES256));
|
CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2,
|
||||||
|
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) {
|
||||||
|
|||||||
@@ -205,7 +205,9 @@ int credential_load(const uint8_t *cred_id,
|
|||||||
CBOR_FIELD_KEY_TEXT_VAL_UINT(2, "credProtect", cred->extensions.credProtect);
|
CBOR_FIELD_KEY_TEXT_VAL_UINT(2, "credProtect", cred->extensions.credProtect);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BYTES(2, "credBlob", cred->extensions.credBlob);
|
CBOR_FIELD_KEY_TEXT_VAL_BYTES(2, "credBlob", cred->extensions.credBlob);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "largeBlobKey", cred->extensions.largeBlobKey);
|
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "largeBlobKey", cred->extensions.largeBlobKey);
|
||||||
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "thirdPartyPayment", cred->extensions.thirdPartyPayment);
|
CBOR_FIELD_KEY_TEXT_VAL_BOOL(2,
|
||||||
|
"thirdPartyPayment",
|
||||||
|
cred->extensions.thirdPartyPayment);
|
||||||
CBOR_ADVANCE(2);
|
CBOR_ADVANCE(2);
|
||||||
}
|
}
|
||||||
CBOR_PARSE_MAP_END(_f1, 2);
|
CBOR_PARSE_MAP_END(_f1, 2);
|
||||||
|
|||||||
@@ -241,8 +241,15 @@ typedef struct CborCharString {
|
|||||||
} } while (0)
|
} } while (0)
|
||||||
|
|
||||||
extern CborError COSE_key(mbedtls_ecp_keypair *, CborEncoder *, CborEncoder *);
|
extern CborError COSE_key(mbedtls_ecp_keypair *, CborEncoder *, CborEncoder *);
|
||||||
extern CborError COSE_key_shared(mbedtls_ecdh_context *key, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder);
|
extern CborError COSE_key_shared(mbedtls_ecdh_context *key,
|
||||||
|
CborEncoder *mapEncoderParent,
|
||||||
|
CborEncoder *mapEncoder);
|
||||||
extern CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder);
|
extern CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder);
|
||||||
extern CborError COSE_read_key(CborValue *f, int64_t *kty, int64_t *alg, int64_t *crv, CborByteString *kax, CborByteString *kay);
|
extern CborError COSE_read_key(CborValue *f,
|
||||||
|
int64_t *kty,
|
||||||
|
int64_t *alg,
|
||||||
|
int64_t *crv,
|
||||||
|
CborByteString *kax,
|
||||||
|
CborByteString *kay);
|
||||||
|
|
||||||
#endif //_CTAP2_CBOR_H_
|
#endif //_CTAP2_CBOR_H_
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ file_t file_entries[] = {
|
|||||||
{ .fid = EF_LARGEBLOB, .parent = 0, .name = NULL,
|
{ .fid = EF_LARGEBLOB, .parent = 0, .name = NULL,
|
||||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Large Blob
|
.ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Large Blob
|
||||||
{ .fid = EF_OTP_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH,
|
{ .fid = EF_OTP_PIN, .parent = 0, .name = NULL,
|
||||||
|
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH,
|
||||||
.data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } },
|
.data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } },
|
||||||
{ .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL,
|
{ .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL,
|
||||||
.ef_structure = 0, .acl = { 0 } } //end
|
.ef_structure = 0, .acl = { 0 } } //end
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ bool cap_supported(uint16_t cap) {
|
|||||||
if (tag_len == 2) {
|
if (tag_len == 2) {
|
||||||
ecaps = (tag_data[0] << 8) | tag_data[1];
|
ecaps = (tag_data[0] << 8) | tag_data[1];
|
||||||
}
|
}
|
||||||
return (ecaps & cap);
|
return ecaps & cap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,8 @@
|
|||||||
#define ALLOW_UPDATE 0x20 // Allow update of existing configuration (selected flags + access code)
|
#define ALLOW_UPDATE 0x20 // Allow update of existing configuration (selected flags + access code)
|
||||||
#define DORMANT 0x40 // Dormant config (woken up, flag removed, requires update flag)
|
#define DORMANT 0x40 // Dormant config (woken up, flag removed, requires update flag)
|
||||||
#define LED_INV 0x80 // LED idle state is off rather than on
|
#define LED_INV 0x80 // LED idle state is off rather than on
|
||||||
#define EXTFLAG_UPDATE_MASK (SERIAL_BTN_VISIBLE | SERIAL_USB_VISIBLE | SERIAL_API_VISIBLE | USE_NUMERIC_KEYPAD | FAST_TRIG | ALLOW_UPDATE | DORMANT | LED_INV)
|
#define EXTFLAG_UPDATE_MASK (SERIAL_BTN_VISIBLE | SERIAL_USB_VISIBLE | SERIAL_API_VISIBLE | \
|
||||||
|
USE_NUMERIC_KEYPAD | FAST_TRIG | ALLOW_UPDATE | DORMANT | LED_INV)
|
||||||
|
|
||||||
/* TKT Flags */
|
/* TKT Flags */
|
||||||
#define TAB_FIRST 0x01 // Send TAB before first part
|
#define TAB_FIRST 0x01 // Send TAB before first part
|
||||||
@@ -63,7 +64,8 @@
|
|||||||
#define OATH_HOTP 0x40 // OATH HOTP mode
|
#define OATH_HOTP 0x40 // OATH HOTP mode
|
||||||
#define CHAL_RESP 0x40 // Challenge-response enabled (both must be set)
|
#define CHAL_RESP 0x40 // Challenge-response enabled (both must be set)
|
||||||
#define PROTECT_CFG2 0x80 // Block update of config 2 unless config 2 is configured and has this bit set
|
#define PROTECT_CFG2 0x80 // Block update of config 2 unless config 2 is configured and has this bit set
|
||||||
#define TKTFLAG_UPDATE_MASK (TAB_FIRST | APPEND_TAB1 | APPEND_TAB2 | APPEND_DELAY1 | APPEND_DELAY2 | APPEND_CR)
|
#define TKTFLAG_UPDATE_MASK (TAB_FIRST | APPEND_TAB1 | APPEND_TAB2 | APPEND_DELAY1 | APPEND_DELAY2 | \
|
||||||
|
APPEND_CR)
|
||||||
|
|
||||||
/* CFG Flags */
|
/* CFG Flags */
|
||||||
#define SEND_REF 0x01 // Send reference string (0..F) before data
|
#define SEND_REF 0x01 // Send reference string (0..F) before data
|
||||||
@@ -135,7 +137,8 @@ app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t modhex_tab[] = {'c', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'r', 't', 'u', 'v'};
|
uint8_t modhex_tab[] =
|
||||||
|
{ '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 (int l = 0; l < len; l++) {
|
||||||
*out++ = modhex_tab[in[l] >> 4];
|
*out++ = modhex_tab[in[l] >> 4];
|
||||||
@@ -152,7 +155,8 @@ void init_otp() {
|
|||||||
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;
|
||||||
if (file_has_data(ef) && !(otp_config->tkt_flags & OATH_HOTP) && !(otp_config->cfg_flags & SHORT_TICKET || otp_config->cfg_flags & STATIC_TICKET)) {
|
if (file_has_data(ef) && !(otp_config->tkt_flags & OATH_HOTP) &&
|
||||||
|
!(otp_config->cfg_flags & SHORT_TICKET || otp_config->cfg_flags & STATIC_TICKET)) {
|
||||||
uint16_t counter = (data[otp_config_size] << 8) | data[otp_config_size + 1];
|
uint16_t counter = (data[otp_config_size] << 8) | data[otp_config_size + 1];
|
||||||
if (++counter <= 0x7fff) {
|
if (++counter <= 0x7fff) {
|
||||||
uint8_t new_data[otp_config_size + 8];
|
uint8_t new_data[otp_config_size + 8];
|
||||||
@@ -207,12 +211,14 @@ int otp_button_pressed(uint8_t slot) {
|
|||||||
if (imf == 0) {
|
if (imf == 0) {
|
||||||
imf = ((otp_config->uid[4] << 8) | otp_config->uid[5]) << 4;
|
imf = ((otp_config->uid[4] << 8) | otp_config->uid[5]) << 4;
|
||||||
}
|
}
|
||||||
uint8_t chal[8] = {imf >> 56, imf >> 48, imf >> 40, imf >> 32, imf >> 24, imf >> 16, imf >> 8, imf & 0xff};
|
uint8_t chal[8] =
|
||||||
|
{ imf >> 56, imf >> 48, imf >> 40, imf >> 32, imf >> 24, imf >> 16, imf >> 8, imf & 0xff };
|
||||||
res_APDU_size = 0;
|
res_APDU_size = 0;
|
||||||
int ret = calculate_oath(1, tmp_key, sizeof(tmp_key), chal, sizeof(chal));
|
int ret = calculate_oath(1, tmp_key, sizeof(tmp_key), chal, sizeof(chal));
|
||||||
if (ret == CCID_OK) {
|
if (ret == CCID_OK) {
|
||||||
uint32_t base = otp_config->cfg_flags & OATH_HOTP8 ? 1e8 : 1e6;
|
uint32_t base = otp_config->cfg_flags & OATH_HOTP8 ? 1e8 : 1e6;
|
||||||
uint32_t number = (res_APDU[2] << 24) | (res_APDU[3] << 16) | (res_APDU[4] << 8) | res_APDU[5];
|
uint32_t number =
|
||||||
|
(res_APDU[2] << 24) | (res_APDU[3] << 16) | (res_APDU[4] << 8) | res_APDU[5];
|
||||||
number %= base;
|
number %= base;
|
||||||
char number_str[9];
|
char number_str[9];
|
||||||
if (otp_config->cfg_flags & OATH_HOTP8) {
|
if (otp_config->cfg_flags & OATH_HOTP8) {
|
||||||
@@ -224,7 +230,9 @@ int otp_button_pressed(uint8_t slot) {
|
|||||||
add_keyboard_buffer((const uint8_t *) number_str, 6, true);
|
add_keyboard_buffer((const uint8_t *) number_str, 6, true);
|
||||||
}
|
}
|
||||||
imf++;
|
imf++;
|
||||||
uint8_t new_chal[8] = {imf >> 56, imf >> 48, imf >> 40, imf >> 32, imf >> 24, imf >> 16, imf >> 8, imf & 0xff};
|
uint8_t new_chal[8] =
|
||||||
|
{ imf >> 56, imf >> 48, imf >> 40, imf >> 32, imf >> 24, imf >> 16, imf >> 8,
|
||||||
|
imf & 0xff };
|
||||||
uint8_t new_otp_config[otp_config_size + sizeof(new_chal)];
|
uint8_t new_otp_config[otp_config_size + sizeof(new_chal)];
|
||||||
memcpy(new_otp_config, otp_config, otp_config_size);
|
memcpy(new_otp_config, otp_config, otp_config_size);
|
||||||
memcpy(new_otp_config + otp_config_size, new_chal, sizeof(new_chal));
|
memcpy(new_otp_config + otp_config_size, new_chal, sizeof(new_chal));
|
||||||
@@ -379,9 +387,12 @@ int cmd_otp() {
|
|||||||
}
|
}
|
||||||
memcpy(apdu.data, file_get_data(ef), FIXED_SIZE + UID_SIZE + KEY_SIZE);
|
memcpy(apdu.data, file_get_data(ef), FIXED_SIZE + UID_SIZE + KEY_SIZE);
|
||||||
odata->fixed_size = otpc->fixed_size;
|
odata->fixed_size = otpc->fixed_size;
|
||||||
odata->ext_flags = (otpc->ext_flags & ~EXTFLAG_UPDATE_MASK) | (odata->ext_flags & EXTFLAG_UPDATE_MASK);
|
odata->ext_flags = (otpc->ext_flags & ~EXTFLAG_UPDATE_MASK) |
|
||||||
odata->tkt_flags = (otpc->tkt_flags & ~TKTFLAG_UPDATE_MASK) | (odata->tkt_flags & TKTFLAG_UPDATE_MASK);
|
(odata->ext_flags & EXTFLAG_UPDATE_MASK);
|
||||||
odata->cfg_flags = (otpc->cfg_flags & ~CFGFLAG_UPDATE_MASK) | (odata->cfg_flags & CFGFLAG_UPDATE_MASK);
|
odata->tkt_flags = (otpc->tkt_flags & ~TKTFLAG_UPDATE_MASK) |
|
||||||
|
(odata->tkt_flags & TKTFLAG_UPDATE_MASK);
|
||||||
|
odata->cfg_flags = (otpc->cfg_flags & ~CFGFLAG_UPDATE_MASK) |
|
||||||
|
(odata->cfg_flags & CFGFLAG_UPDATE_MASK);
|
||||||
flash_write_data_to_file(ef, apdu.data, otp_config_size);
|
flash_write_data_to_file(ef, apdu.data, otp_config_size);
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
}
|
}
|
||||||
@@ -427,7 +438,12 @@ int cmd_otp() {
|
|||||||
}
|
}
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (p1 == 0x30 || p1 == 0x38) {
|
if (p1 == 0x30 || p1 == 0x38) {
|
||||||
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), otp_config->aes_key, KEY_SIZE, apdu.data, 8, res_APDU);
|
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
|
||||||
|
otp_config->aes_key,
|
||||||
|
KEY_SIZE,
|
||||||
|
apdu.data,
|
||||||
|
8,
|
||||||
|
res_APDU);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
res_APDU_size = 20;
|
res_APDU_size = 20;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#ifndef __VERSION_H_
|
#ifndef __VERSION_H_
|
||||||
#define __VERSION_H_
|
#define __VERSION_H_
|
||||||
|
|
||||||
#define PICO_FIDO_VERSION 0x0504
|
#define PICO_FIDO_VERSION 0x0506
|
||||||
|
|
||||||
#define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff)
|
#define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff)
|
||||||
#define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff)
|
#define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff)
|
||||||
|
|||||||
Reference in New Issue
Block a user