Moving from U2F to CTAP1.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Submodule pico-hsm-sdk updated: 7491021102...867d4637ee
@@ -18,19 +18,19 @@
|
|||||||
#include "fido.h"
|
#include "fido.h"
|
||||||
#include "hsm.h"
|
#include "hsm.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "u2f.h"
|
#include "ctap.h"
|
||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
int cmd_authenticate() {
|
int cmd_authenticate() {
|
||||||
U2F_AUTHENTICATE_REQ *req = (U2F_AUTHENTICATE_REQ *)apdu.data;
|
CTAP_AUTHENTICATE_REQ *req = (CTAP_AUTHENTICATE_REQ *)apdu.data;
|
||||||
U2F_AUTHENTICATE_RESP *resp = (U2F_AUTHENTICATE_RESP *)res_APDU;
|
CTAP_AUTHENTICATE_RESP *resp = (CTAP_AUTHENTICATE_RESP *)res_APDU;
|
||||||
if (scan_files() != CCID_OK)
|
if (scan_files() != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
if (req->keyHandleLen != KEY_HANDLE_LEN)
|
if (req->keyHandleLen != KEY_HANDLE_LEN)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
if (P1(apdu) == U2F_AUTH_ENFORCE && wait_button_pressed() == true)
|
if (P1(apdu) == CTAP_AUTH_ENFORCE && wait_button_pressed() == true)
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
|
|
||||||
mbedtls_ecdsa_context key;
|
mbedtls_ecdsa_context key;
|
||||||
@@ -40,7 +40,7 @@ int cmd_authenticate() {
|
|||||||
mbedtls_ecdsa_free(&key);
|
mbedtls_ecdsa_free(&key);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
if (P1(apdu) == U2F_AUTH_CHECK_ONLY) {
|
if (P1(apdu) == CTAP_AUTH_CHECK_ONLY) {
|
||||||
for (int i = 0; i < KEY_PATH_ENTRIES; i++) {
|
for (int i = 0; i < KEY_PATH_ENTRIES; i++) {
|
||||||
uint32_t k = *(uint32_t *)&req->keyHandle[i*sizeof(uint32_t)];
|
uint32_t k = *(uint32_t *)&req->keyHandle[i*sizeof(uint32_t)];
|
||||||
if (!(k & 0x80000000)) {
|
if (!(k & 0x80000000)) {
|
||||||
@@ -53,9 +53,9 @@ int cmd_authenticate() {
|
|||||||
mbedtls_ecdsa_free(&key);
|
mbedtls_ecdsa_free(&key);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
uint8_t key_base[U2F_APPID_SIZE + KEY_PATH_LEN];
|
uint8_t key_base[CTAP_APPID_SIZE + KEY_PATH_LEN];
|
||||||
memcpy(key_base, req->appId, U2F_APPID_SIZE);
|
memcpy(key_base, req->appId, CTAP_APPID_SIZE);
|
||||||
memcpy(key_base + U2F_APPID_SIZE, req->keyHandle, KEY_PATH_LEN);
|
memcpy(key_base + CTAP_APPID_SIZE, req->keyHandle, KEY_PATH_LEN);
|
||||||
ret = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), d, 32, key_base, sizeof(key_base), hmac);
|
ret = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), d, 32, key_base, sizeof(key_base), hmac);
|
||||||
mbedtls_platform_zeroize(d, sizeof(d));
|
mbedtls_platform_zeroize(d, sizeof(d));
|
||||||
if (memcmp(req->keyHandle + KEY_PATH_LEN, hmac, sizeof(hmac)) != 0)
|
if (memcmp(req->keyHandle + KEY_PATH_LEN, hmac, sizeof(hmac)) != 0)
|
||||||
@@ -63,24 +63,24 @@ int cmd_authenticate() {
|
|||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
resp->flags = 0;
|
resp->flags = 0;
|
||||||
resp->flags |= P1(apdu) == U2F_AUTH_ENFORCE ? U2F_AUTH_FLAG_TUP : 0x0;
|
resp->flags |= P1(apdu) == CTAP_AUTH_ENFORCE ? CTAP_AUTH_FLAG_TUP : 0x0;
|
||||||
uint32_t ctr = *(uint32_t *)file_get_data(ef_counter);
|
uint32_t ctr = *(uint32_t *)file_get_data(ef_counter);
|
||||||
resp->ctr[0] = ctr >> 24;
|
resp->ctr[0] = ctr >> 24;
|
||||||
resp->ctr[1] = ctr >> 16;
|
resp->ctr[1] = ctr >> 16;
|
||||||
resp->ctr[2] = ctr >> 8;
|
resp->ctr[2] = ctr >> 8;
|
||||||
resp->ctr[3] = ctr & 0xff;
|
resp->ctr[3] = ctr & 0xff;
|
||||||
uint8_t hash[32], sig_base[U2F_APPID_SIZE + 1 + 4 + U2F_CHAL_SIZE];
|
uint8_t hash[32], sig_base[CTAP_APPID_SIZE + 1 + 4 + CTAP_CHAL_SIZE];
|
||||||
memcpy(sig_base, req->appId, U2F_APPID_SIZE);
|
memcpy(sig_base, req->appId, CTAP_APPID_SIZE);
|
||||||
memcpy(sig_base+U2F_APPID_SIZE, &resp->flags, sizeof(uint8_t));
|
memcpy(sig_base+CTAP_APPID_SIZE, &resp->flags, sizeof(uint8_t));
|
||||||
memcpy(sig_base + U2F_APPID_SIZE + 1, resp->ctr, 4);
|
memcpy(sig_base + CTAP_APPID_SIZE + 1, resp->ctr, 4);
|
||||||
memcpy(sig_base + U2F_APPID_SIZE + 1 + 4, req->chal, U2F_CHAL_SIZE);
|
memcpy(sig_base + CTAP_APPID_SIZE + 1 + 4, req->chal, CTAP_CHAL_SIZE);
|
||||||
ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), sig_base, sizeof(sig_base), hash);
|
ret = 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, MBEDTLS_MD_SHA256, hash, 32, (uint8_t *)resp->sig, U2F_MAX_EC_SIG_SIZE, &olen, random_gen, NULL);
|
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_ecdsa_free(&key);
|
mbedtls_ecdsa_free(&key);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
|
|||||||
@@ -18,19 +18,19 @@
|
|||||||
#include "fido.h"
|
#include "fido.h"
|
||||||
#include "hsm.h"
|
#include "hsm.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "u2f.h"
|
#include "ctap.h"
|
||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
int cmd_register() {
|
int cmd_register() {
|
||||||
U2F_REGISTER_REQ *req = (U2F_REGISTER_REQ *)apdu.data;
|
CTAP_REGISTER_REQ *req = (CTAP_REGISTER_REQ *)apdu.data;
|
||||||
U2F_REGISTER_RESP *resp = (U2F_REGISTER_RESP *)res_APDU;
|
CTAP_REGISTER_RESP *resp = (CTAP_REGISTER_RESP *)res_APDU;
|
||||||
resp->registerId = U2F_REGISTER_ID;
|
resp->registerId = CTAP_REGISTER_ID;
|
||||||
resp->keyHandleLen = KEY_HANDLE_LEN;
|
resp->keyHandleLen = KEY_HANDLE_LEN;
|
||||||
if (scan_files() != CCID_OK)
|
if (scan_files() != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
if (apdu.nc != U2F_APPID_SIZE + U2F_CHAL_SIZE)
|
if (apdu.nc != CTAP_APPID_SIZE + CTAP_CHAL_SIZE)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
if (wait_button_pressed() == true)
|
if (wait_button_pressed() == true)
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
@@ -42,19 +42,19 @@ int cmd_register() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
ret = mbedtls_ecp_point_write_binary(&key.grp, &key.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, (uint8_t *)&resp->pubKey, U2F_EC_POINT_SIZE);
|
ret = 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);
|
size_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], sign_base[1 + U2F_APPID_SIZE + U2F_CHAL_SIZE + KEY_HANDLE_LEN + U2F_EC_POINT_SIZE];
|
uint8_t hash[32], sign_base[1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE + KEY_HANDLE_LEN + CTAP_EC_POINT_SIZE];
|
||||||
sign_base[0] = U2F_REGISTER_HASH_ID;
|
sign_base[0] = CTAP_REGISTER_HASH_ID;
|
||||||
memcpy(sign_base + 1, req->appId, U2F_APPID_SIZE);
|
memcpy(sign_base + 1, req->appId, CTAP_APPID_SIZE);
|
||||||
memcpy(sign_base + 1 + U2F_APPID_SIZE, req->chal, U2F_CHAL_SIZE);
|
memcpy(sign_base + 1 + CTAP_APPID_SIZE, req->chal, CTAP_CHAL_SIZE);
|
||||||
memcpy(sign_base + 1 + U2F_APPID_SIZE + U2F_CHAL_SIZE, resp->keyHandleCertSig, KEY_HANDLE_LEN);
|
memcpy(sign_base + 1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE, resp->keyHandleCertSig, KEY_HANDLE_LEN);
|
||||||
memcpy(sign_base + 1 + U2F_APPID_SIZE + U2F_CHAL_SIZE + KEY_HANDLE_LEN, (uint8_t *)&resp->pubKey, U2F_EC_POINT_SIZE);
|
memcpy(sign_base + 1 + CTAP_APPID_SIZE + CTAP_CHAL_SIZE + KEY_HANDLE_LEN, (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);
|
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();
|
||||||
@@ -64,11 +64,11 @@ 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, MBEDTLS_MD_SHA256, hash, 32, (uint8_t *)resp->keyHandleCertSig + KEY_HANDLE_LEN + ef_certdev_size, U2F_MAX_EC_SIG_SIZE, &olen, random_gen, NULL);
|
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_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(U2F_REGISTER_RESP) - sizeof(resp->keyHandleCertSig) + KEY_HANDLE_LEN + ef_certdev_size + olen;
|
res_APDU_size = sizeof(CTAP_REGISTER_RESP) - sizeof(resp->keyHandleCertSig) + KEY_HANDLE_LEN + ef_certdev_size + olen;
|
||||||
DEBUG_PAYLOAD(res_APDU, res_APDU_size);
|
DEBUG_PAYLOAD(res_APDU, res_APDU_size);
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "hsm.h"
|
#include "hsm.h"
|
||||||
|
|
||||||
int cmd_version() {
|
int cmd_version() {
|
||||||
memcpy(res_APDU, "U2F_V2", strlen("U2F_V2"));
|
memcpy(res_APDU, "CTAP_V2", strlen("U2F_V2"));
|
||||||
res_APDU_size = strlen("U2F_V2");
|
res_APDU_size = strlen("U2F_V2");
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "fido.h"
|
#include "fido.h"
|
||||||
#include "hsm.h"
|
#include "hsm.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "u2f.h"
|
#include "ctap.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
@@ -112,9 +112,9 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, mbedtls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (new_key == true) {
|
if (new_key == true) {
|
||||||
uint8_t key_base[U2F_APPID_SIZE + KEY_PATH_LEN];
|
uint8_t key_base[CTAP_APPID_SIZE + KEY_PATH_LEN];
|
||||||
memcpy(key_base, app_id, U2F_APPID_SIZE);
|
memcpy(key_base, app_id, CTAP_APPID_SIZE);
|
||||||
memcpy(key_base + U2F_APPID_SIZE, key_handle, KEY_PATH_LEN);
|
memcpy(key_base + CTAP_APPID_SIZE, key_handle, KEY_PATH_LEN);
|
||||||
if ((r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), outk, 32, key_base, sizeof(key_base), key_handle + 32)) != 0)
|
if ((r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), outk, 32, key_base, sizeof(key_base), key_handle + 32)) != 0)
|
||||||
{
|
{
|
||||||
mbedtls_platform_zeroize(outk, sizeof(outk));
|
mbedtls_platform_zeroize(outk, sizeof(outk));
|
||||||
@@ -225,9 +225,9 @@ extern int cmd_authenticate();
|
|||||||
extern int cmd_version();
|
extern int cmd_version();
|
||||||
|
|
||||||
static const cmd_t cmds[] = {
|
static const cmd_t cmds[] = {
|
||||||
{ U2F_REGISTER, cmd_register },
|
{ CTAP_REGISTER, cmd_register },
|
||||||
{ U2F_AUTHENTICATE, cmd_authenticate },
|
{ CTAP_AUTHENTICATE, cmd_authenticate },
|
||||||
{ U2F_VERSION, cmd_version },
|
{ CTAP_VERSION, cmd_version },
|
||||||
{ 0x00, 0x0}
|
{ 0x00, 0x0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
|
|
||||||
#define U2F_PUBKEY_LEN (65)
|
#define CTAP_PUBKEY_LEN (65)
|
||||||
#define KEY_PATH_LEN (32)
|
#define KEY_PATH_LEN (32)
|
||||||
#define KEY_PATH_ENTRIES (KEY_PATH_LEN / sizeof(uint32_t))
|
#define KEY_PATH_ENTRIES (KEY_PATH_LEN / sizeof(uint32_t))
|
||||||
#define SHA256_DIGEST_LENGTH (32)
|
#define SHA256_DIGEST_LENGTH (32)
|
||||||
|
|||||||
Reference in New Issue
Block a user