Upgrade to v5.0

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2024-11-09 18:09:48 +01:00
37 changed files with 646 additions and 596 deletions

View File

@@ -38,7 +38,7 @@ int node_derive_bip_child(const mbedtls_ecp_keypair *parent,
mbedtls_mpi_init(&kchild);
if (i[0] >= 0x80) {
if (mbedtls_mpi_cmp_int(&parent->d, 0) == 0) {
return CCID_ERR_NULL_PARAM;
return PICOKEY_ERR_NULL_PARAM;
}
data[0] = 0x00;
mbedtls_mpi_write_binary(&parent->d, data + 1, 32);
@@ -72,19 +72,19 @@ int node_derive_bip_child(const mbedtls_ecp_keypair *parent,
memcpy(cchild, iR, 32);
mbedtls_mpi_free(&il);
mbedtls_mpi_free(&kchild);
return CCID_OK;
return PICOKEY_OK;
}
int sha256_ripemd160(const uint8_t *buffer, size_t buffer_len, uint8_t *output) {
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), buffer, buffer_len, output);
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160), output, 32, output);
return CCID_OK;
return PICOKEY_OK;
}
int sha256_sha256(const uint8_t *buffer, size_t buffer_len, uint8_t *output) {
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), buffer, buffer_len, output);
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), output, 32, output);
return CCID_OK;
return PICOKEY_OK;
}
int node_fingerprint_bip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) {
@@ -98,7 +98,7 @@ int node_fingerprint_bip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) {
sizeof(buffer));
sha256_ripemd160(buffer, sizeof(buffer), buffer);
memcpy(fingerprint, buffer, 4);
return CCID_OK;
return PICOKEY_OK;
}
int node_fingerprint_slip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) {
@@ -106,7 +106,7 @@ int node_fingerprint_slip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) {
mbedtls_mpi_write_binary(&ctx->d, buffer, sizeof(buffer));
sha256_ripemd160(buffer, sizeof(buffer), buffer);
memcpy(fingerprint, buffer, 4);
return CCID_OK;
return PICOKEY_OK;
}
int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32],
@@ -115,13 +115,13 @@ int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32],
mbedtls_ecp_keypair_init(ctx);
file_t *ef = search_file(EF_MASTER_SEED | mid);
if (!file_has_data(ef)) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
memcpy(mkey, file_get_data(ef), sizeof(mkey));
int r = mkek_decrypt(mkey + 1,
sizeof(mkey) - 1);
if (r != CCID_OK) {
return CCID_EXEC_ERROR;
if (r != PICOKEY_OK) {
return PICOKEY_EXEC_ERROR;
}
if (mkey[0] == 0x1 || mkey[0] == 0x2) {
if (mkey[0] == 0x1) {
@@ -131,7 +131,7 @@ int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32],
mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1);
}
else {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
mbedtls_mpi_read_binary(&ctx->d, mkey + 1, 32);
@@ -143,7 +143,7 @@ int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32],
memcpy(chain, mkey + 1, 32);
}
key_type[0] = mkey[0];
return CCID_OK;
return PICOKEY_OK;
}
int node_derive_path(const uint8_t *path,
@@ -166,16 +166,16 @@ int node_derive_path(const uint8_t *path,
for (; walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data); node++) {
if (tag == 0x02) {
if ((node == 0 && tag_len != 1) || (node != 0 && tag_len != 4)) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (node == 0) {
if ((r = load_master_bip(tag_data[0], ctx, chain, key_type)) != CCID_OK) {
if ((r = load_master_bip(tag_data[0], ctx, chain, key_type)) != PICOKEY_OK) {
return r;
}
}
else if (node > 0) {
node_fingerprint_bip(ctx, fingerprint);
if ((r = node_derive_bip_child(ctx, chain, tag_data, ctx, chain)) != CCID_OK) {
if ((r = node_derive_bip_child(ctx, chain, tag_data, ctx, chain)) != PICOKEY_OK) {
return r;
}
memcpy(last_node, tag_data, 4);
@@ -183,7 +183,7 @@ int node_derive_path(const uint8_t *path,
}
else if (tag == 0x04) {
if (node == 0) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
else if (node > 0) {
node_fingerprint_slip(ctx, fingerprint);
@@ -202,7 +202,7 @@ int node_derive_path(const uint8_t *path,
if (nodes) {
*nodes = node;
}
return CCID_OK;
return PICOKEY_OK;
}
int cmd_bip_slip() {
@@ -253,11 +253,11 @@ int cmd_bip_slip() {
mkey[0] = p1;
file_t *ef = file_new(EF_MASTER_SEED | p2);
int r = mkek_encrypt(mkey + 1, sizeof(mkey) - 1);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
r = file_put_data(ef, mkey, sizeof(mkey));
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
@@ -271,7 +271,7 @@ int cmd_bip_slip() {
size_t olen = 0;
int r =
node_derive_path(apdu.data, (uint16_t)apdu.nc, &ctx, chain, fgpt, &nodes, last_node, &key_type);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
@@ -317,7 +317,7 @@ int cmd_bip_slip() {
&nodes,
last_node,
&hd_keytype);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&hd_context);
return SW_EXEC_ERROR();
}

View File

@@ -42,7 +42,7 @@ int cmd_change_pin() {
}
uint8_t mkek[MKEK_SIZE];
r = load_mkek(mkek); //loads the MKEK with old pin
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
//encrypt MKEK with new pin
@@ -57,7 +57,7 @@ int cmd_change_pin() {
}
r = store_mkek(mkek);
release_mkek(mkek);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
uint8_t dhash[33];

View File

@@ -48,9 +48,9 @@ int cmd_decrypt_asym() {
mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
}
int r = load_private_key_rsa(&ctx, ef);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_rsa_free(&ctx);
if (r == CCID_VERIFICATION_FAILED) {
if (r == PICOKEY_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -178,7 +178,7 @@ int cmd_decrypt_asym() {
if (file_get_size(tf) == kdom_uid.len &&
memcmp(file_get_data(tf), kdom_uid.data, kdom_uid.len) == 0) {
file_new(EF_DKEK + n);
if (store_dkek_key(n, res_APDU + 1) != CCID_OK) {
if (store_dkek_key(n, res_APDU + 1) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
mbedtls_platform_zeroize(res_APDU, 32);

View File

@@ -38,7 +38,7 @@ int cmd_delete_file() {
if (!authenticate_action(ef, ACL_OP_DELETE_SELF)) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
if (delete_file(ef) != CCID_OK) {
if (delete_file(ef) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
return SW_OK();

View File

@@ -57,9 +57,9 @@ int cmd_derive_asym() {
int r;
r = load_private_key_ec(&ctx, fkey);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ctx);
if (r == CCID_VERIFICATION_FAILED) {
if (r == PICOKEY_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -88,7 +88,7 @@ int cmd_derive_asym() {
return SW_EXEC_ERROR();
}
r = store_keys(&ctx, PICO_KEYS_KEY_EC, dest_id);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}

View File

@@ -28,6 +28,19 @@
#include "kek.h"
#include "mbedtls/hkdf.h"
#include "mbedtls/chachapoly.h"
#ifdef PICO_RP2350
#include "otp.h"
#endif
#define CMD_DATETIME 0xA
#define CMD_DYNOPS 0x6
#define CMD_SECURE_LOCK 0x3A
#define SECURE_LOCK_KEY_AGREEMENT 0x1
#define SECURE_LOCK_ENABLE 0x2
#define SECURE_LOCK_MASK 0x3
#define SECURE_LOCK_DISABLE 0x4
#define CMD_PHY 0x1B
#define CMD_OTP 0x4C
int cmd_extras() {
#ifndef ENABLE_EMULATION
@@ -40,7 +53,7 @@ int cmd_extras() {
if (wait_button_pressed() == true) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
if (P1(apdu) == 0xA) { //datetime operations
if (P1(apdu) == CMD_DATETIME) { //datetime operations
if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2();
}
@@ -84,7 +97,7 @@ int cmd_extras() {
#endif
}
}
else if (P1(apdu) == 0x6) { //dynamic options
else if (P1(apdu) == CMD_DYNOPS) { //dynamic options
if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2();
}
@@ -103,11 +116,11 @@ int cmd_extras() {
low_flash_available();
}
}
else if (P1(apdu) == 0x3A) { // secure lock
else if (P1(apdu) == CMD_SECURE_LOCK) { // secure lock
if (apdu.nc == 0) {
return SW_WRONG_LENGTH();
}
if (P2(apdu) == 0x01) { // Key Agreement
if (P2(apdu) == SECURE_LOCK_KEY_AGREEMENT) { // Key Agreement
mbedtls_ecdh_context hkey;
mbedtls_ecdh_init(&hkey);
mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1);
@@ -143,7 +156,7 @@ int cmd_extras() {
mse.init = true;
res_APDU_size = (uint16_t)olen;
}
else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) {
else if (P2(apdu) == SECURE_LOCK_ENABLE || P2(apdu) == SECURE_LOCK_MASK || P2(apdu) == SECURE_LOCK_DISABLE) {
if (mse.init == false) {
return SW_COMMAND_NOT_ALLOWED();
}
@@ -152,11 +165,11 @@ int cmd_extras() {
if (ret != 0) {
return SW_WRONG_DATA();
}
if (P2(apdu) == 0x02 || P2(apdu) == 0x04) { // Enable
if (P2(apdu) == SECURE_LOCK_ENABLE || P2(apdu) == SECURE_LOCK_DISABLE) { // Enable
uint16_t opts = get_device_options();
uint8_t newopts[] = { opts >> 8, (opts & 0xff) };
if ((P2(apdu) == 0x02 && !(opts & HSM_OPT_SECURE_LOCK)) ||
(P2(apdu) == 0x04 && (opts & HSM_OPT_SECURE_LOCK))) {
if ((P2(apdu) == SECURE_LOCK_ENABLE && !(opts & HSM_OPT_SECURE_LOCK)) ||
(P2(apdu) == SECURE_LOCK_DISABLE && (opts & HSM_OPT_SECURE_LOCK))) {
uint16_t tfids[] = { EF_MKEK, EF_MKEK_SO };
for (int t = 0; t < sizeof(tfids) / sizeof(uint16_t); t++) {
file_t *tf = search_file(tfids[t]);
@@ -171,24 +184,24 @@ int cmd_extras() {
}
}
}
if (P2(apdu) == 0x02) {
if (P2(apdu) == SECURE_LOCK_ENABLE) {
newopts[0] |= HSM_OPT_SECURE_LOCK >> 8;
}
else if (P2(apdu) == 0x04) {
else if (P2(apdu) == SECURE_LOCK_DISABLE) {
newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8;
}
file_t *tf = search_file(EF_DEVOPS);
file_put_data(tf, newopts, sizeof(newopts));
low_flash_available();
}
else if (P2(apdu) == 0x03) {
else if (P2(apdu) == SECURE_LOCK_MASK) {
memcpy(mkek_mask, apdu.data, apdu.nc);
has_mkek_mask = true;
}
}
}
#ifndef ENABLE_EMULATION
else if (P1(apdu) == 0x1B) { // Set PHY
else if (P1(apdu) == CMD_PHY) { // Set PHY
if (apdu.nc == 0) {
if (file_has_data(ef_phy)) {
res_APDU_size = file_get_size(ef_phy);
@@ -196,50 +209,84 @@ int cmd_extras() {
}
}
else {
uint8_t tmp[PHY_MAX_SIZE];
memset(tmp, 0, sizeof(tmp));
uint16_t opts = 0;
if (file_has_data(ef_phy)) {
memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy)));
if (file_get_size(ef_phy) >= 8) {
opts = (tmp[PHY_OPTS] << 8) | tmp[PHY_OPTS + 1];
}
}
if (P2(apdu) == PHY_VID) { // VIDPID
if (P2(apdu) == PHY_VIDPID) { // VIDPID
if (apdu.nc != 4) {
return SW_WRONG_LENGTH();
}
memcpy(tmp + PHY_VID, apdu.data, 4);
opts |= PHY_OPT_VPID;
phy_data.vid = (apdu.data[0] << 8) | apdu.data[1];
phy_data.pid = (apdu.data[2] << 8) | apdu.data[3];
phy_data.vidpid_present = true;
}
else if (P2(apdu) == PHY_LED_GPIO || P2(apdu) == PHY_LED_MODE) {
if (apdu.nc != 1) {
return SW_WRONG_LENGTH();
}
tmp[P2(apdu)] = apdu.data[0];
if (P2(apdu) == PHY_LED_GPIO) {
opts |= PHY_OPT_GPIO;
}
else if (P2(apdu) == PHY_LED_MODE) {
opts |= PHY_OPT_LED;
}
else if (P2(apdu) == PHY_LED_GPIO) {
phy_data.led_gpio = apdu.data[0];
phy_data.led_gpio_present = true;
}
else if (P2(apdu) == PHY_LED_BTNESS) {
phy_data.led_brightness = apdu.data[0];
phy_data.led_brightness_present = true;
}
else if (P2(apdu) == PHY_OPTS) {
if (apdu.nc != 2) {
return SW_WRONG_LENGTH();
}
uint16_t opt = (apdu.data[0] << 8) | apdu.data[1];
opts = (opts & ~PHY_OPT_MASK) | (opt & PHY_OPT_MASK);
phy_data.opts = (apdu.data[0] << 8) | apdu.data[1];
}
else {
return SW_INCORRECT_P1P2();
}
tmp[PHY_OPTS] = opts >> 8;
tmp[PHY_OPTS + 1] = opts & 0xff;
file_put_data(ef_phy, tmp, sizeof(tmp));
uint8_t tmp[PHY_MAX_SIZE];
uint16_t tmp_len = 0;
memset(tmp, 0, sizeof(tmp));
if (phy_serialize_data(&phy_data, tmp, &tmp_len) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
file_put_data(ef_phy, tmp, tmp_len);
low_flash_available();
}
}
#endif
#if PICO_RP2350
else if (P1(apdu) == CMD_OTP) {
if (apdu.nc < 2) {
return SW_WRONG_LENGTH();
}
uint16_t row = (apdu.data[0] << 8) | apdu.data[1];
bool israw = P2(apdu) == 0x1;
if (apdu.nc == 2) {
if (row > 0xbf && row < 0xf48) {
return SW_WRONG_DATA();
}
if (israw) {
memcpy(res_APDU, otp_buffer_raw(row), apdu.ne);
}
else {
memcpy(res_APDU, otp_buffer(row), apdu.ne);
}
res_APDU_size = apdu.ne;
}
else {
apdu.nc -= 2;
apdu.data += 2;
if (apdu.nc > 1024) {
return SW_WRONG_LENGTH();
}
if (apdu.nc % (israw ? 4 : 2)) {
return SW_WRONG_DATA();
}
uint8_t adata[1024] __attribute__((aligned(4)));
memcpy(adata, apdu.data, apdu.nc);
int ret = 0;
if (israw) {
ret = otp_write_data_raw(row, adata, apdu.nc);
}
else {
ret = otp_write_data(row, adata, apdu.nc);
}
if (ret != 0) {
return SW_EXEC_ERROR();
}
}
}
#endif
else {
return SW_INCORRECT_P1P2();

View File

@@ -47,7 +47,7 @@ int cmd_general_authenticate() {
mbedtls_ecp_keypair ectx;
mbedtls_ecp_keypair_init(&ectx);
r = load_private_key_ecdh(&ectx, fkey);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ectx);
return SW_EXEC_ERROR();
}
@@ -106,7 +106,7 @@ int cmd_general_authenticate() {
r = sm_sign(t, pubkey_len + 16, res_APDU + res_APDU_size);
free(t);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
res_APDU_size += 8;

View File

@@ -23,6 +23,7 @@
#include "version.h"
#include "asn1.h"
#include "cvc.h"
#include "otp.h"
extern void scan_all();
@@ -132,10 +133,10 @@ int cmd_initialize() {
release_mkek(mkek);
return SW_EXEC_ERROR();
}
if (ret_mkek != CCID_OK) {
if (ret_mkek != PICOKEY_OK) {
ret_mkek = load_mkek(mkek); //Try again with new PIN/SO-PIN just in case some is the same
}
if (store_mkek(ret_mkek == CCID_OK ? mkek : NULL) != CCID_OK) {
if (store_mkek(ret_mkek == PICOKEY_OK ? mkek : NULL) != PICOKEY_OK) {
release_mkek(mkek);
return SW_EXEC_ERROR();
}
@@ -143,31 +144,31 @@ int cmd_initialize() {
if (dkeks) {
if (*dkeks > 0) {
uint16_t d = *dkeks;
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) {
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
else {
int r = save_dkek_key(0, random_bytes_get(32));
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
uint16_t d = 0x0101;
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) {
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
}
else {
uint16_t d = 0x0000;
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) {
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
if (kds) {
uint8_t t[MAX_KEY_DOMAINS * 2], k = MIN(*kds, MAX_KEY_DOMAINS);
memset(t, 0xff, 2 * k);
if (file_put_data(tf_kd, t, 2 * k) != CCID_OK) {
if (file_put_data(tf_kd, t, 2 * k) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
@@ -179,59 +180,55 @@ int cmd_initialize() {
return SW_EXEC_ERROR();
}
int ret = 0;
if (ret_mkek != CCID_OK || !file_has_data(fdkey)) {
if (ret_mkek != PICOKEY_OK || !file_has_data(fdkey)) {
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256R1;
uint8_t index = 0, key_id = 0;
ret = mbedtls_ecdsa_genkey(&ecdsa, ec_id, random_gen, &index);
uint8_t key_id = 0;
if (otp_key_2) {
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecdsa, otp_key_2, 32);
}
else {
ret = mbedtls_ecdsa_genkey(&ecdsa, ec_id, random_gen, NULL);
}
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id);
if (ret != CCID_OK) {
if (ret != PICOKEY_OK) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
size_t cvc_len = 0;
if ((cvc_len = asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, NULL, 0)) == 0) {
uint16_t ee_len = 0, term_len = 0;
if ((ee_len = asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, NULL, 0)) == 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
file_t *fpk = search_file(EF_EE_DEV);
ret = file_put_data(fpk, res_APDU, (uint16_t)cvc_len);
ret = file_put_data(fpk, res_APDU, ee_len);
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
if ((cvc_len = asn1_cvc_cert(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, NULL, 0, true)) == 0) {
if ((term_len = asn1_cvc_cert(&ecdsa, PICO_KEYS_KEY_EC, res_APDU + ee_len, 4096 - ee_len, NULL, 0, true)) == 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
memcpy(res_APDU + cvc_len, res_APDU, cvc_len);
mbedtls_ecdsa_free(&ecdsa);
fpk = search_file(EF_TERMCA);
ret = file_put_data(fpk, res_APDU, (uint16_t)(2 * cvc_len));
ret = file_put_data(fpk, res_APDU, ee_len + term_len);
if (ret != 0) {
return SW_EXEC_ERROR();
}
const uint8_t *keyid =
(const uint8_t *) "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0",
const uint8_t *keyid = (const uint8_t *) "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0",
*label = (const uint8_t *) "ESPICOHSMTR";
uint16_t prkd_len = asn1_build_prkd_ecc(label,
(uint16_t)strlen((const char *) label),
keyid,
20,
256,
res_APDU,
4096);
uint16_t prkd_len = asn1_build_prkd_ecc(label, (uint16_t)strlen((const char *) label), keyid, 20, 256, res_APDU, 4096);
fpk = search_file(EF_PRKD_DEV);
ret = file_put_data(fpk, res_APDU, prkd_len);
}
if (ret != 0) {
return SW_EXEC_ERROR();

View File

@@ -72,8 +72,8 @@ int cmd_key_domain() {
import_dkek_share(p2, apdu.data);
if (++current_dkeks >= dkeks) {
int r = save_dkek_key(p2, NULL);
if (r != CCID_OK) {
if (r == CCID_NO_LOGIN) {
if (r != PICOKEY_OK) {
if (r == PICOKEY_NO_LOGIN) {
pending_save_dkek = p2;
}
else {
@@ -86,7 +86,7 @@ int cmd_key_domain() {
uint8_t t[MAX_KEY_DOMAINS * 2];
memcpy(t, kdata, tf_kd_size);
t[2 * p2 + 1] = current_dkeks;
if (file_put_data(tf_kd, t, tf_kd_size) != CCID_OK) {
if (file_put_data(tf_kd, t, tf_kd_size) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
@@ -129,17 +129,17 @@ int cmd_key_domain() {
else if (p1 == 0x4) {
t[2 * p2 + 1] = current_dkeks = 0;
}
if (file_put_data(tf_kd, t, tf_kd_size) != CCID_OK) {
if (file_put_data(tf_kd, t, tf_kd_size) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
file_t *tf = NULL;
if ((tf = search_file(EF_DKEK + p2))) {
if (delete_file(tf) != CCID_OK) {
if (delete_file(tf) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
if (p1 == 0x3 && (tf = search_file(EF_XKEK + p2))) {
if (delete_file(tf) != CCID_OK) {
if (delete_file(tf) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}

View File

@@ -56,10 +56,10 @@ int cmd_key_gen() {
aes_type = PICO_KEYS_KEY_AES_512;
}
r = store_keys(aes_key, aes_type, key_id);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_MEMORY_FAILURE();
}
if (find_and_store_meta_key(key_id) != CCID_OK) {
if (find_and_store_meta_key(key_id) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();

View File

@@ -51,8 +51,8 @@ int cmd_key_unwrap() {
mbedtls_rsa_init(&ctx);
do {
r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len);
} while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != CCID_OK) {
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEY_OK) {
mbedtls_rsa_free(&ctx);
return SW_EXEC_ERROR();
}
@@ -62,7 +62,7 @@ int cmd_key_unwrap() {
return SW_EXEC_ERROR();
}
mbedtls_rsa_free(&ctx);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
@@ -71,8 +71,8 @@ int cmd_key_unwrap() {
mbedtls_ecp_keypair_init(&ctx);
do {
r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len);
} while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != CCID_OK) {
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
@@ -82,7 +82,7 @@ int cmd_key_unwrap() {
return SW_EXEC_ERROR();
}
mbedtls_ecp_keypair_free(&ctx);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
@@ -97,8 +97,8 @@ int cmd_key_unwrap() {
&key_size,
&allowed,
&allowed_len);
} while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != CCID_OK) {
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
if (key_size == 64) {
@@ -117,7 +117,7 @@ int cmd_key_unwrap() {
return SW_EXEC_ERROR();
}
r = store_keys(aes_key, aes_type, key_id);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
@@ -136,7 +136,7 @@ int cmd_key_unwrap() {
}
r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_len);
free(meta);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
}

View File

@@ -60,9 +60,9 @@ int cmd_key_wrap() {
mbedtls_rsa_context ctx;
mbedtls_rsa_init(&ctx);
r = load_private_key_rsa(&ctx, ef);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_rsa_free(&ctx);
if (r == CCID_VERIFICATION_FAILED) {
if (r == PICOKEY_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -74,9 +74,9 @@ int cmd_key_wrap() {
mbedtls_ecp_keypair ctx;
mbedtls_ecp_keypair_init(&ctx);
r = load_private_key_ec(&ctx, ef);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ctx);
if (r == CCID_VERIFICATION_FAILED) {
if (r == PICOKEY_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -110,7 +110,7 @@ int cmd_key_wrap() {
r = dkek_encode_key(kdom, kdata_aes, aes_type, res_APDU, &wrap_len, meta_tag, tag_len);
mbedtls_platform_zeroize(kdata_aes, sizeof(kdata_aes));
}
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
res_APDU_size = wrap_len;

View File

@@ -63,7 +63,7 @@ int cmd_keypair_gen() {
return SW_EXEC_ERROR();
}
ret = store_keys(&rsa, PICO_KEYS_KEY_RSA, key_id);
if (ret != CCID_OK) {
if (ret != PICOKEY_OK) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
@@ -144,7 +144,7 @@ int cmd_keypair_gen() {
}
ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id);
mbedtls_ecdsa_free(&ecdsa);
if (ret != CCID_OK) {
if (ret != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
@@ -154,7 +154,7 @@ int cmd_keypair_gen() {
else {
return SW_WRONG_DATA();
}
if (find_and_store_meta_key(key_id) != CCID_OK) {
if (find_and_store_meta_key(key_id) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id);

View File

@@ -51,7 +51,7 @@ int cmd_mse() {
}
else {
if (p2 == 0xB6) {
if (puk_store_select_chr(tag_data) == CCID_OK) {
if (puk_store_select_chr(tag_data) == PICOKEY_OK) {
return SW_OK();
}
}

View File

@@ -40,11 +40,11 @@ int cmd_pso() {
apdu.nc += tlv_len;
}
int r = cvc_verify(apdu.data, (uint16_t)apdu.nc, current_puk->cvcert, current_puk->cvcert_len);
if (r != CCID_OK) {
if (r == CCID_WRONG_DATA) {
if (r != PICOKEY_OK) {
if (r == PICOKEY_WRONG_DATA) {
return SW_DATA_INVALID();
}
else if (r == CCID_WRONG_SIGNATURE) {
else if (r == PICOKEY_WRONG_SIGNATURE) {
return SW_CONDITIONS_NOT_SATISFIED();
}
return SW_EXEC_ERROR();
@@ -56,7 +56,7 @@ int cmd_pso() {
ca_ef = file_new(fid);
file_put_data(ca_ef, apdu.data, (uint16_t)apdu.nc);
if (add_cert_puk_store(file_get_data(ca_ef), file_get_size(ca_ef),
false) != CCID_OK) {
false) != PICOKEY_OK) {
return SW_FILE_FULL();
}

View File

@@ -59,19 +59,19 @@ int cmd_reset_retry() {
dhash[0] = newpin_len;
double_hash_pin(apdu.data + (apdu.nc - newpin_len), newpin_len, dhash + 1);
file_put_data(file_pin1, dhash, sizeof(dhash));
if (pin_reset_retries(file_pin1, true) != CCID_OK) {
if (pin_reset_retries(file_pin1, true) != PICOKEY_OK) {
return SW_MEMORY_FAILURE();
}
uint8_t mkek[MKEK_SIZE];
int r = load_mkek(mkek); //loads the MKEK with SO pin
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
hash_multi(apdu.data + (apdu.nc - newpin_len), newpin_len, session_pin);
has_session_pin = true;
r = store_mkek(mkek);
release_mkek(mkek);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
@@ -99,7 +99,7 @@ int cmd_reset_retry() {
return SW_WRONG_LENGTH();
}
}
if (pin_reset_retries(file_pin1, true) != CCID_OK) {
if (pin_reset_retries(file_pin1, true) != PICOKEY_OK) {
return SW_MEMORY_FAILURE();
}
return SW_OK();

View File

@@ -83,17 +83,17 @@ int pkcs1_strip_digest_info_prefix(mbedtls_md_type_t *algorithm,
*algorithm = digest_info_prefix[i].algorithm;
}
if (out_dat == NULL) {
return CCID_OK;
return PICOKEY_OK;
}
if (*out_len < hash_len) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
memmove(out_dat, in_dat + hdr_len, hash_len);
*out_len = hash_len;
return CCID_OK;
return PICOKEY_OK;
}
}
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
//-----
@@ -143,9 +143,9 @@ int cmd_signature() {
mbedtls_rsa_init(&ctx);
int r = load_private_key_rsa(&ctx, fkey);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_rsa_free(&ctx);
if (r == CCID_VERIFICATION_FAILED) {
if (r == PICOKEY_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -154,7 +154,7 @@ int cmd_signature() {
if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached
uint16_t nc = (uint16_t)apdu.nc;
if (pkcs1_strip_digest_info_prefix(&md, apdu.data, (uint16_t)apdu.nc, apdu.data,
&nc) != CCID_OK) { //gets the MD algo id and strips it off
&nc) != PICOKEY_OK) { //gets the MD algo id and strips it off
return SW_EXEC_ERROR();
}
apdu.nc = nc;
@@ -265,9 +265,9 @@ int cmd_signature() {
md = MBEDTLS_MD_SHA512;
}
int r = load_private_key_ec(&ctx, fkey);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ctx);
if (r == CCID_VERIFICATION_FAILED) {
if (r == PICOKEY_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();

View File

@@ -78,7 +78,7 @@ int cmd_update_ef() {
}
if (offset == 0) {
int r = file_put_data(ef, data, data_len);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_MEMORY_FAILURE();
}
}
@@ -92,7 +92,7 @@ int cmd_update_ef() {
memcpy(data_merge + offset, data, data_len);
int r = file_put_data(ef, data_merge, offset + data_len);
free(data_merge);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_MEMORY_FAILURE();
}
}

View File

@@ -333,7 +333,7 @@ uint16_t asn1_cvc_aut(void *rsa_ecdsa,
}
mbedtls_ecp_keypair ectx;
mbedtls_ecp_keypair_init(&ectx);
if (load_private_key_ec(&ectx, fkey) != CCID_OK) {
if (load_private_key_ec(&ectx, fkey) != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ectx);
return 0;
}
@@ -702,12 +702,12 @@ int puk_verify(const uint8_t *sig,
uint16_t puk_len = 0;
const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len);
if (!puk) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
uint16_t oid_len = 0;
const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6);
if (!oid) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA
uint16_t t81_len = 0, t82_len = 0;
@@ -716,7 +716,7 @@ int puk_verify(const uint8_t *sig,
&t81_len,
0x82);
if (!t81 || !t82) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa);
@@ -744,32 +744,32 @@ int puk_verify(const uint8_t *sig,
}
if (md == MBEDTLS_MD_NONE) {
mbedtls_rsa_free(&rsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
int r = mbedtls_mpi_read_binary(&rsa.N, t81, t81_len);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
r = mbedtls_mpi_read_binary(&rsa.E, t82, t82_len);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
r = mbedtls_rsa_complete(&rsa);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
r = mbedtls_rsa_check_pubkey(&rsa);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
r = mbedtls_rsa_pkcs1_verify(&rsa, md, (unsigned int)hash_len, hash, sig);
mbedtls_rsa_free(&rsa);
if (r != 0) {
return CCID_WRONG_SIGNATURE;
return PICOKEY_WRONG_SIGNATURE;
}
}
else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC
@@ -790,34 +790,34 @@ int puk_verify(const uint8_t *sig,
md = MBEDTLS_MD_SHA512;
}
if (md == MBEDTLS_MD_NONE) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
uint16_t t86_len = 0;
const uint8_t *t86 = cvc_get_field(puk, puk_len, &t86_len, 0x86);
if (!t86) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
mbedtls_ecp_group_id ec_id = cvc_inherite_ec_group(ca, ca_len);
if (ec_id == MBEDTLS_ECP_DP_NONE) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
int ret = mbedtls_ecp_group_load(&ecdsa.grp, ec_id);
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
ret = mbedtls_ecp_point_read_binary(&ecdsa.grp, &ecdsa.Q, t86, t86_len);
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
ret = mbedtls_ecp_check_pubkey(&ecdsa.grp, &ecdsa.Q);
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
@@ -827,44 +827,44 @@ int puk_verify(const uint8_t *sig,
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
ret = mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
if (ret != 0) {
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
ret = mbedtls_ecdsa_verify(&ecdsa.grp, hash, hash_len, &ecdsa.Q, &r, &s);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa);
if (ret != 0) {
return CCID_WRONG_SIGNATURE;
return PICOKEY_WRONG_SIGNATURE;
}
}
return CCID_OK;
return PICOKEY_OK;
}
int cvc_verify(const uint8_t *cert, uint16_t cert_len, const uint8_t *ca, uint16_t ca_len) {
uint16_t puk_len = 0;
const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len);
if (!puk) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
uint16_t oid_len = 0, cv_body_len = 0, sig_len = 0;
const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6);
const uint8_t *cv_body = cvc_get_body(cert, cert_len, &cv_body_len);
const uint8_t *sig = cvc_get_sig(cert, cert_len, &sig_len);
if (!sig) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (!cv_body) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (!oid) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
mbedtls_md_type_t md = MBEDTLS_MD_NONE;
if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA
@@ -905,18 +905,18 @@ int cvc_verify(const uint8_t *cert, uint16_t cert_len, const uint8_t *ca, uint16
}
}
if (md == MBEDTLS_MD_NONE) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md);
uint8_t hash[64], hash_len = mbedtls_md_get_size(md_info);
uint8_t tlv_body = 2 + format_tlv_len(cv_body_len, NULL);
int r = mbedtls_md(md_info, cv_body - tlv_body, cv_body_len + tlv_body, hash);
if (r != 0) {
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
r = puk_verify(sig, sig_len, hash, hash_len, ca, ca_len);
if (r != 0) {
return CCID_WRONG_SIGNATURE;
return PICOKEY_WRONG_SIGNATURE;
}
return CCID_OK;
return PICOKEY_OK;
}

View File

@@ -29,6 +29,7 @@
#include "mbedtls/ecdsa.h"
#include "mbedtls/chachapoly.h"
#include "files.h"
#include "otp.h"
extern bool has_session_pin, has_session_sopin;
extern uint8_t session_pin[32], session_sopin[32];
@@ -51,7 +52,7 @@ uint32_t crc32c(const uint8_t *buf, size_t len) {
int load_mkek(uint8_t *mkek) {
if (has_session_pin == false && has_session_sopin == false) {
return CCID_NO_LOGIN;
return PICOKEY_NO_LOGIN;
}
const uint8_t *pin = NULL;
if (pin == NULL && has_session_pin == true) {
@@ -69,23 +70,23 @@ int load_mkek(uint8_t *mkek) {
}
}
if (pin == NULL) { //Should never happen
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
if (has_mkek_mask) {
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mkek_mask[i];
}
}
int ret =
aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
int ret = aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
if (ret != 0) {
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
if (crc32c(MKEK_KEY(mkek), MKEK_KEY_SIZE) != *(uint32_t *) MKEK_CHECKSUM(mkek)) {
return CCID_WRONG_DKEK;
return PICOKEY_WRONG_DKEK;
}
return CCID_OK;
if (has_mkek_mask || otp_key_1) {
const uint8_t *mask = otp_key_1 ? otp_key_1 : mkek_mask;
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mask[i];
}
}
return PICOKEY_OK;
}
mse_t mse = { .init = false };
@@ -94,14 +95,7 @@ int mse_decrypt_ct(uint8_t *data, size_t len) {
mbedtls_chachapoly_context chatx;
mbedtls_chachapoly_init(&chatx);
mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12);
int ret = mbedtls_chachapoly_auth_decrypt(&chatx,
len - 16,
mse.key_enc,
mse.Qpt,
65,
data + len - 16,
data,
data);
int ret = mbedtls_chachapoly_auth_decrypt(&chatx, len - 16, mse.key_enc, mse.Qpt, 65, data + len - 16, data, data);
mbedtls_chachapoly_free(&chatx);
return ret;
}
@@ -109,7 +103,7 @@ int mse_decrypt_ct(uint8_t *data, size_t len) {
int load_dkek(uint8_t id, uint8_t *dkek) {
file_t *tf = search_file(EF_DKEK + id);
if (!file_has_data(tf)) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE);
return mkek_decrypt(dkek, DKEK_KEY_SIZE);
@@ -121,7 +115,7 @@ void release_mkek(uint8_t *mkek) {
int store_mkek(const uint8_t *mkek) {
if (has_session_pin == false && has_session_sopin == false) {
return CCID_NO_LOGIN;
return PICOKEY_NO_LOGIN;
}
uint8_t tmp_mkek[MKEK_SIZE];
if (mkek == NULL) {
@@ -139,12 +133,9 @@ int store_mkek(const uint8_t *mkek) {
if (!tf) {
release_mkek(tmp_mkek);
release_mkek(tmp_mkek_pin);
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
aes_encrypt_cfb_256(session_pin,
MKEK_IV(tmp_mkek_pin),
MKEK_KEY(tmp_mkek_pin),
MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
aes_encrypt_cfb_256(session_pin, MKEK_IV(tmp_mkek_pin), MKEK_KEY(tmp_mkek_pin), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
file_put_data(tf, tmp_mkek_pin, MKEK_SIZE);
release_mkek(tmp_mkek_pin);
}
@@ -155,32 +146,29 @@ int store_mkek(const uint8_t *mkek) {
if (!tf) {
release_mkek(tmp_mkek);
release_mkek(tmp_mkek_sopin);
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
aes_encrypt_cfb_256(session_sopin,
MKEK_IV(tmp_mkek_sopin),
MKEK_KEY(tmp_mkek_sopin),
MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
aes_encrypt_cfb_256(session_sopin, MKEK_IV(tmp_mkek_sopin), MKEK_KEY(tmp_mkek_sopin), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
file_put_data(tf, tmp_mkek_sopin, MKEK_SIZE);
release_mkek(tmp_mkek_sopin);
}
low_flash_available();
release_mkek(tmp_mkek);
return CCID_OK;
return PICOKEY_OK;
}
int store_dkek_key(uint8_t id, uint8_t *dkek) {
file_t *tf = search_file(EF_DKEK + id);
if (!tf) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
int r = mkek_encrypt(dkek, DKEK_KEY_SIZE);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
file_put_data(tf, dkek, DKEK_KEY_SIZE);
low_flash_available();
return CCID_OK;
return PICOKEY_OK;
}
int save_dkek_key(uint8_t id, const uint8_t *key) {
@@ -188,7 +176,7 @@ int save_dkek_key(uint8_t id, const uint8_t *key) {
if (!key) {
file_t *tf = search_file(EF_DKEK + id);
if (!tf) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE);
}
@@ -202,7 +190,7 @@ int import_dkek_share(uint8_t id, const uint8_t *share) {
uint8_t tmp_dkek[DKEK_KEY_SIZE];
file_t *tf = search_file(EF_DKEK + id);
if (!tf) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
memset(tmp_dkek, 0, sizeof(tmp_dkek));
if (file_get_size(tf) == DKEK_KEY_SIZE) {
@@ -213,7 +201,7 @@ int import_dkek_share(uint8_t id, const uint8_t *share) {
}
file_put_data(tf, tmp_dkek, DKEK_KEY_SIZE);
low_flash_available();
return CCID_OK;
return PICOKEY_OK;
}
int dkek_kcv(uint8_t id, uint8_t *kcv) { //kcv 8 bytes
@@ -221,45 +209,45 @@ int dkek_kcv(uint8_t id, uint8_t *kcv) { //kcv 8 bytes
memset(kcv, 0, 8);
memset(hsh, 0, sizeof(hsh));
int r = load_dkek(id, dkek);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
hash256(dkek, DKEK_KEY_SIZE, hsh);
mbedtls_platform_zeroize(dkek, sizeof(dkek));
memcpy(kcv, hsh, 8);
return CCID_OK;
return PICOKEY_OK;
}
int dkek_kenc(uint8_t id, uint8_t *kenc) { //kenc 32 bytes
uint8_t dkek[DKEK_KEY_SIZE + 4];
memset(kenc, 0, 32);
int r = load_dkek(id, dkek);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
memcpy(dkek + DKEK_KEY_SIZE, "\x0\x0\x0\x1", 4);
hash256(dkek, sizeof(dkek), kenc);
mbedtls_platform_zeroize(dkek, sizeof(dkek));
return CCID_OK;
return PICOKEY_OK;
}
int dkek_kmac(uint8_t id, uint8_t *kmac) { //kmac 32 bytes
uint8_t dkek[DKEK_KEY_SIZE + 4];
memset(kmac, 0, 32);
int r = load_dkek(id, dkek);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
memcpy(dkek + DKEK_KEY_SIZE, "\x0\x0\x0\x2", 4);
hash256(dkek, DKEK_KEY_SIZE + 4, kmac);
mbedtls_platform_zeroize(dkek, sizeof(dkek));
return CCID_OK;
return PICOKEY_OK;
}
int mkek_encrypt(uint8_t *data, uint16_t len) {
int r;
uint8_t mkek[MKEK_SIZE + 4];
if ((r = load_mkek(mkek)) != CCID_OK) {
if ((r = load_mkek(mkek)) != PICOKEY_OK) {
return r;
}
r = aes_encrypt_cfb_256(MKEK_KEY(mkek), MKEK_IV(mkek), data, len);
@@ -270,7 +258,7 @@ int mkek_encrypt(uint8_t *data, uint16_t len) {
int mkek_decrypt(uint8_t *data, uint16_t len) {
int r;
uint8_t mkek[MKEK_SIZE + 4];
if ((r = load_mkek(mkek)) != CCID_OK) {
if ((r = load_mkek(mkek)) != PICOKEY_OK) {
return r;
}
r = aes_decrypt_cfb_256(MKEK_KEY(mkek), MKEK_IV(mkek), data, len);
@@ -278,15 +266,9 @@ int mkek_decrypt(uint8_t *data, uint16_t len) {
return r;
}
int dkek_encode_key(uint8_t id,
void *key_ctx,
int key_type,
uint8_t *out,
uint16_t *out_len,
const uint8_t *allowed,
uint16_t allowed_len) {
int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint16_t *out_len, const uint8_t *allowed, uint16_t allowed_len) {
if (!(key_type & PICO_KEYS_KEY_RSA) && !(key_type & PICO_KEYS_KEY_EC) && !(key_type & PICO_KEYS_KEY_AES)) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
uint8_t kb[8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13]; //worst case: RSA-4096 (plus, 13 bytes padding)
@@ -298,21 +280,21 @@ int dkek_encode_key(uint8_t id,
uint8_t kenc[32];
memset(kenc, 0, sizeof(kenc));
r = dkek_kenc(id, kenc);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
uint8_t kcv[8];
memset(kcv, 0, sizeof(kcv));
r = dkek_kcv(id, kcv);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
uint8_t kmac[32];
memset(kmac, 0, sizeof(kmac));
r = dkek_kmac(id, kmac);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
@@ -331,10 +313,10 @@ int dkek_encode_key(uint8_t id,
}
if (kb_len != 16 && kb_len != 24 && kb_len != 32 && kb_len != 64) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (*out_len < 8 + 1 + 10 + 6 + (2 + 64 + 14) + 16) { // 14 bytes padding
return CCID_WRONG_LENGTH;
return PICOKEY_WRONG_LENGTH;
}
put_uint16_t(kb_len, kb + 8);
@@ -346,7 +328,7 @@ int dkek_encode_key(uint8_t id,
}
else if (key_type & PICO_KEYS_KEY_RSA) {
if (*out_len < 8 + 1 + 12 + 6 + (8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13) + 16) { //13 bytes pading
return CCID_WRONG_LENGTH;
return PICOKEY_WRONG_LENGTH;
}
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
kb_len = 0;
@@ -367,7 +349,7 @@ int dkek_encode_key(uint8_t id,
}
else if (key_type & PICO_KEYS_KEY_EC) {
if (*out_len < 8 + 1 + 12 + 6 + (8 + 2 * 8 + 9 * 66 + 2 + 4) + 16) { //4 bytes pading
return CCID_WRONG_LENGTH;
return PICOKEY_WRONG_LENGTH;
}
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
kb_len = 0;
@@ -386,12 +368,7 @@ int dkek_encode_key(uint8_t id,
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N);
size_t olen = 0;
mbedtls_ecp_point_write_binary(&ecdsa->grp,
&ecdsa->grp.G,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&olen,
kb + 8 + kb_len + 2,
sizeof(kb) - 8 - kb_len - 2);
mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2);
put_uint16_t((uint16_t)olen, kb + 8 + kb_len);
kb_len += 2 + (uint16_t)olen;
@@ -399,12 +376,7 @@ int dkek_encode_key(uint8_t id,
mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->d);
mbedtls_ecp_point_write_binary(&ecdsa->grp,
&ecdsa->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&olen,
kb + 8 + kb_len + 2,
sizeof(kb) - 8 - kb_len - 2);
mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2);
put_uint16_t((uint16_t)olen, kb + 8 + kb_len);
kb_len += 2 + (uint16_t)olen;
@@ -458,25 +430,20 @@ int dkek_encode_key(uint8_t id,
kb[kb_len] = 0x80;
}
r = aes_encrypt(kenc, NULL, 256, PICO_KEYS_AES_MODE_CBC, kb, kb_len_pad);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
memcpy(out + *out_len, kb, kb_len_pad);
*out_len += kb_len_pad;
r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB),
kmac,
256,
out,
*out_len,
out + *out_len);
r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, out, *out_len, out + *out_len);
*out_len += 16;
if (r != 0) {
return r;
}
return CCID_OK;
return PICOKEY_OK;
}
int dkek_type_key(const uint8_t *in) {
@@ -492,70 +459,59 @@ int dkek_type_key(const uint8_t *in) {
return 0x0;
}
int dkek_decode_key(uint8_t id,
void *key_ctx,
const uint8_t *in,
uint16_t in_len,
int *key_size_out,
uint8_t **allowed,
uint16_t *allowed_len) {
int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_len, int *key_size_out, uint8_t **allowed, uint16_t *allowed_len) {
uint8_t kcv[8];
int r = 0;
memset(kcv, 0, sizeof(kcv));
r = dkek_kcv(id, kcv);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
uint8_t kmac[32];
memset(kmac, 0, sizeof(kmac));
r = dkek_kmac(id, kmac);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
uint8_t kenc[32];
memset(kenc, 0, sizeof(kenc));
r = dkek_kenc(id, kenc);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
if (memcmp(kcv, in, 8) != 0) {
return CCID_WRONG_DKEK;
return PICOKEY_WRONG_DKEK;
}
uint8_t signature[16];
r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB),
kmac,
256,
in,
in_len - 16,
signature);
r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, in, in_len - 16, signature);
if (r != 0) {
return CCID_WRONG_SIGNATURE;
return PICOKEY_WRONG_SIGNATURE;
}
if (memcmp(signature, in + in_len - 16, 16) != 0) {
return CCID_WRONG_SIGNATURE;
return PICOKEY_WRONG_SIGNATURE;
}
int key_type = in[8];
if (key_type != 5 && key_type != 6 && key_type != 12 && key_type != 15) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if ((key_type == 5 || key_type == 6) &&
memcmp(in + 9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02", 12) != 0) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (key_type == 12 &&
memcmp(in + 9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03", 12) != 0) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (key_type == 15 && memcmp(in + 9, "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01", 10) != 0) {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
uint16_t ofs = 9;
@@ -579,13 +535,13 @@ int dkek_decode_key(uint8_t id,
ofs += len + 2;
if ((in_len - 16 - ofs) % 16 != 0) {
return CCID_WRONG_PADDING;
return PICOKEY_WRONG_PADDING;
}
uint8_t kb[8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13]; //worst case: RSA-4096 (plus, 13 bytes padding)
memset(kb, 0, sizeof(kb));
memcpy(kb, in + ofs, in_len - 16 - ofs);
r = aes_decrypt(kenc, NULL, 256, PICO_KEYS_AES_MODE_CBC, kb, in_len - 16 - ofs);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
@@ -602,14 +558,14 @@ int dkek_decode_key(uint8_t id,
r = mbedtls_mpi_read_binary(&rsa->D, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
len = get_uint16_t(kb, ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->N, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
}
else if (key_type == 6) {
@@ -623,7 +579,7 @@ int dkek_decode_key(uint8_t id,
r = mbedtls_mpi_read_binary(&rsa->P, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
//PQ
@@ -633,7 +589,7 @@ int dkek_decode_key(uint8_t id,
r = mbedtls_mpi_read_binary(&rsa->Q, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
//N
len = get_uint16_t(kb, ofs); ofs += len + 2;
@@ -643,33 +599,33 @@ int dkek_decode_key(uint8_t id,
r = mbedtls_mpi_read_binary(&rsa->E, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (key_type == 5) {
r = mbedtls_rsa_import(rsa, &rsa->N, NULL, NULL, &rsa->D, &rsa->E);
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
}
else if (key_type == 6) {
r = mbedtls_rsa_import(rsa, NULL, &rsa->P, &rsa->Q, NULL, &rsa->E);
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
}
r = mbedtls_rsa_complete(rsa);
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
r = mbedtls_rsa_check_privkey(rsa);
if (r != 0) {
mbedtls_rsa_free(rsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
}
else if (key_type == 12) {
@@ -687,7 +643,7 @@ int dkek_decode_key(uint8_t id,
mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(kb + ofs, len);
if (ec_id == MBEDTLS_ECP_DP_NONE) {
mbedtls_ecdsa_free(ecdsa);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
ofs += len;
@@ -709,7 +665,7 @@ int dkek_decode_key(uint8_t id,
r = mbedtls_ecp_read_key(ec_id, ecdsa, kb + ofs, len);
if (r != 0) {
mbedtls_ecdsa_free(ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
ofs += len;
@@ -725,17 +681,17 @@ int dkek_decode_key(uint8_t id,
}
if (r != 0) {
mbedtls_ecdsa_free(ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
}
r = mbedtls_ecp_check_pub_priv(ecdsa, ecdsa, random_gen, NULL);
if (r != 0) {
mbedtls_ecdsa_free(ecdsa);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
}
else if (key_type == 15) {
memcpy(key_ctx, kb + ofs, key_size);
}
return CCID_OK;
return PICOKEY_OK;
}

View File

@@ -43,6 +43,8 @@ bool has_session_pin = false, has_session_sopin = false;
const uint8_t *dev_name = NULL;
uint16_t dev_name_len = 0;
uint8_t PICO_PRODUCT = 1;
static int sc_hsm_process_apdu();
static void init_sc_hsm();
@@ -85,7 +87,7 @@ int sc_hsm_select_aid(app_t *a, uint8_t force) {
a->process_apdu = sc_hsm_process_apdu;
a->unload = sc_hsm_unload;
init_sc_hsm();
return CCID_OK;
return PICOKEY_OK;
}
INITIALIZER( sc_hsm_ctor ) {
@@ -178,10 +180,10 @@ uint8_t puk_status[MAX_PUK];
int add_cert_puk_store(const uint8_t *data, uint16_t data_len, bool copy) {
if (data == NULL || data_len == 0) {
return CCID_ERR_NULL_PARAM;
return PICOKEY_ERR_NULL_PARAM;
}
if (puk_store_entries == MAX_PUK_STORE_ENTRIES) {
return CCID_ERR_MEMORY_FATAL;
return PICOKEY_ERR_MEMORY_FATAL;
}
puk_store[puk_store_entries].copied = copy;
@@ -205,17 +207,17 @@ int add_cert_puk_store(const uint8_t *data, uint16_t data_len, bool copy) {
&puk_store[puk_store_entries].puk_len);
puk_store_entries++;
return CCID_OK;
return PICOKEY_OK;
}
int puk_store_select_chr(const uint8_t *chr) {
for (int i = 0; i < puk_store_entries; i++) {
if (memcmp(puk_store[i].chr, chr, puk_store[i].chr_len) == 0) {
current_puk = &puk_store[i];
return CCID_OK;
return PICOKEY_OK;
}
}
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
void reset_puk_store() {
@@ -261,7 +263,7 @@ int sc_hsm_unload() {
has_session_pin = has_session_sopin = false;
isUserAuthenticated = false;
sm_session_pin_len = 0;
return CCID_OK;
return PICOKEY_OK;
}
uint16_t get_device_options() {
@@ -334,16 +336,16 @@ int parse_ef_dir(const file_t *f, int mode) {
int pin_reset_retries(const file_t *pin, bool force) {
if (!pin) {
return CCID_ERR_NULL_PARAM;
return PICOKEY_ERR_NULL_PARAM;
}
const file_t *max = search_file(pin->fid + 1);
const file_t *act = search_file(pin->fid + 2);
if (!max || !act) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
uint8_t retries = file_read_uint8(act);
if (retries == 0 && force == false) { // blocked
return CCID_ERR_BLOCKED;
return PICOKEY_ERR_BLOCKED;
}
retries = file_read_uint8(max);
int r = file_put_data((file_t *) act, &retries, sizeof(retries));
@@ -353,26 +355,26 @@ int pin_reset_retries(const file_t *pin, bool force) {
int pin_wrong_retry(const file_t *pin) {
if (!pin) {
return CCID_ERR_NULL_PARAM;
return PICOKEY_ERR_NULL_PARAM;
}
const file_t *act = search_file(pin->fid + 2);
if (!act) {
return CCID_ERR_FILE_NOT_FOUND;
return PICOKEY_ERR_FILE_NOT_FOUND;
}
uint8_t retries = file_read_uint8(act);
if (retries > 0) {
retries -= 1;
int r = file_put_data((file_t *) act, &retries, sizeof(retries));
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
low_flash_available();
if (retries == 0) {
return CCID_ERR_BLOCKED;
return PICOKEY_ERR_BLOCKED;
}
return retries;
}
return CCID_ERR_BLOCKED;
return PICOKEY_ERR_BLOCKED;
}
bool pka_enabled() {
@@ -391,7 +393,7 @@ uint16_t check_pin(const file_t *pin, const uint8_t *data, uint16_t len) {
if (is_secured_apdu() && sm_session_pin_len > 0 && pin == file_pin1) {
if (len == sm_session_pin_len && memcmp(data, sm_session_pin, len) != 0) {
int retries;
if ((retries = pin_wrong_retry(pin)) < CCID_OK) {
if ((retries = pin_wrong_retry(pin)) < PICOKEY_OK) {
return SW_PIN_BLOCKED();
}
return set_res_sw(0x63, 0xc0 | (uint8_t)retries);
@@ -405,17 +407,17 @@ uint16_t check_pin(const file_t *pin, const uint8_t *data, uint16_t len) {
}
if (memcmp(file_get_data(pin) + 1, dhash, sizeof(dhash)) != 0) {
int retries;
if ((retries = pin_wrong_retry(pin)) < CCID_OK) {
if ((retries = pin_wrong_retry(pin)) < PICOKEY_OK) {
return SW_PIN_BLOCKED();
}
return set_res_sw(0x63, 0xc0 | (uint8_t)retries);
}
}
int r = pin_reset_retries(pin, false);
if (r == CCID_ERR_BLOCKED) {
if (r == PICOKEY_ERR_BLOCKED) {
return SW_PIN_BLOCKED();
}
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_MEMORY_FAILURE();
}
if (pka_enabled() == false) {
@@ -552,18 +554,18 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) {
memcpy(kdata, key_ctx, key_size);
}
else {
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
if (!fpk) {
return CCID_ERR_MEMORY_FATAL;
return PICOKEY_ERR_MEMORY_FATAL;
}
r = mkek_encrypt(kdata, key_size);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
r = file_put_data(fpk, kdata, (uint16_t)key_size);
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return r;
}
char key_id_str[4] = {0};
@@ -580,7 +582,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) {
}
}
low_flash_available();
return CCID_OK;
return PICOKEY_OK;
}
int find_and_store_meta_key(uint8_t key_id) {
@@ -614,73 +616,73 @@ int find_and_store_meta_key(uint8_t key_id) {
int r = meta_add((KEY_PREFIX << 8) | key_id, meta, (uint16_t)meta_size);
free(meta);
if (r != 0) {
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
}
return CCID_OK;
return PICOKEY_OK;
}
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
if (wait_button_pressed() == true) { // timeout
return CCID_VERIFICATION_FAILED;
return PICOKEY_VERIFICATION_FAILED;
}
uint16_t key_size = file_get_size(fkey);
uint8_t kdata[4096 / 8];
memcpy(kdata, file_get_data(fkey), key_size);
if (mkek_decrypt(kdata, key_size) != 0) {
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size / 2) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (mbedtls_mpi_read_binary(&ctx->Q, kdata + key_size / 2, key_size / 2) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (mbedtls_mpi_lset(&ctx->E, 0x10001) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
if (mbedtls_rsa_import(ctx, NULL, &ctx->P, &ctx->Q, NULL, &ctx->E) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (mbedtls_rsa_complete(ctx) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
if (mbedtls_rsa_check_privkey(ctx) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
return PICOKEY_WRONG_DATA;
}
return CCID_OK;
return PICOKEY_OK;
}
int load_private_key_ec(mbedtls_ecp_keypair *ctx, file_t *fkey) {
if (wait_button_pressed() == true) { // timeout
return CCID_VERIFICATION_FAILED;
return PICOKEY_VERIFICATION_FAILED;
}
uint16_t key_size = file_get_size(fkey);
uint8_t kdata[67]; // Worst case, 521 bit + 1byte
memcpy(kdata, file_get_data(fkey), key_size);
if (mkek_decrypt(kdata, key_size) != 0) {
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
mbedtls_ecp_group_id gid = kdata[0];
int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1);
if (r != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_ecp_keypair_free(ctx);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (gid == MBEDTLS_ECP_DP_ED25519 || gid == MBEDTLS_ECP_DP_ED448) {
@@ -691,9 +693,9 @@ int load_private_key_ec(mbedtls_ecp_keypair *ctx, file_t *fkey) {
}
if (r != 0) {
mbedtls_ecp_keypair_free(ctx);
return CCID_EXEC_ERROR;
return PICOKEY_EXEC_ERROR;
}
return CCID_OK;
return PICOKEY_OK;
}
int load_private_key_ecdh(mbedtls_ecp_keypair *ctx, file_t *fkey) {
return load_private_key_ec(ctx, fkey);
@@ -762,7 +764,7 @@ static const cmd_t cmds[] = {
int sc_hsm_process_apdu() {
int r = sm_unwrap();
if (r != CCID_OK) {
if (r != PICOKEY_OK) {
return SW_DATA_INVALID();
}
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {

View File

@@ -18,7 +18,7 @@
#ifndef __VERSION_H_
#define __VERSION_H_
#define HSM_VERSION 0x0402
#define HSM_VERSION 0x0500
#define HSM_VERSION_MAJOR ((HSM_VERSION >> 8) & 0xff)
#define HSM_VERSION_MINOR (HSM_VERSION & 0xff)