Upgrade PicoKeys SDK.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2026-05-01 12:54:04 +02:00
parent 251b35dd9c
commit 38a7d147b6
32 changed files with 555 additions and 803 deletions
+4 -4
View File
@@ -45,9 +45,9 @@ else()
endif()
set(USB_ITF_CCID 1)
set(USB_ITF_WCID 1)
include(pico-keys-sdk/pico_keys_sdk_import.cmake)
include(pico-keys-sdk/picokeys_sdk_import.cmake)
if(NOT ESP_PLATFORM)
set(SOURCES ${PICO_KEYS_SOURCES})
set(SOURCES ${PICOKEYS_SOURCES})
endif()
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/hsm/sc_hsm.c
@@ -100,7 +100,7 @@ if(NOT ESP_PLATFORM)
)
target_compile_options(pico_hsm PRIVATE ${COMMON_COMPILE_OPTIONS})
pico_keys_apply_strict_flags(
picokeys_apply_strict_flags(
SOURCES ${SOURCES}
FILTER_REGEX "/src/hsm/|/pico-keys-sdk/src/|/pico-keys-sdk/config/"
)
@@ -136,7 +136,7 @@ if(NOT ESP_PLATFORM)
-Wl,--gc-sections
)
endif(APPLE)
set(PICO_HSM_EMU_LIBS pico_keys_sdk pthread m)
set(PICO_HSM_EMU_LIBS picokeys_sdk pthread m)
if(NOT SKIP_MBEDTLS_FOR_OPENSSL_EMULATION)
list(APPEND PICO_HSM_EMU_LIBS mbedtls)
endif()
+37 -84
View File
@@ -27,78 +27,58 @@ const uint8_t *sym_seed = (const uint8_t *) "Symmetric key seed";
mbedtls_ecp_keypair hd_context = { 0 };
uint8_t hd_keytype = 0;
static int node_derive_bip_child(const mbedtls_ecp_keypair *parent,
const uint8_t cpar[32],
const uint8_t *i,
mbedtls_ecp_keypair *child,
uint8_t cchild[32]) {
static int node_derive_bip_child(const mbedtls_ecp_keypair *parent, const uint8_t cpar[32], const uint8_t *i, mbedtls_ecp_keypair *child, uint8_t cchild[32]) {
uint8_t data[1 + 32 + 4], I[64], *iL = I, *iR = I + 32;
mbedtls_mpi il, kchild;
mbedtls_mpi_init(&il);
mbedtls_mpi_init(&kchild);
if (i[0] >= 0x80) {
if (mbedtls_mpi_cmp_int(&parent->d, 0) == 0) {
return PICOKEY_ERR_NULL_PARAM;
return PICOKEYS_ERR_NULL_PARAM;
}
data[0] = 0x00;
mbedtls_mpi_write_binary(&parent->d, data + 1, 32);
}
else {
size_t olen = 0;
mbedtls_ecp_point_write_binary(&parent->grp,
&parent->Q,
MBEDTLS_ECP_PF_COMPRESSED,
&olen,
data,
33);
mbedtls_ecp_point_write_binary(&parent->grp, &parent->Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, data, 33);
}
do {
memcpy(data + 33, i, 4);
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512),
cpar,
32,
data,
sizeof(data),
I);
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), cpar, 32, data, sizeof(data), I);
mbedtls_mpi_read_binary(&il, iL, 32);
mbedtls_mpi_add_mpi(&kchild, &il, &parent->d);
mbedtls_mpi_mod_mpi(&kchild, &kchild, &parent->grp.N);
data[0] = 0x01;
memcpy(data + 1, iR, 32);
} while (mbedtls_mpi_cmp_mpi(&il,
&parent->grp.N) != -1 || mbedtls_mpi_cmp_int(&kchild, 0) == 0);
} while (mbedtls_mpi_cmp_mpi(&il, &parent->grp.N) != -1 || mbedtls_mpi_cmp_int(&kchild, 0) == 0);
mbedtls_mpi_copy(&child->d, &kchild);
mbedtls_ecp_mul(&child->grp, &child->Q, &child->d, &child->grp.G, random_gen, NULL);
mbedtls_ecp_mul(&child->grp, &child->Q, &child->d, &child->grp.G, random_fill_iterator, NULL);
memcpy(cchild, iR, 32);
mbedtls_mpi_free(&il);
mbedtls_mpi_free(&kchild);
return PICOKEY_OK;
return PICOKEYS_OK;
}
static 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 PICOKEY_OK;
return PICOKEYS_OK;
}
static 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 PICOKEY_OK;
return PICOKEYS_OK;
}
static int node_fingerprint_bip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) {
size_t olen = 0;
uint8_t buffer[33];
mbedtls_ecp_point_write_binary(&ctx->grp,
&ctx->Q,
MBEDTLS_ECP_PF_COMPRESSED,
&olen,
buffer,
sizeof(buffer));
mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, buffer, sizeof(buffer));
sha256_ripemd160(buffer, sizeof(buffer), buffer);
memcpy(fingerprint, buffer, 4);
return PICOKEY_OK;
return PICOKEYS_OK;
}
static int node_fingerprint_slip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) {
@@ -106,22 +86,21 @@ static 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 PICOKEY_OK;
return PICOKEYS_OK;
}
static int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32],
uint8_t key_type[1]) {
static int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32], uint8_t key_type[1]) {
uint8_t mkey[65];
mbedtls_ecp_keypair_init(ctx);
file_t *ef = search_file(EF_MASTER_SEED | mid);
file_t *ef = file_search(EF_MASTER_SEED | mid);
if (!file_has_data(ef)) {
return PICOKEY_ERR_FILE_NOT_FOUND;
return PICOKEYS_ERR_FILE_NOT_FOUND;
}
memcpy(mkey, file_get_data(ef), sizeof(mkey));
int r = mkek_decrypt(mkey + 1,
sizeof(mkey) - 1);
if (r != PICOKEY_OK) {
return PICOKEY_EXEC_ERROR;
if (r != PICOKEYS_OK) {
return PICOKEYS_EXEC_ERROR;
}
if (mkey[0] == 0x1 || mkey[0] == 0x2) {
if (mkey[0] == 0x1) {
@@ -131,29 +110,22 @@ static int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain
mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1);
}
else {
return PICOKEY_WRONG_DATA;
return PICOKEYS_WRONG_DATA;
}
mbedtls_mpi_read_binary(&ctx->d, mkey + 1, 32);
memcpy(chain, mkey + 33, 32);
mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL);
mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_fill_iterator, NULL);
}
else if (mkey[0] == 0x3) {
mbedtls_mpi_read_binary(&ctx->d, mkey + 33, 32);
memcpy(chain, mkey + 1, 32);
}
key_type[0] = mkey[0];
return PICOKEY_OK;
return PICOKEYS_OK;
}
static int node_derive_path(const uint8_t *path,
uint16_t path_len,
mbedtls_ecp_keypair *ctx,
uint8_t chain[32],
uint8_t fingerprint[4],
uint8_t *nodes,
uint8_t last_node[4],
uint8_t key_type[1]) {
static int node_derive_path(const uint8_t *path, uint16_t path_len, mbedtls_ecp_keypair *ctx, uint8_t chain[32], uint8_t fingerprint[4], uint8_t *nodes, uint8_t last_node[4], uint8_t key_type[1]) {
uint8_t *tag_data = NULL, *p = NULL;
uint16_t tag_len = 0, tag = 0x0;
uint8_t node = 0, N[64] = { 0 };
@@ -166,16 +138,16 @@ static 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 PICOKEY_WRONG_DATA;
return PICOKEYS_WRONG_DATA;
}
if (node == 0) {
if ((r = load_master_bip(tag_data[0], ctx, chain, key_type)) != PICOKEY_OK) {
if ((r = load_master_bip(tag_data[0], ctx, chain, key_type)) != PICOKEYS_OK) {
return r;
}
}
else if (node > 0) {
node_fingerprint_bip(ctx, fingerprint);
if ((r = node_derive_bip_child(ctx, chain, tag_data, ctx, chain)) != PICOKEY_OK) {
if ((r = node_derive_bip_child(ctx, chain, tag_data, ctx, chain)) != PICOKEYS_OK) {
return r;
}
memcpy(last_node, tag_data, 4);
@@ -183,17 +155,12 @@ static int node_derive_path(const uint8_t *path,
}
else if (tag == 0x04) {
if (node == 0) {
return PICOKEY_WRONG_DATA;
return PICOKEYS_WRONG_DATA;
}
else if (node > 0) {
node_fingerprint_slip(ctx, fingerprint);
*(tag_data - 1) = 0;
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512),
chain,
32,
tag_data - 1,
tag_len + 1,
N);
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), chain, 32, tag_data - 1, tag_len + 1, N);
memcpy(chain, N, 32);
mbedtls_mpi_read_binary(&ctx->d, N + 32, 32);
}
@@ -202,7 +169,7 @@ static int node_derive_path(const uint8_t *path,
if (nodes) {
*nodes = node;
}
return PICOKEY_OK;
return PICOKEYS_OK;
}
int cmd_bip_slip(void) {
@@ -230,7 +197,7 @@ int cmd_bip_slip(void) {
}
if (apdu.nc == 0) {
seed_len = 64;
random_gen(NULL, seed, seed_len);
random_fill_buffer(seed, seed_len);
}
else {
seed_len = MIN((uint8_t)apdu.nc, 64);
@@ -238,8 +205,7 @@ int cmd_bip_slip(void) {
}
if (p1 == 0x1 || p1 == 0x2) {
do {
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), key_seed,
strlen((char *) key_seed), seed, seed_len, seed);
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), key_seed, strlen((char *) key_seed), seed, seed_len, seed);
mbedtls_mpi_read_binary(&il, seed, 32);
seed_len = 64;
} while (mbedtls_mpi_cmp_int(&il, 0) == 0 || mbedtls_mpi_cmp_mpi(&il, &grp.N) != -1);
@@ -247,20 +213,19 @@ int cmd_bip_slip(void) {
mbedtls_mpi_free(&il);
}
else if (p1 == 0x3) {
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), key_seed,
strlen((char *) key_seed), seed, seed_len, seed);
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), key_seed, strlen((char *) key_seed), seed, seed_len, seed);
}
mkey[0] = p1;
file_t *ef = file_new(EF_MASTER_SEED | p2);
int r = mkek_encrypt(mkey + 1, sizeof(mkey) - 1);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
r = file_put_data(ef, mkey, sizeof(mkey));
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
flash_commit();
}
else if (p1 == 0xA) {
if (apdu.nc == 0) {
@@ -271,7 +236,7 @@ int cmd_bip_slip(void) {
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 != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
@@ -287,12 +252,7 @@ int cmd_bip_slip(void) {
if (key_type == 0x1 || key_type == 0x2) {
memcpy(res_APDU + res_APDU_size, chain, 32);
res_APDU_size += 32;
mbedtls_ecp_point_write_binary(&ctx.grp,
&ctx.Q,
MBEDTLS_ECP_PF_COMPRESSED,
&olen,
pubkey,
sizeof(pubkey));
mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, pubkey, sizeof(pubkey));
memcpy(res_APDU + res_APDU_size, pubkey, olen);
res_APDU_size += (uint16_t)olen;
}
@@ -309,15 +269,8 @@ int cmd_bip_slip(void) {
}
else if (p1 == 0x10) {
uint8_t chain[32] = { 0 }, fgpt[4] = { 0 }, last_node[4] = { 0 }, nodes = 0;
int r = node_derive_path(apdu.data,
(uint16_t)apdu.nc,
&hd_context,
chain,
fgpt,
&nodes,
last_node,
&hd_keytype);
if (r != PICOKEY_OK) {
int r = node_derive_path(apdu.data, (uint16_t)apdu.nc, &hd_context, chain, fgpt, &nodes, last_node, &hd_keytype);
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&hd_context);
return SW_EXEC_ERROR();
}
+4 -3
View File
@@ -18,6 +18,7 @@
#include "crypto_utils.h"
#include "sc_hsm.h"
#include "kek.h"
#include "files.h"
int cmd_change_pin(void) {
if (P1(apdu) == 0x0) {
@@ -42,7 +43,7 @@ int cmd_change_pin(void) {
}
uint8_t mkek[MKEK_SIZE];
r = load_mkek(mkek); //loads the MKEK with old pin
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
//encrypt MKEK with new pin
@@ -57,7 +58,7 @@ int cmd_change_pin(void) {
}
r = store_mkek(mkek);
release_mkek(mkek);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
uint8_t dhash[34];
@@ -65,7 +66,7 @@ int cmd_change_pin(void) {
dhash[1] = 1; // Format
pin_derive_verifier(apdu.data + pin_len, (uint16_t)(apdu.nc - pin_len), dhash + 2);
file_put_data(file_pin, dhash, sizeof(dhash));
low_flash_available();
flash_commit();
return SW_OK();
}
}
+14 -101
View File
@@ -151,7 +151,7 @@ static int mbedtls_ansi_x963_kdf(mbedtls_md_type_t md_type,
mbedtls_md_update(&md_ctx, input, input_len);
//TODO: be careful with architecture little vs. big
put_uint32_t_be(counter, counter_buf);
put_uint32_be(counter, counter_buf);
mbedtls_md_update(&md_ctx, counter_buf, 4);
@@ -174,7 +174,7 @@ int cmd_cipher_sym(void) {
if (wait_button_pressed() == true) { // timeout
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
file_t *ef = search_file((KEY_PREFIX << 8) | key_id);
file_t *ef = file_search((KEY_PREFIX << 8) | key_id);
if (hd_keytype == 0) {
if (!ef) {
return SW_FILE_NOT_FOUND();
@@ -204,12 +204,7 @@ int cmd_cipher_sym(void) {
mbedtls_aes_free(&aes);
return SW_EXEC_ERROR();
}
r = mbedtls_aes_crypt_cbc(&aes,
MBEDTLS_AES_ENCRYPT,
apdu.nc,
tmp_iv,
apdu.data,
res_APDU);
r = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, apdu.nc, tmp_iv, apdu.data, res_APDU);
mbedtls_aes_free(&aes);
if (r != 0) {
return SW_EXEC_ERROR();
@@ -221,12 +216,7 @@ int cmd_cipher_sym(void) {
mbedtls_aes_free(&aes);
return SW_EXEC_ERROR();
}
r = mbedtls_aes_crypt_cbc(&aes,
MBEDTLS_AES_DECRYPT,
apdu.nc,
tmp_iv,
apdu.data,
res_APDU);
r = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, apdu.nc, tmp_iv, apdu.data, res_APDU);
mbedtls_aes_free(&aes);
if (r != 0) {
return SW_EXEC_ERROR();
@@ -257,15 +247,7 @@ int cmd_cipher_sym(void) {
res_APDU_size = 16;
}
else if (algo == ALGO_AES_DERIVE) {
int r = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
NULL,
0,
kdata,
key_size,
apdu.data,
apdu.nc,
res_APDU,
apdu.nc);
int r = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0,kdata, key_size, apdu.data, apdu.nc, res_APDU, apdu.nc);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) {
return SW_EXEC_ERROR();
@@ -294,24 +276,10 @@ int cmd_cipher_sym(void) {
mbedtls_chachapoly_init(&ctx);
mbedtls_chachapoly_setkey(&ctx, kdata);
if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
r = mbedtls_chachapoly_encrypt_and_tag(&ctx,
enc.len,
asn1_len(&iv) > 0 ? iv.data : tmp_iv,
aad.data,
aad.len,
enc.data,
res_APDU,
res_APDU + enc.len);
r = mbedtls_chachapoly_encrypt_and_tag(&ctx, enc.len, asn1_len(&iv) > 0 ? iv.data : tmp_iv, aad.data, aad.len, enc.data, res_APDU, res_APDU + enc.len);
}
else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_chachapoly_auth_decrypt(&ctx,
enc.len - 16,
asn1_len(&iv) > 0 ? iv.data : tmp_iv,
aad.data,
aad.len,
enc.data + enc.len - 16,
enc.data,
res_APDU);
r = mbedtls_chachapoly_auth_decrypt(&ctx,enc.len - 16, asn1_len(&iv) > 0 ? iv.data : tmp_iv, aad.data, aad.len, enc.data + enc.len - 16, enc.data, res_APDU);
}
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_chachapoly_free(&ctx);
@@ -369,16 +337,7 @@ int cmd_cipher_sym(void) {
else if (memcmp(oid.data, OID_HKDF_SHA512, oid.len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
}
int r = mbedtls_hkdf(md_info,
iv.data,
iv.len,
kdata,
key_size,
enc.data,
enc.len,
res_APDU,
apdu.ne > 0 &&
apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info));
int r = mbedtls_hkdf(md_info, iv.data, iv.len, kdata, key_size, enc.data, enc.len, res_APDU, apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info));
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) {
return SW_EXEC_ERROR();
@@ -399,15 +358,7 @@ int cmd_cipher_sym(void) {
return SW_WRONG_DATA();
}
r = mbedtls_pkcs5_pbkdf2_hmac_ext(md_type,
kdata,
key_size,
salt.p,
salt.len,
iterations,
keylen ? keylen : (apdu.ne > 0 &&
apdu.ne < 65536 ? apdu.ne : 32),
res_APDU);
r = mbedtls_pkcs5_pbkdf2_hmac_ext(md_type, kdata, key_size, salt.p, salt.len, iterations, keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32), res_APDU);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) {
return SW_EXEC_ERROR();
@@ -442,13 +393,7 @@ int cmd_cipher_sym(void) {
else if (memcmp(enc.data, OID_HMAC_SHA512, enc.len) == 0) {
md_type = MBEDTLS_MD_SHA512;
}
int r = mbedtls_ansi_x963_kdf(md_type,
key_size,
kdata,
aad.len,
aad.data,
apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32,
res_APDU);
int r = mbedtls_ansi_x963_kdf(md_type, key_size, kdata, aad.len, aad.data, apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32, res_APDU);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) {
return SW_WRONG_DATA();
@@ -550,16 +495,7 @@ int cmd_cipher_sym(void) {
res_APDU_size = enc.len + 16;
}
else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_gcm_auth_decrypt(&gctx,
enc.len - 16,
iv.data,
iv.len,
aad.data,
aad.len,
enc.data + enc.len - 16,
16,
enc.data,
res_APDU);
r = mbedtls_gcm_auth_decrypt(&gctx, enc.len - 16, iv.data, iv.len, aad.data, aad.len, enc.data + enc.len - 16, 16, enc.data, res_APDU);
res_APDU_size = enc.len - 16;
}
mbedtls_gcm_free(&gctx);
@@ -592,29 +528,11 @@ int cmd_cipher_sym(void) {
}
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
r = mbedtls_ccm_encrypt_and_tag(&gctx,
enc.len,
iv.data,
iv.len,
aad.data,
aad.len,
enc.data,
res_APDU,
res_APDU + enc.len,
16);
r = mbedtls_ccm_encrypt_and_tag(&gctx, enc.len, iv.data, iv.len, aad.data,aad.len, enc.data, res_APDU, res_APDU + enc.len, 16);
res_APDU_size = enc.len + 16;
}
else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_ccm_auth_decrypt(&gctx,
enc.len - 16,
iv.data,
iv.len,
aad.data,
aad.len,
enc.data,
res_APDU,
enc.data + enc.len - 16,
16);
r = mbedtls_ccm_auth_decrypt(&gctx, enc.len - 16, iv.data, iv.len, aad.data, aad.len, enc.data, res_APDU, enc.data + enc.len - 16, 16);
res_APDU_size = enc.len - 16;
}
mbedtls_ccm_free(&gctx);
@@ -668,12 +586,7 @@ int cmd_cipher_sym(void) {
}
key_size = 32;
mbedtls_mpi_write_binary(&hd_context.d, kdata, key_size);
r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512),
kdata,
key_size,
aad.data,
aad.len,
secret);
r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), kdata, key_size,aad.data, aad.len, secret);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) {
return SW_EXEC_ERROR();
+10 -16
View File
@@ -31,7 +31,7 @@ int cmd_decrypt_asym(void) {
if (!isUserAuthenticated) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
file_t *ef = search_file((KEY_PREFIX << 8) | key_id);
file_t *ef = file_search((KEY_PREFIX << 8) | key_id);
if (!ef) {
return SW_FILE_NOT_FOUND();
}
@@ -48,9 +48,9 @@ int cmd_decrypt_asym(void) {
mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
}
int r = load_private_key_rsa(&ctx, ef);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
mbedtls_rsa_free(&ctx);
if (r == PICOKEY_VERIFICATION_FAILED) {
if (r == PICOKEYS_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -61,13 +61,13 @@ int cmd_decrypt_asym(void) {
}
if (p2 == ALGO_RSA_DECRYPT_PKCS1 || p2 == ALGO_RSA_DECRYPT_OEP) {
size_t olen = apdu.nc;
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.data, res_APDU, 512);
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_fill_iterator, NULL, &olen, apdu.data, res_APDU, 512);
if (r == 0) {
res_APDU_size = (uint16_t)olen;
}
}
else {
r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU);
r = mbedtls_rsa_private(&ctx, random_fill_iterator, NULL, apdu.data, res_APDU);
if (r == 0) {
res_APDU_size = key_size;
}
@@ -134,9 +134,7 @@ int cmd_decrypt_asym(void) {
// The SmartCard-HSM returns the point result of the DH operation
// with a leading '04'
res_APDU[0] = 0x04;
r =
mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU + 1, MBEDTLS_ECP_MAX_BYTES, random_gen,
NULL);
r = mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU + 1, MBEDTLS_ECP_MAX_BYTES, random_fill_iterator, NULL);
mbedtls_ecdh_free(&ctx);
if (r != 0) {
return SW_EXEC_ERROR();
@@ -158,10 +156,7 @@ int cmd_decrypt_asym(void) {
while (walk_tlv(&ctxi, &p, &tag, &ctxo.len, &ctxo.data)) {
if (tag == 0x73) {
asn1_ctx_t oid = {0};
if (asn1_find_tag(&ctxo, 0x6, &oid) == true &&
oid.len == strlen(OID_ID_KEY_DOMAIN_UID) &&
memcmp(oid.data, OID_ID_KEY_DOMAIN_UID,
strlen(OID_ID_KEY_DOMAIN_UID)) == 0) {
if (asn1_find_tag(&ctxo, 0x6, &oid) == true && oid.len == strlen(OID_ID_KEY_DOMAIN_UID) && memcmp(oid.data, OID_ID_KEY_DOMAIN_UID, strlen(OID_ID_KEY_DOMAIN_UID)) == 0) {
if (asn1_find_tag(&ctxo, 0x80, &kdom_uid) == false) {
return SW_WRONG_DATA();
}
@@ -173,12 +168,11 @@ int cmd_decrypt_asym(void) {
return SW_WRONG_DATA();
}
for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) {
file_t *tf = search_file(EF_XKEK + n);
file_t *tf = file_search(EF_XKEK + n);
if (tf) {
if (file_get_size(tf) == kdom_uid.len &&
memcmp(file_get_data(tf), kdom_uid.data, kdom_uid.len) == 0) {
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) != PICOKEY_OK) {
if (store_dkek_key(n, res_APDU + 1) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
mbedtls_platform_zeroize(res_APDU, 32);
+5 -5
View File
@@ -25,20 +25,20 @@ int cmd_delete_file(void) {
if (apdu.nc == 0) {
ef = currentEF;
if (!(ef = search_file(ef->fid))) {
if (!(ef = file_search(ef->fid))) {
return SW_FILE_NOT_FOUND();
}
}
else {
uint16_t fid = get_uint16_t_be(apdu.data);
if (!(ef = search_file(fid))) {
uint16_t fid = get_uint16_be(apdu.data);
if (!(ef = file_search(fid))) {
return SW_FILE_NOT_FOUND();
}
}
if (!authenticate_action(ef, ACL_OP_DELETE_SELF)) {
if (!file_authenticate_action(ef, ACL_OP_DELETE_SELF)) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
if (delete_file(ef) != PICOKEY_OK) {
if (file_delete(ef) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
return SW_OK();
+5 -5
View File
@@ -42,7 +42,7 @@ int cmd_derive_asym(void) {
if (!isUserAuthenticated) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
if (!(fkey = search_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) {
if (!(fkey = file_search((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) {
return SW_FILE_NOT_FOUND();
}
if (key_has_purpose(fkey, ALGO_EC_DERIVE) == false) {
@@ -57,9 +57,9 @@ int cmd_derive_asym(void) {
int r;
r = load_private_key_ec(&ctx, fkey);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&ctx);
if (r == PICOKEY_VERIFICATION_FAILED) {
if (r == PICOKEYS_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
@@ -87,8 +87,8 @@ int cmd_derive_asym(void) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
r = store_keys(&ctx, PICO_KEYS_KEY_EC, dest_id);
if (r != PICOKEY_OK) {
r = store_keys(&ctx, PICOKEYS_KEY_EC, dest_id);
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
+2 -8
View File
@@ -34,7 +34,7 @@ int cmd_external_authenticate(void) {
if (apdu.nc == 0) {
return SW_WRONG_LENGTH();
}
file_t *ef_puk = search_file(EF_PUKAUT);
file_t *ef_puk = file_search(EF_PUKAUT);
if (!file_has_data(ef_puk)) {
return SW_FILE_NOT_FOUND();
}
@@ -44,13 +44,7 @@ int cmd_external_authenticate(void) {
memcpy(input, dev_name, dev_name_len);
memcpy(input + dev_name_len, challenge, challenge_len);
hash256(input, dev_name_len + challenge_len, hash);
int r =
puk_verify(apdu.data,
(uint16_t)apdu.nc,
hash,
32,
file_get_data(ef_puk_aut),
file_get_size(ef_puk_aut));
int r = puk_verify(apdu.data, (uint16_t)apdu.nc, hash, 32, file_get_data(ef_puk_aut), file_get_size(ef_puk_aut));
free(input);
if (r != 0) {
return SW_CONDITIONS_NOT_SATISFIED();
+8 -8
View File
@@ -59,13 +59,13 @@ int cmd_extras(void) {
}
uint16_t opts = get_device_options();
if (apdu.nc == 0) {
res_APDU_size += put_uint16_t_be(opts, res_APDU);
res_APDU_size += put_uint16_be(opts, res_APDU);
}
else {
uint8_t newopts[] = { apdu.data[0], (opts & 0xff) };
file_t *tf = search_file(EF_DEVOPS);
file_t *tf = file_search(EF_DEVOPS);
file_put_data(tf, newopts, sizeof(newopts));
low_flash_available();
flash_commit();
}
}
else if (cmd == CMD_SECURE_LOCK) { // secure lock
@@ -76,7 +76,7 @@ int cmd_extras(void) {
mbedtls_ecdh_context hkey;
mbedtls_ecdh_init(&hkey);
mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1);
int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen, NULL);
int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_fill_iterator, NULL);
mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1);
ret = mbedtls_ecp_point_read_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Qp, apdu.data, apdu.nc);
if (ret != 0) {
@@ -87,7 +87,7 @@ int cmd_extras(void) {
uint8_t buf[MBEDTLS_ECP_MAX_BYTES];
size_t olen = 0;
ret = mbedtls_ecdh_calc_secret(&hkey, &olen, buf, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL);
ret = mbedtls_ecdh_calc_secret(&hkey, &olen, buf, MBEDTLS_ECP_MAX_BYTES, random_fill_iterator, NULL);
if (ret != 0) {
mbedtls_ecdh_free(&hkey);
mbedtls_platform_zeroize(buf, sizeof(buf));
@@ -123,7 +123,7 @@ int cmd_extras(void) {
(P2(apdu) == SECURE_LOCK_DISABLE && (opts & HSM_OPT_SECURE_LOCK))) {
uint16_t tfids[] = { EF_MKEK, EF_MKEK_SO };
for (size_t t = 0; t < sizeof(tfids) / sizeof(uint16_t); t++) {
file_t *tf = search_file(tfids[t]);
file_t *tf = file_search(tfids[t]);
if (tf) {
uint8_t *tmp = (uint8_t *) calloc(1, file_get_size(tf));
memcpy(tmp, file_get_data(tf), file_get_size(tf));
@@ -141,9 +141,9 @@ int cmd_extras(void) {
else if (P2(apdu) == SECURE_LOCK_DISABLE) {
newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8;
}
file_t *tf = search_file(EF_DEVOPS);
file_t *tf = file_search(EF_DEVOPS);
file_put_data(tf, newopts, sizeof(newopts));
low_flash_available();
flash_commit();
}
else if (P2(apdu) == SECURE_LOCK_MASK && (opts & HSM_OPT_SECURE_LOCK)) {
memcpy(mkek_mask, apdu.data, MKEK_KEY_SIZE);
+4 -9
View File
@@ -41,14 +41,14 @@ int cmd_general_authenticate(void) {
pubkey_len = tag_len + 1;
}
}
file_t *fkey = search_file(EF_KEY_DEV);
file_t *fkey = file_search(EF_KEY_DEV);
if (!fkey) {
return SW_EXEC_ERROR();
}
mbedtls_ecp_keypair ectx;
mbedtls_ecp_keypair_init(&ectx);
r = load_private_key_ecdh(&ectx, fkey);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&ectx);
return SW_EXEC_ERROR();
}
@@ -77,12 +77,7 @@ int cmd_general_authenticate(void) {
}
size_t olen = 0;
uint8_t derived[MBEDTLS_ECP_MAX_BYTES];
r = mbedtls_ecdh_calc_secret(&ctx,
&olen,
derived,
MBEDTLS_ECP_MAX_BYTES,
random_gen,
NULL);
r = mbedtls_ecdh_calc_secret(&ctx, &olen, derived, MBEDTLS_ECP_MAX_BYTES, random_fill_iterator, NULL);
mbedtls_ecdh_free(&ctx);
if (r != 0) {
return SW_EXEC_ERROR();
@@ -110,7 +105,7 @@ int cmd_general_authenticate(void) {
r = sm_sign(t, pubkey_len + 16, res_APDU + res_APDU_size);
free(t);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
res_APDU_size += 8;
+32 -28
View File
@@ -45,7 +45,7 @@ int cmd_initialize(void) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
int ret_mkek = load_mkek(mkek); //Try loading MKEK with previous session
initialize_flash(true);
file_initialize_flash(true);
scan_all();
has_session_pin = has_session_sopin = has_mkek_mask = false;
uint16_t tag = 0x0;
@@ -55,7 +55,7 @@ int cmd_initialize(void) {
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
if (tag == 0x80) { //options
file_t *tf = search_file(EF_DEVOPS);
file_t *tf = file_search(EF_DEVOPS);
file_put_data(tf, tag_data, tag_len);
}
else if (tag == 0x81) { //user pin
@@ -81,7 +81,7 @@ int cmd_initialize(void) {
}
}
else if (tag == 0x91) { //retries user pin
file_t *tf = search_file(EF_PIN1_MAX_RETRIES);
file_t *tf = file_search(EF_PIN1_MAX_RETRIES);
if (tf && tf->data) {
file_put_data(tf, tag_data, tag_len);
}
@@ -99,7 +99,7 @@ int cmd_initialize(void) {
file_put_data(tf, NULL, 0);
}
else if (tag == 0x93) {
file_t *ef_puk = search_file(EF_PUKAUT);
file_t *ef_puk = file_search(EF_PUKAUT);
if (!ef_puk) {
release_mkek(mkek);
return SW_MEMORY_FAILURE();
@@ -131,15 +131,15 @@ int cmd_initialize(void) {
*/
}
}
file_t *tf_kd = search_file(EF_KEY_DOMAIN);
file_t *tf_kd = file_search(EF_KEY_DOMAIN);
if (!tf_kd) {
release_mkek(mkek);
return SW_EXEC_ERROR();
}
if (ret_mkek != PICOKEY_OK) {
if (ret_mkek != PICOKEYS_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 == PICOKEY_OK ? mkek : NULL) != PICOKEY_OK) {
if (store_mkek(ret_mkek == PICOKEYS_OK ? mkek : NULL) != PICOKEYS_OK) {
release_mkek(mkek);
return SW_EXEC_ERROR();
}
@@ -147,43 +147,43 @@ int cmd_initialize(void) {
if (dkeks) {
if (*dkeks > 0) {
uint16_t d = *dkeks;
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEY_OK) {
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
else {
int r = save_dkek_key(0, random_bytes_get(32));
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
uint16_t d = 0x0101;
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEY_OK) {
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
}
else {
uint16_t d = 0x0000;
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEY_OK) {
if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != PICOKEYS_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) != PICOKEY_OK) {
if (file_put_data(tf_kd, t, 2 * k) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
/* When initialized, it has all credentials */
isUserAuthenticated = true;
/* Create terminal private key */
file_t *fdkey = search_file(EF_KEY_DEV);
file_t *fdkey = file_search(EF_KEY_DEV);
if (!fdkey) {
return SW_EXEC_ERROR();
}
int ret = 0;
if (ret_mkek != PICOKEY_OK || !file_has_data(fdkey)) {
if (ret_mkek != PICOKEYS_OK || !file_has_data(fdkey)) {
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256R1;
@@ -194,59 +194,63 @@ int cmd_initialize(void) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
ret = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL);
ret = mbedtls_ecp_keypair_calc_public(&ecdsa, random_fill_iterator, NULL);
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
}
else {
ret = mbedtls_ecdsa_genkey(&ecdsa, ec_id, random_gen, NULL);
ret = mbedtls_ecdsa_genkey(&ecdsa, ec_id, random_fill_iterator, NULL);
}
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id);
if (ret != PICOKEY_OK) {
ret = store_keys(&ecdsa, PICOKEYS_KEY_EC, key_id);
if (ret != PICOKEYS_OK) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
uint16_t ee_len = 0, term_len = 0;
if ((ee_len = asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
if ((ee_len = asn1_cvc_aut(&ecdsa, PICOKEYS_KEY_EC, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
file_t *fpk = search_file(EF_EE_DEV);
file_t *fpk = file_search(EF_EE_DEV);
ret = file_put_data(fpk, res_APDU, ee_len);
if (ret != 0) {
if (ret != PICOKEYS_OK) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
if ((term_len = asn1_cvc_cert(&ecdsa, PICO_KEYS_KEY_EC, res_APDU + ee_len, MAX_APDU_DATA - ee_len, NULL, 0, true)) == 0) {
if ((term_len = asn1_cvc_cert(&ecdsa, PICOKEYS_KEY_EC, res_APDU + ee_len, MAX_APDU_DATA - ee_len, NULL, 0, true)) == 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
mbedtls_ecdsa_free(&ecdsa);
fpk = search_file(EF_TERMCA);
fpk = file_search(EF_TERMCA);
ret = file_put_data(fpk, res_APDU, ee_len + term_len);
if (ret != 0) {
if (ret != PICOKEYS_OK) {
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",
*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, MAX_APDU_DATA);
fpk = search_file(EF_PRKD_DEV);
fpk = file_search(EF_PRKD_DEV);
ret = file_put_data(fpk, res_APDU, prkd_len);
}
if (ret != 0) {
if (ret != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
flash_commit();
reset_puk_store();
}
else { //free memory bytes request
int heap_left = heapLeft();
res_APDU_size += put_uint32_t_be(heap_left, res_APDU);
res_APDU_size += put_uint32_be(heap_left, res_APDU);
res_APDU[4] = 0;
res_APDU[5] = HSM_VERSION_MAJOR;
res_APDU[6] = HSM_VERSION_MINOR;
+16 -16
View File
@@ -44,7 +44,7 @@ int cmd_key_domain(void) {
if (p2 >= MAX_KEY_DOMAINS) {
return SW_WRONG_P1P2();
}
file_t *tf_kd = search_file(EF_KEY_DOMAIN);
file_t *tf_kd = file_search(EF_KEY_DOMAIN);
if (!tf_kd) {
return SW_EXEC_ERROR();
}
@@ -72,8 +72,8 @@ int cmd_key_domain(void) {
import_dkek_share(p2, apdu.data);
if (++current_dkeks >= dkeks) {
int r = save_dkek_key(p2, NULL);
if (r != PICOKEY_OK) {
if (r == PICOKEY_NO_LOGIN) {
if (r != PICOKEYS_OK) {
if (r == PICOKEYS_NO_LOGIN) {
pending_save_dkek = p2;
}
else {
@@ -86,13 +86,13 @@ int cmd_key_domain(void) {
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) != PICOKEY_OK) {
if (file_put_data(tf_kd, t, tf_kd_size) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
flash_commit();
}
else {
file_t *tf = search_file(EF_XKEK + p2);
file_t *tf = file_search(EF_XKEK + p2);
if (current_dkeks == 0xff && !file_has_data(tf)) { //XKEK have always 0xff
return SW_REFERENCE_NOT_FOUND();
}
@@ -104,7 +104,7 @@ int cmd_key_domain(void) {
}
if (p1 == 0x3) { //if key domain is not empty, command is denied
for (uint16_t i = 1; i < 256; i++) {
file_t *fkey = search_file(KEY_PREFIX << 8 | (uint8_t)i);
file_t *fkey = file_search(KEY_PREFIX << 8 | (uint8_t)i);
if (get_key_domain(fkey) == p2) {
return SW_FILE_EXISTS();
}
@@ -129,21 +129,21 @@ int cmd_key_domain(void) {
else if (p1 == 0x4) {
t[2 * p2 + 1] = current_dkeks = 0;
}
if (file_put_data(tf_kd, t, tf_kd_size) != PICOKEY_OK) {
if (file_put_data(tf_kd, t, tf_kd_size) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
file_t *tf = NULL;
if ((tf = search_file(EF_DKEK + p2))) {
if (delete_file(tf) != PICOKEY_OK) {
if ((tf = file_search(EF_DKEK + p2))) {
if (file_delete(tf) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
if (p1 == 0x3 && (tf = search_file(EF_XKEK + p2))) {
if (delete_file(tf) != PICOKEY_OK) {
if (p1 == 0x3 && (tf = file_search(EF_XKEK + p2))) {
if (file_delete(tf) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
low_flash_available();
flash_commit();
if (p1 == 0x3) {
return SW_REFERENCE_NOT_FOUND();
}
@@ -151,7 +151,7 @@ int cmd_key_domain(void) {
else if (p1 == 0x2) { //XKEK Key Domain creation
if (apdu.nc > 0) {
uint16_t pub_len = 0;
file_t *fterm = search_file(EF_TERMCA);
file_t *fterm = file_search(EF_TERMCA);
if (!fterm) {
return SW_EXEC_ERROR();
}
@@ -190,7 +190,7 @@ int cmd_key_domain(void) {
t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86);
if (t86) {
file_put_data(tf, t86 + 1, (uint16_t)t86_len - 1);
low_flash_available();
flash_commit();
}
}
}
@@ -203,7 +203,7 @@ int cmd_key_domain(void) {
res_APDU[1] = dkeks > current_dkeks ? dkeks - current_dkeks : 0;
dkek_kcv(p2, res_APDU + 2);
res_APDU_size = 2 + 8;
file_t *tf = search_file(EF_XKEK + p2);
file_t *tf = file_search(EF_XKEK + p2);
if (file_has_data(tf)) {
memcpy(res_APDU + 10, file_get_data(tf), file_get_size(tf));
res_APDU_size += file_get_size(tf);
+7 -7
View File
@@ -44,24 +44,24 @@ int cmd_key_gen(void) {
memcpy(aes_key, random_bytes_get(key_size), key_size);
int aes_type = 0x0;
if (key_size == 16) {
aes_type = PICO_KEYS_KEY_AES_128;
aes_type = PICOKEYS_KEY_AES_128;
}
else if (key_size == 24) {
aes_type = PICO_KEYS_KEY_AES_192;
aes_type = PICOKEYS_KEY_AES_192;
}
else if (key_size == 32) {
aes_type = PICO_KEYS_KEY_AES_256;
aes_type = PICOKEYS_KEY_AES_256;
}
else if (key_size == 64) {
aes_type = PICO_KEYS_KEY_AES_512;
aes_type = PICOKEYS_KEY_AES_512;
}
r = store_keys(aes_key, aes_type, key_id);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_MEMORY_FAILURE();
}
if (find_and_store_meta_key(key_id) != PICOKEY_OK) {
if (find_and_store_meta_key(key_id) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
low_flash_available();
flash_commit();
return SW_OK();
}
+24 -30
View File
@@ -32,7 +32,7 @@ int cmd_key_unwrap(void) {
uint8_t *data = apdu.data;
uint16_t data_len = apdu.nc;
if (data_len == 0) { // New style
file_t *tef = search_file(0x2F10);
file_t *tef = file_search(0x2F10);
if (!file_has_data(tef)) {
return SW_FILE_NOT_FOUND();
}
@@ -46,78 +46,72 @@ int cmd_key_unwrap(void) {
if (key_type == 0x0) {
return SW_DATA_INVALID();
}
if (key_type & PICO_KEYS_KEY_RSA) {
if (key_type & PICOKEYS_KEY_RSA) {
mbedtls_rsa_context ctx;
mbedtls_rsa_init(&ctx);
do {
r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len);
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEY_OK) {
} while ((r == PICOKEYS_ERR_FILE_NOT_FOUND || r == PICOKEYS_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEYS_OK) {
mbedtls_rsa_free(&ctx);
return SW_EXEC_ERROR();
}
r = store_keys(&ctx, PICO_KEYS_KEY_RSA, key_id);
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICO_KEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
r = store_keys(&ctx, PICOKEYS_KEY_RSA, key_id);
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICOKEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
mbedtls_rsa_free(&ctx);
return SW_EXEC_ERROR();
}
mbedtls_rsa_free(&ctx);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
else if (key_type & PICO_KEYS_KEY_EC) {
else if (key_type & PICOKEYS_KEY_EC) {
mbedtls_ecp_keypair ctx;
mbedtls_ecp_keypair_init(&ctx);
do {
r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len);
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEY_OK) {
} while ((r == PICOKEYS_ERR_FILE_NOT_FOUND || r == PICOKEYS_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
r = store_keys(&ctx, PICO_KEYS_KEY_EC, key_id);
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICO_KEYS_KEY_EC, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
r = store_keys(&ctx, PICOKEYS_KEY_EC, key_id);
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICOKEYS_KEY_EC, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR();
}
mbedtls_ecp_keypair_free(&ctx);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
else if (key_type & PICO_KEYS_KEY_AES) {
else if (key_type & PICOKEYS_KEY_AES) {
uint8_t aes_key[64];
int key_size = 0, aes_type = 0;
do {
r = dkek_decode_key((uint8_t)++kdom,
aes_key,
data,
data_len,
&key_size,
&allowed,
&allowed_len);
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEY_OK) {
r = dkek_decode_key((uint8_t)++kdom, aes_key, data, data_len, &key_size, &allowed, &allowed_len);
} while ((r == PICOKEYS_ERR_FILE_NOT_FOUND || r == PICOKEYS_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
if (key_size == 64) {
aes_type = PICO_KEYS_KEY_AES_512;
aes_type = PICOKEYS_KEY_AES_512;
}
else if (key_size == 32) {
aes_type = PICO_KEYS_KEY_AES_256;
aes_type = PICOKEYS_KEY_AES_256;
}
else if (key_size == 24) {
aes_type = PICO_KEYS_KEY_AES_192;
aes_type = PICOKEYS_KEY_AES_192;
}
else if (key_size == 16) {
aes_type = PICO_KEYS_KEY_AES_128;
aes_type = PICOKEYS_KEY_AES_128;
}
else {
return SW_EXEC_ERROR();
}
r = store_keys(aes_key, aes_type, key_id);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
@@ -136,7 +130,7 @@ int cmd_key_unwrap(void) {
}
r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_len);
free(meta);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return r;
}
}
@@ -148,6 +142,6 @@ int cmd_key_unwrap(void) {
}
res_APDU_size = 0;
}
low_flash_available();
flash_commit();
return SW_OK();
}
+15 -15
View File
@@ -30,7 +30,7 @@ int cmd_key_wrap(void) {
if (!isUserAuthenticated) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
file_t *ef = search_file((KEY_PREFIX << 8) | key_id);
file_t *ef = file_search((KEY_PREFIX << 8) | key_id);
if (!ef) {
return SW_FILE_NOT_FOUND();
}
@@ -38,7 +38,7 @@ int cmd_key_wrap(void) {
if (kdom == 0xff) {
return SW_REFERENCE_NOT_FOUND();
}
file_t *tf_kd = search_file(EF_KEY_DOMAIN);
file_t *tf_kd = file_search(EF_KEY_DOMAIN);
uint8_t *kdata = file_get_data(tf_kd), dkeks = kdata ? kdata[2 * kdom] : 0,
current_dkeks = kdata ? kdata[2 * kdom + 1] : 0;
if (dkeks != current_dkeks || dkeks == 0 || dkeks == 0xff) {
@@ -47,7 +47,7 @@ int cmd_key_wrap(void) {
if (key_has_purpose(ef, ALGO_WRAP) == false) {
return SW_CONDITIONS_NOT_SATISFIED();
}
file_t *prkd = search_file((PRKD_PREFIX << 8) | key_id);
file_t *prkd = file_search((PRKD_PREFIX << 8) | key_id);
if (!prkd) {
return SW_FILE_NOT_FOUND();
}
@@ -58,28 +58,28 @@ int cmd_key_wrap(void) {
mbedtls_rsa_context ctx;
mbedtls_rsa_init(&ctx);
r = load_private_key_rsa(&ctx, ef);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
mbedtls_rsa_free(&ctx);
if (r == PICOKEY_VERIFICATION_FAILED) {
if (r == PICOKEYS_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
}
r = dkek_encode_key(kdom, &ctx, PICO_KEYS_KEY_RSA, res_APDU, &wrap_len, meta_tag, tag_len);
r = dkek_encode_key(kdom, &ctx, PICOKEYS_KEY_RSA, res_APDU, &wrap_len, meta_tag, tag_len);
mbedtls_rsa_free(&ctx);
}
else if (*dprkd == P15_KEYTYPE_ECC) {
mbedtls_ecp_keypair ctx;
mbedtls_ecp_keypair_init(&ctx);
r = load_private_key_ec(&ctx, ef);
if (r != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
mbedtls_ecp_keypair_free(&ctx);
if (r == PICOKEY_VERIFICATION_FAILED) {
if (r == PICOKEYS_VERIFICATION_FAILED) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
return SW_EXEC_ERROR();
}
r = dkek_encode_key(kdom, &ctx, PICO_KEYS_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len);
r = dkek_encode_key(kdom, &ctx, PICOKEYS_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len);
mbedtls_ecp_keypair_free(&ctx);
}
else if (*dprkd == P15_KEYTYPE_AES) {
@@ -88,27 +88,27 @@ int cmd_key_wrap(void) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
uint16_t key_size = file_get_size(ef), aes_type = PICO_KEYS_KEY_AES;
uint16_t key_size = file_get_size(ef), aes_type = PICOKEYS_KEY_AES;
memcpy(kdata_aes, file_get_data(ef), key_size);
if (mkek_decrypt(kdata_aes, key_size) != 0) {
return SW_EXEC_ERROR();
}
if (key_size == 64) {
aes_type = PICO_KEYS_KEY_AES_512;
aes_type = PICOKEYS_KEY_AES_512;
}
else if (key_size == 32) {
aes_type = PICO_KEYS_KEY_AES_256;
aes_type = PICOKEYS_KEY_AES_256;
}
else if (key_size == 24) {
aes_type = PICO_KEYS_KEY_AES_192;
aes_type = PICOKEYS_KEY_AES_192;
}
else if (key_size == 16) {
aes_type = PICO_KEYS_KEY_AES_128;
aes_type = PICOKEYS_KEY_AES_128;
}
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 != PICOKEY_OK) {
if (r != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
res_APDU_size = wrap_len;
+12 -15
View File
@@ -49,17 +49,16 @@ int cmd_keypair_gen(void) {
}
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa);
uint8_t index = 0;
ret = mbedtls_rsa_gen_key(&rsa, random_gen, &index, key_size, exponent);
ret = mbedtls_rsa_gen_key(&rsa, random_fill_iterator, NULL, key_size, exponent);
if (ret != 0) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&rsa, PICOKEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
return SW_EXEC_ERROR();
}
ret = store_keys(&rsa, PICO_KEYS_KEY_RSA, key_id);
if (ret != PICOKEY_OK) {
ret = store_keys(&rsa, PICOKEYS_KEY_RSA, key_id);
if (ret != PICOKEYS_OK) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
@@ -90,8 +89,7 @@ int cmd_keypair_gen(void) {
}
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
uint8_t index = 0;
ret = mbedtls_ecdsa_genkey(&ecdsa, ec_id, random_gen, &index);
ret = mbedtls_ecdsa_genkey(&ecdsa, ec_id, random_fill_iterator, NULL);
if (ret != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
@@ -107,12 +105,11 @@ int cmd_keypair_gen(void) {
if (a92.data[0] > MAX_KEY_DOMAINS) {
return SW_WRONG_DATA();
}
file_t *tf_xkek = search_file(EF_XKEK + a92.data[0]);
file_t *tf_xkek = file_search(EF_XKEK + a92.data[0]);
if (!tf_xkek) {
return SW_WRONG_DATA();
}
ext.len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size(
tf_xkek);
ext.len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size(tf_xkek);
ext.data = (uint8_t *) calloc(1, ext.len);
uint8_t *pe = ext.data;
*pe++ = 0x73;
@@ -127,7 +124,7 @@ int cmd_keypair_gen(void) {
}
}
}
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, MAX_APDU_DATA, ext.data, ext.len)) == 0) {
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ecdsa, PICOKEYS_KEY_EC, res_APDU, MAX_APDU_DATA, ext.data, ext.len)) == 0) {
if (ext.data) {
free(ext.data);
}
@@ -137,9 +134,9 @@ int cmd_keypair_gen(void) {
if (ext.data) {
free(ext.data);
}
ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id);
ret = store_keys(&ecdsa, PICOKEYS_KEY_EC, key_id);
mbedtls_ecdsa_free(&ecdsa);
if (ret != PICOKEY_OK) {
if (ret != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
}
@@ -149,7 +146,7 @@ int cmd_keypair_gen(void) {
else {
return SW_WRONG_DATA();
}
if (find_and_store_meta_key(key_id) != PICOKEY_OK) {
if (find_and_store_meta_key(key_id) != PICOKEYS_OK) {
return SW_EXEC_ERROR();
}
file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id);
@@ -160,6 +157,6 @@ int cmd_keypair_gen(void) {
if (apdu.ne == 0) {
apdu.ne = res_APDU_size;
}
low_flash_available();
flash_commit();
return SW_OK();
}
+7 -4
View File
@@ -18,14 +18,17 @@
#include "sc_hsm.h"
#include "files.h"
extern uint16_t dynamic_files;
extern file_t dynamic_file[];
int cmd_list_keys(void) {
/* First we send DEV private key */
/* Both below conditions should be always TRUE */
if (search_file(EF_PRKD_DEV)) {
res_APDU_size += put_uint16_t_be(EF_PRKD_DEV, res_APDU + res_APDU_size);
if (file_search(EF_PRKD_DEV)) {
res_APDU_size += put_uint16_be(EF_PRKD_DEV, res_APDU + res_APDU_size);
}
if (search_file(EF_KEY_DEV)) {
res_APDU_size += put_uint16_t_be(EF_KEY_DEV, res_APDU + res_APDU_size);
if (file_search(EF_KEY_DEV)) {
res_APDU_size += put_uint16_be(EF_KEY_DEV, res_APDU + res_APDU_size);
}
//first CC
for (int i = 0; i < dynamic_files; i++) {
+2 -2
View File
@@ -51,13 +51,13 @@ int cmd_mse(void) {
}
else {
if (p2 == 0xB6) {
if (puk_store_select_chr(tag_data) == PICOKEY_OK) {
if (puk_store_select_chr(tag_data) == PICOKEYS_OK) {
return SW_OK();
}
}
else if (p2 == 0xA4) { /* Aut */
for (uint8_t i = 0; i < MAX_PUK; i++) {
file_t *ef = search_file(EF_PUK + i);
file_t *ef = file_search(EF_PUK + i);
if (!ef) {
break;
}
+8 -21
View File
@@ -39,23 +39,22 @@ int cmd_pso(void) {
apdu.nc += tlv_len;
}
int r = cvc_verify(apdu.data, (uint16_t)apdu.nc, current_puk->cvcert, current_puk->cvcert_len);
if (r != PICOKEY_OK) {
if (r == PICOKEY_WRONG_DATA) {
if (r != PICOKEYS_OK) {
if (r == PICOKEYS_WRONG_DATA) {
return SW_DATA_INVALID();
}
else if (r == PICOKEY_WRONG_SIGNATURE) {
else if (r == PICOKEYS_WRONG_SIGNATURE) {
return SW_CONDITIONS_NOT_SATISFIED();
}
return SW_EXEC_ERROR();
}
for (uint8_t i = 0; i < 0xfe; i++) {
uint16_t fid = (CA_CERTIFICATE_PREFIX << 8) | i;
file_t *ca_ef = search_file(fid);
file_t *ca_ef = file_search(fid);
if (!ca_ef) {
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) != PICOKEY_OK) {
if (add_cert_puk_store(file_get_data(ca_ef), file_get_size(ca_ef), false) != PICOKEYS_OK) {
return SW_FILE_FULL();
}
@@ -125,30 +124,18 @@ int cmd_pso(void) {
}
}
file_t *cd_ef = file_new((CD_PREFIX << 8) | i);
uint16_t cd_len = (uint16_t)asn1_build_cert_description(chr,
chr_len,
puk_bin,
puk_bin_len,
fid,
NULL,
0);
uint16_t cd_len = (uint16_t)asn1_build_cert_description(chr, chr_len, puk_bin, puk_bin_len, fid, NULL, 0);
if (cd_len == 0) {
return SW_EXEC_ERROR();
}
uint8_t *buf = (uint8_t *) calloc(cd_len, sizeof(uint8_t));
r = (int)asn1_build_cert_description(chr,
chr_len,
puk_bin,
puk_bin_len,
fid,
buf,
cd_len);
r = (int)asn1_build_cert_description(chr, chr_len, puk_bin, puk_bin_len, fid, buf, cd_len);
file_put_data(cd_ef, buf, cd_len);
free(buf);
if (r == 0) {
return SW_EXEC_ERROR();
}
low_flash_available();
flash_commit();
break;
}
}

Some files were not shown because too many files have changed in this diff Show More