Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/algo ext #78

Merged
merged 13 commits into from
Jan 2, 2024
14 changes: 9 additions & 5 deletions applets/admin/admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ uint8_t cfg_is_webusb_landing_enable(void) { return current_config.webusb_landin

uint8_t cfg_is_kbd_with_return_enable(void) { return current_config.kbd_with_return_en; }

uint8_t cfg_is_piv_algo_extension_enable(void) { return current_config.piv_algo_ext_en; }

void admin_poweroff(void) { pin.is_validated = 0; }

int admin_install(const uint8_t reset) {
Expand Down Expand Up @@ -131,9 +129,6 @@ static int admin_config(const CAPDU *capdu, RAPDU *rapdu) {
case ADMIN_P1_CFG_KBD_WITH_RETURN:
current_config.kbd_with_return_en = P2 & 1;
break;
case ADMIN_P1_CFG_PIV_ALGO_EXT:
current_config.piv_algo_ext_en = P2 & 1;
break;
default:
EXCEPT(SW_WRONG_P1P2);
}
Expand Down Expand Up @@ -266,6 +261,15 @@ int admin_process_apdu(const CAPDU *capdu, RAPDU *rapdu) {
case ADMIN_INS_TOGGLE_NDEF_READ_ONLY:
ret = ndef_toggle_read_only(capdu, rapdu);
break;
case ADMIN_INS_RESET_CTAP:
ret = ctap_install(1);
break;
case ADMIN_INS_READ_CTAP_SM2_CONFIG:
ret = ctap_read_sm2_config(capdu, rapdu);
break;
case ADMIN_INS_WRITE_CTAP_SM2_CONFIG:
ret = ctap_write_sm2_config(capdu, rapdu);
break;
case ADMIN_INS_CHANGE_PIN:
ret = admin_change_pin(capdu, rapdu);
break;
Expand Down
19 changes: 7 additions & 12 deletions applets/ctap/cose-key.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@

#define COSE_KEY_LABEL_KTY 1
#define COSE_KEY_LABEL_ALG 3
#define COSE_KEY_LABEL_CRV (-1)
#define COSE_KEY_LABEL_X (-2)
#define COSE_KEY_LABEL_Y (-3)
#define COSE_KEY_LABEL_CRV -1
#define COSE_KEY_LABEL_X -2
#define COSE_KEY_LABEL_Y -3

#define COSE_KEY_KTY_OKP 1
#define COSE_KEY_KTY_EC2 2

#define COSE_KEY_CRV_P256 1
#define COSE_KEY_CRV_ED25519 6
#define COSE_KEY_CRV_SM2 9

#define COSE_ALG_ES256 (-7)
#define COSE_ALG_EDDSA (-8)
#define COSE_ALG_ECDH_ES_HKDF_256 (-25)
#define COSE_ALG_SM2 (-48)

#define COSE_KEY_ES256_SIZE 77
#define COSE_KEY_ECDH_ES_HKDF_257_SIZE 78
#define COSE_KEY_EDDSA_SIZE 42
#define COSE_ALG_ES256 -7
#define COSE_ALG_EDDSA -8
#define COSE_ALG_ECDH_ES_HKDF_256 -25

#endif // CANOKEY_CORE_FIDO2_COSE_KEY_H_
7 changes: 7 additions & 0 deletions applets/ctap/ctap-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define PIN_CTR_ATTR 0x03
#define KH_KEY_ATTR 0x04
#define HE_KEY_ATTR 0x05
#define SM2_ATTR 0x06
#define DC_FILE "ctap_dc"
#define DC_GENERAL_ATTR 0x00
#define DC_META_FILE "ctap_dm"
Expand Down Expand Up @@ -364,6 +365,12 @@ typedef struct {
uint8_t pin_uv_auth_param[SHA256_DIGEST_LENGTH];
} CTAP_large_blobs;

typedef struct {
uint8_t enabled;
int32_t curve_id;
int32_t algo_id;
} __packed CTAP_sm2_attr;

int u2f_register(const CAPDU *capdu, RAPDU *rapdu);
int u2f_authenticate(const CAPDU *capdu, RAPDU *rapdu);
int u2f_version(const CAPDU *capdu, RAPDU *rapdu);
Expand Down
9 changes: 7 additions & 2 deletions applets/ctap/ctap-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
if (ret != CborNoError) return CTAP2_ERR_INVALID_CBOR; \
} while (0)

extern CTAP_sm2_attr ctap_sm2_attr;

static void maybe_truncate_rpid(uint8_t stored_rpid[MAX_STORED_RPID_LENGTH], size_t *stored_len, const uint8_t *rpid,
size_t rpid_len) {
if (rpid_len <= MAX_STORED_RPID_LENGTH) {
Expand Down Expand Up @@ -183,7 +185,9 @@ uint8_t parse_verify_pub_key_cred_params(CborValue *val, int32_t *alg_type) {
for (size_t i = 0; i < arr_length; ++i) {
ret = parse_pub_key_cred_param(&arr, &cur_alg_type);
CHECK_PARSER_RET(ret);
if (ret == 0 && (cur_alg_type == COSE_ALG_ES256 || cur_alg_type == COSE_ALG_EDDSA)) {
if (ret == 0 && (cur_alg_type == COSE_ALG_ES256 ||
cur_alg_type == COSE_ALG_EDDSA ||
(ctap_sm2_attr.enabled && cur_alg_type == ctap_sm2_attr.algo_id))) {
// https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.html#authenticatorMakeCredential
//
// > This sequence is ordered from most preferred (by the RP) to least preferred.
Expand Down Expand Up @@ -314,7 +318,7 @@ uint8_t parse_cose_key(CborValue *val, uint8_t *public_key) {
if (cbor_value_get_type(&map) != CborIntegerType) return CTAP2_ERR_CBOR_UNEXPECTED_TYPE;
ret = cbor_value_get_int_checked(&map, &key);
CHECK_CBOR_RET(ret);
if (key != COSE_ALG_ES256 && key != COSE_ALG_ECDH_ES_HKDF_256) return CTAP2_ERR_UNHANDLED_REQUEST;
if (key != COSE_ALG_ECDH_ES_HKDF_256) return CTAP2_ERR_UNHANDLED_REQUEST;
++parsed_keys;
break;

Expand Down Expand Up @@ -674,6 +678,7 @@ uint8_t parse_make_credential(CborParser *parser, CTAP_make_credential *mc, cons
CHECK_PARSER_RET(ret);
if (mc->alg_type == COSE_ALG_ES256) DBG_MSG("EcDSA found\n");
else if (mc->alg_type == COSE_ALG_EDDSA) DBG_MSG("EdDSA found\n");
else if (mc->alg_type == ctap_sm2_attr.algo_id) DBG_MSG("SM2 found\n");
else
DBG_MSG("Found other algorithm\n");
mc->parsed_params |= PARAM_PUB_KEY_CRED_PARAMS;
Expand Down
Loading
Loading