Upgrade to v5.2

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2025-01-15 13:07:35 +01:00
commit 4c636e0ce5
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
24 changed files with 164 additions and 120 deletions

View file

@ -25,6 +25,7 @@ jobs:
run: | run: |
./workflows/autobuild.sh pico ./workflows/autobuild.sh pico
./build_pico_hsm.sh ./build_pico_hsm.sh
./workflows/autobuild.sh esp32
- name: Update nightly release - name: Update nightly release
uses: pyTooling/Actions/releaser@main uses: pyTooling/Actions/releaser@main
with: with:

View file

@ -80,7 +80,7 @@ set(USB_ITF_CCID 1)
set(USB_ITF_WCID 1) set(USB_ITF_WCID 1)
include(pico-keys-sdk/pico_keys_sdk_import.cmake) include(pico-keys-sdk/pico_keys_sdk_import.cmake)
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/hsm/version.h") SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/hsm/version.h" 1)
if(ESP_PLATFORM) if(ESP_PLATFORM)
project(pico_hsm) project(pico_hsm)
@ -125,5 +125,7 @@ if(NOT ESP_PLATFORM)
) )
endif(APPLE) endif(APPLE)
target_link_libraries(pico_hsm PRIVATE pthread m) target_link_libraries(pico_hsm PRIVATE pthread m)
else()
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
endif() endif()
endif() endif()

View file

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
VERSION_MAJOR="5" VERSION_MAJOR="5"
VERSION_MINOR="0-eddsa1" VERSION_MINOR="2-eddsa1"
SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}" SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}"
#if ! [[ -z "${GITHUB_SHA}" ]]; then #if ! [[ -z "${GITHUB_SHA}" ]]; then
# SUFFIX="${SUFFIX}.${GITHUB_SHA}" # SUFFIX="${SUFFIX}.${GITHUB_SHA}"

@ -1 +1 @@
Subproject commit 1d86efa33bf1b3c118947eac14280f9953a49bc9 Subproject commit edc2b3a4985a8cc95880e1d2b42b5aec9d793bbf

View file

@ -3,6 +3,9 @@
# #
IGNORE_UNKNOWN_FILES_FOR_MANAGED_COMPONENTS=y IGNORE_UNKNOWN_FILES_FOR_MANAGED_COMPONENTS=y
CONFIG_TINYUSB=y
CONFIG_TINYUSB_TASK_STACK_SIZE=16384
CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="pico-keys-sdk/config/esp32/partitions.csv" CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="pico-keys-sdk/config/esp32/partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/config/esp32/partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/config/esp32/partitions.csv"

View file

@ -143,10 +143,7 @@ int mbedtls_ansi_x963_kdf(mbedtls_md_type_t md_type,
mbedtls_md_update(&md_ctx, input, input_len); mbedtls_md_update(&md_ctx, input, input_len);
//TODO: be careful with architecture little vs. big //TODO: be careful with architecture little vs. big
counter_buf[0] = (uint8_t) ((counter >> 24) & 0xff); put_uint32_t_be(counter, counter_buf);
counter_buf[1] = (uint8_t) ((counter >> 16) & 0xff);
counter_buf[2] = (uint8_t) ((counter >> 8) & 0xff);
counter_buf[3] = (uint8_t) ((counter >> 0) & 0xff);
mbedtls_md_update(&md_ctx, counter_buf, 4); mbedtls_md_update(&md_ctx, counter_buf, 4);
@ -413,13 +410,7 @@ int cmd_cipher_sym() {
size_t olen = 0; size_t olen = 0;
mbedtls_asn1_buf params = mbedtls_asn1_buf params =
{.p = aad.data, .len = aad.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; {.p = aad.data, .len = aad.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)};
int r = mbedtls_pkcs5_pbes2_ext(&params, int r = mbedtls_pkcs5_pbes2_ext(&params, algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT, kdata, key_size, enc.data, enc.len, res_APDU, MAX_APDU_DATA, &olen);
algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT,
kdata,
key_size,
enc.data,
enc.len,
res_APDU, 4096, &olen);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) { if (r != 0) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();

View file

@ -30,7 +30,7 @@ int cmd_delete_file() {
} }
} }
else { else {
uint16_t fid = (apdu.data[0] << 8) | apdu.data[1]; uint16_t fid = get_uint16_t_be(apdu.data);
if (!(ef = search_file(fid))) { if (!(ef = search_file(fid))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }

View file

@ -19,6 +19,7 @@
#include "mbedtls/ecdh.h" #include "mbedtls/ecdh.h"
#ifdef PICO_PLATFORM #ifdef PICO_PLATFORM
#include "pico/aon_timer.h" #include "pico/aon_timer.h"
#include "hardware/watchdog.h"
#else #else
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
@ -35,17 +36,20 @@
#define CMD_DATETIME 0xA #define CMD_DATETIME 0xA
#define CMD_DYNOPS 0x6 #define CMD_DYNOPS 0x6
#define CMD_SECURE_LOCK 0x3A #define CMD_SECURE_LOCK 0x3A
#define CMD_REBOOT 0xFB
#define SECURE_LOCK_KEY_AGREEMENT 0x1 #define SECURE_LOCK_KEY_AGREEMENT 0x1
#define SECURE_LOCK_ENABLE 0x2 #define SECURE_LOCK_ENABLE 0x2
#define SECURE_LOCK_MASK 0x3 #define SECURE_LOCK_MASK 0x3
#define SECURE_LOCK_DISABLE 0x4 #define SECURE_LOCK_DISABLE 0x4
#define CMD_PHY 0x1B #define CMD_PHY 0x1B
#define CMD_OTP 0x4C #define CMD_OTP 0x4C
#define CMD_MEMORY 0x5
int cmd_extras() { int cmd_extras() {
int cmd = P1(apdu);
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
// Only allow change PHY without PIN // Only allow change PHY without PIN
if (!isUserAuthenticated && P1(apdu) != 0x1B) { if (!isUserAuthenticated && cmd != CMD_PHY && cmd != CMD_MEMORY) {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
} }
#endif #endif
@ -53,7 +57,7 @@ int cmd_extras() {
if (wait_button_pressed() == true) { if (wait_button_pressed() == true) {
return SW_SECURE_MESSAGE_EXEC_ERROR(); return SW_SECURE_MESSAGE_EXEC_ERROR();
} }
if (P1(apdu) == CMD_DATETIME) { //datetime operations if (cmd == CMD_DATETIME) { //datetime operations
if (P2(apdu) != 0x0) { if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
@ -66,8 +70,7 @@ int cmd_extras() {
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
#endif #endif
struct tm *tm = localtime(&tv.tv_sec); struct tm *tm = localtime(&tv.tv_sec);
res_APDU[res_APDU_size++] = (tm->tm_year + 1900) >> 8; res_APDU_size += put_uint16_t_be(tm->tm_year + 1900, res_APDU);
res_APDU[res_APDU_size++] = (tm->tm_year + 1900) & 0xff;
res_APDU[res_APDU_size++] = tm->tm_mon; res_APDU[res_APDU_size++] = tm->tm_mon;
res_APDU[res_APDU_size++] = tm->tm_mday; res_APDU[res_APDU_size++] = tm->tm_mday;
res_APDU[res_APDU_size++] = tm->tm_wday; res_APDU[res_APDU_size++] = tm->tm_wday;
@ -80,7 +83,7 @@ int cmd_extras() {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
struct tm tm; struct tm tm;
tm.tm_year = ((apdu.data[0] << 8) | (apdu.data[1])) - 1900; tm.tm_year = get_uint16_t_be(apdu.data) - 1900;
tm.tm_mon = apdu.data[2]; tm.tm_mon = apdu.data[2];
tm.tm_mday = apdu.data[3]; tm.tm_mday = apdu.data[3];
tm.tm_wday = apdu.data[4]; tm.tm_wday = apdu.data[4];
@ -97,7 +100,7 @@ int cmd_extras() {
#endif #endif
} }
} }
else if (P1(apdu) == CMD_DYNOPS) { //dynamic options else if (cmd == CMD_DYNOPS) { //dynamic options
if (P2(apdu) != 0x0) { if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
@ -106,8 +109,7 @@ int cmd_extras() {
} }
uint16_t opts = get_device_options(); uint16_t opts = get_device_options();
if (apdu.nc == 0) { if (apdu.nc == 0) {
res_APDU[res_APDU_size++] = opts >> 8; res_APDU_size += put_uint16_t_be(opts, res_APDU);
res_APDU[res_APDU_size++] = opts & 0xff;
} }
else { else {
uint8_t newopts[] = { apdu.data[0], (opts & 0xff) }; uint8_t newopts[] = { apdu.data[0], (opts & 0xff) };
@ -116,7 +118,7 @@ int cmd_extras() {
low_flash_available(); low_flash_available();
} }
} }
else if (P1(apdu) == CMD_SECURE_LOCK) { // secure lock else if (cmd == CMD_SECURE_LOCK) { // secure lock
if (apdu.nc == 0) { if (apdu.nc == 0) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
@ -148,7 +150,7 @@ int cmd_extras() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 4096); ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, MAX_APDU_DATA);
mbedtls_ecdh_free(&hkey); mbedtls_ecdh_free(&hkey);
if (ret != 0) { if (ret != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
@ -160,13 +162,12 @@ int cmd_extras() {
if (mse.init == false) { if (mse.init == false) {
return SW_COMMAND_NOT_ALLOWED(); return SW_COMMAND_NOT_ALLOWED();
} }
uint16_t opts = get_device_options();
int ret = mse_decrypt_ct(apdu.data, apdu.nc); int ret = mse_decrypt_ct(apdu.data, apdu.nc);
if (ret != 0) { if (ret != 0) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
if (P2(apdu) == SECURE_LOCK_ENABLE || P2(apdu) == SECURE_LOCK_DISABLE) { // 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) }; uint8_t newopts[] = { opts >> 8, (opts & 0xff) };
if ((P2(apdu) == SECURE_LOCK_ENABLE && !(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))) { (P2(apdu) == SECURE_LOCK_DISABLE && (opts & HSM_OPT_SECURE_LOCK))) {
@ -194,14 +195,14 @@ int cmd_extras() {
file_put_data(tf, newopts, sizeof(newopts)); file_put_data(tf, newopts, sizeof(newopts));
low_flash_available(); low_flash_available();
} }
else if (P2(apdu) == SECURE_LOCK_MASK) { else if (P2(apdu) == SECURE_LOCK_MASK && (opts & HSM_OPT_SECURE_LOCK)) {
memcpy(mkek_mask, apdu.data, apdu.nc); memcpy(mkek_mask, apdu.data, MKEK_KEY_SIZE);
has_mkek_mask = true; has_mkek_mask = true;
} }
} }
} }
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
else if (P1(apdu) == CMD_PHY) { // Set PHY else if (cmd == CMD_PHY) { // Set PHY
if (apdu.nc == 0) { if (apdu.nc == 0) {
if (file_has_data(ef_phy)) { if (file_has_data(ef_phy)) {
res_APDU_size = file_get_size(ef_phy); res_APDU_size = file_get_size(ef_phy);
@ -213,8 +214,8 @@ int cmd_extras() {
if (apdu.nc != 4) { if (apdu.nc != 4) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
phy_data.vid = (apdu.data[0] << 8) | apdu.data[1]; phy_data.vid = get_uint16_t_be(apdu.data);
phy_data.pid = (apdu.data[2] << 8) | apdu.data[3]; phy_data.pid = get_uint16_t_be(apdu.data + 2);
phy_data.vidpid_present = true; phy_data.vidpid_present = true;
} }
else if (P2(apdu) == PHY_LED_GPIO) { else if (P2(apdu) == PHY_LED_GPIO) {
@ -229,7 +230,7 @@ int cmd_extras() {
if (apdu.nc != 2) { if (apdu.nc != 2) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
phy_data.opts = (apdu.data[0] << 8) | apdu.data[1]; phy_data.opts = get_uint16_t_be(apdu.data);
} }
else { else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
@ -246,11 +247,11 @@ int cmd_extras() {
} }
#endif #endif
#if PICO_RP2350 #if PICO_RP2350
else if (P1(apdu) == CMD_OTP) { else if (cmd == CMD_OTP) {
if (apdu.nc < 2) { if (apdu.nc < 2) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
uint16_t row = (apdu.data[0] << 8) | apdu.data[1]; uint16_t row = get_uint16_t_be(apdu.data);
bool israw = P2(apdu) == 0x1; bool israw = P2(apdu) == 0x1;
if (apdu.nc == 2) { if (apdu.nc == 2) {
if (row > 0xbf && row < 0xf48) { if (row > 0xbf && row < 0xf48) {
@ -288,6 +289,23 @@ int cmd_extras() {
} }
} }
#endif #endif
#ifdef PICO_PLATFORM
else if (cmd == CMD_REBOOT) {
if (apdu.nc != 0) {
return SW_WRONG_LENGTH();
}
watchdog_reboot(0, 0, 100);
}
#endif
else if (cmd == CMD_MEMORY) {
res_APDU_size = 0;
uint32_t free = flash_free_space(), total = flash_total_space(), used = flash_used_space(), nfiles = flash_num_files(), size = flash_size();
res_APDU_size += put_uint32_t_be(free, res_APDU + res_APDU_size);
res_APDU_size += put_uint32_t_be(used, res_APDU + res_APDU_size);
res_APDU_size += put_uint32_t_be(total, res_APDU + res_APDU_size);
res_APDU_size += put_uint32_t_be(nfiles, res_APDU + res_APDU_size);
res_APDU_size += put_uint32_t_be(size, res_APDU + res_APDU_size);
}
else { else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }

View file

@ -43,10 +43,14 @@ extern void reset_puk_store();
int cmd_initialize() { int cmd_initialize() {
if (apdu.nc > 0) { if (apdu.nc > 0) {
uint8_t mkek[MKEK_SIZE]; uint8_t mkek[MKEK_SIZE];
uint16_t opts = get_device_options();
if (opts & HSM_OPT_SECURE_LOCK && !has_mkek_mask) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
int ret_mkek = load_mkek(mkek); //Try loading MKEK with previous session int ret_mkek = load_mkek(mkek); //Try loading MKEK with previous session
initialize_flash(true); initialize_flash(true);
scan_all(); scan_all();
has_session_pin = has_session_sopin = false; has_session_pin = has_session_sopin = has_mkek_mask = false;
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL; uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL;
uint16_t tag_len = 0; uint16_t tag_len = 0;
@ -206,7 +210,7 @@ int cmd_initialize() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
uint16_t ee_len = 0, term_len = 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) { if ((ee_len = asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
@ -218,7 +222,7 @@ int cmd_initialize() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if ((term_len = asn1_cvc_cert(&ecdsa, PICO_KEYS_KEY_EC, res_APDU + ee_len, 4096 - ee_len, NULL, 0, true)) == 0) { if ((term_len = asn1_cvc_cert(&ecdsa, PICO_KEYS_KEY_EC, res_APDU + ee_len, MAX_APDU_DATA - ee_len, NULL, 0, true)) == 0) {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
@ -231,7 +235,7 @@ int cmd_initialize() {
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"; *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, MAX_APDU_DATA);
fpk = search_file(EF_PRKD_DEV); fpk = search_file(EF_PRKD_DEV);
ret = file_put_data(fpk, res_APDU, prkd_len); ret = file_put_data(fpk, res_APDU, prkd_len);
} }
@ -243,10 +247,7 @@ int cmd_initialize() {
} }
else { //free memory bytes request else { //free memory bytes request
int heap_left = heapLeft(); int heap_left = heapLeft();
res_APDU[0] = ((heap_left >> 24) & 0xff); res_APDU_size += put_uint32_t_be(heap_left, res_APDU);
res_APDU[1] = ((heap_left >> 16) & 0xff);
res_APDU[2] = ((heap_left >> 8) & 0xff);
res_APDU[3] = ((heap_left >> 0) & 0xff);
res_APDU[4] = 0; res_APDU[4] = 0;
res_APDU[5] = HSM_VERSION_MAJOR; res_APDU[5] = HSM_VERSION_MAJOR;
res_APDU[6] = HSM_VERSION_MINOR; res_APDU[6] = HSM_VERSION_MINOR;

View file

@ -57,7 +57,7 @@ int cmd_key_unwrap() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = store_keys(&ctx, PICO_KEYS_KEY_RSA, key_id); 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, 4096, NULL, 0)) == 0) { if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICO_KEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
mbedtls_rsa_free(&ctx); mbedtls_rsa_free(&ctx);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
@ -77,7 +77,7 @@ int cmd_key_unwrap() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = store_keys(&ctx, PICO_KEYS_KEY_EC, key_id); 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, 4096, NULL, 0)) == 0) { if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICO_KEYS_KEY_EC, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
mbedtls_ecp_keypair_free(&ctx); mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }

View file

@ -58,8 +58,7 @@ int cmd_keypair_gen() {
mbedtls_rsa_free(&rsa); mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if ((res_APDU_size = if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
(uint16_t)asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
ret = store_keys(&rsa, PICO_KEYS_KEY_RSA, key_id); ret = store_keys(&rsa, PICO_KEYS_KEY_RSA, key_id);
@ -131,8 +130,7 @@ int cmd_keypair_gen() {
} }
} }
} }
if ((res_APDU_size = if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, MAX_APDU_DATA, ext.data, ext.len)) == 0) {
(uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext.data, ext.len)) == 0) {
if (ext.data) { if (ext.data) {
free(ext.data); free(ext.data);
} }

View file

@ -22,12 +22,10 @@ int cmd_list_keys() {
/* First we send DEV private key */ /* First we send DEV private key */
/* Both below conditions should be always TRUE */ /* Both below conditions should be always TRUE */
if (search_file(EF_PRKD_DEV)) { if (search_file(EF_PRKD_DEV)) {
res_APDU[res_APDU_size++] = EF_PRKD_DEV >> 8; res_APDU_size += put_uint16_t_be(EF_PRKD_DEV, res_APDU + res_APDU_size);
res_APDU[res_APDU_size++] = EF_PRKD_DEV & 0xff;
} }
if (search_file(EF_KEY_DEV)) { if (search_file(EF_KEY_DEV)) {
res_APDU[res_APDU_size++] = EF_KEY_DEV >> 8; res_APDU_size += put_uint16_t_be(EF_KEY_DEV, res_APDU + res_APDU_size);
res_APDU[res_APDU_size++] = EF_KEY_DEV & 0xff;
} }
//first CC //first CC
for (int i = 0; i < dynamic_files; i++) { for (int i = 0; i < dynamic_files; i++) {

View file

@ -30,7 +30,7 @@ int cmd_read_binary() {
offset = p2; offset = p2;
} }
else { else {
offset = make_uint16_t(p1, p2) & 0x7fff; offset = make_uint16_t_be(p1, p2) & 0x7fff;
ef = currentEF; ef = currentEF;
} }
} }
@ -41,7 +41,7 @@ int cmd_read_binary() {
} }
} }
else { else {
uint16_t file_id = make_uint16_t(p1, p2); // & 0x7fff; uint16_t file_id = make_uint16_t_be(p1, p2); // & 0x7fff;
if (file_id == 0x0) { if (file_id == 0x0) {
ef = currentEF; ef = currentEF;
} }

View file

@ -48,7 +48,7 @@ int cmd_select() {
//} //}
if (apdu.nc == 2) { if (apdu.nc == 2) {
fid = get_uint16_t(apdu.data, 0); fid = get_uint16_t_be(apdu.data);
} }
//if ((fid & 0xff00) == (KEY_PREFIX << 8)) //if ((fid & 0xff00) == (KEY_PREFIX << 8))
@ -119,8 +119,7 @@ int cmd_select() {
res_APDU[res_APDU_size++] = 0x85; res_APDU[res_APDU_size++] = 0x85;
res_APDU[res_APDU_size++] = 5; res_APDU[res_APDU_size++] = 5;
uint16_t opts = get_device_options(); uint16_t opts = get_device_options();
res_APDU[res_APDU_size++] = opts >> 8; res_APDU_size += put_uint16_t_be(opts, res_APDU + res_APDU_size);
res_APDU[res_APDU_size++] = opts & 0xff;
res_APDU[res_APDU_size++] = 0xFF; res_APDU[res_APDU_size++] = 0xFF;
res_APDU[res_APDU_size++] = HSM_VERSION_MAJOR; res_APDU[res_APDU_size++] = HSM_VERSION_MAJOR;
res_APDU[res_APDU_size++] = HSM_VERSION_MINOR; res_APDU[res_APDU_size++] = HSM_VERSION_MINOR;

View file

@ -431,8 +431,7 @@ uint16_t asn1_build_cert_description(const uint8_t *label,
p += format_tlv_len(asn1_len_tag(0x4, sizeof(uint16_t)), p); p += format_tlv_len(asn1_len_tag(0x4, sizeof(uint16_t)), p);
*p++ = 0x4; *p++ = 0x4;
p += format_tlv_len(sizeof(uint16_t), p); p += format_tlv_len(sizeof(uint16_t), p);
*p++ = fid >> 8; put_uint16_t_be(fid, p); p += sizeof(uint16_t);
*p++ = fid & 0xff;
return (uint16_t)(p - buf); return (uint16_t)(p - buf);
} }
@ -508,8 +507,7 @@ uint16_t asn1_build_prkd_generic(const uint8_t *label,
p += format_tlv_len(asn1_len_tag(0x2, 2), p); p += format_tlv_len(asn1_len_tag(0x2, 2), p);
*p++ = 0x2; *p++ = 0x2;
p += format_tlv_len(2, p); p += format_tlv_len(2, p);
*p++ = (keysize >> 8) & 0xff; p += put_uint16_t_be(keysize, p);
*p++ = keysize & 0xff;
} }
//Seq 4 //Seq 4
@ -528,8 +526,7 @@ uint16_t asn1_build_prkd_generic(const uint8_t *label,
if (key_type & PICO_KEYS_KEY_EC || key_type & PICO_KEYS_KEY_RSA) { if (key_type & PICO_KEYS_KEY_EC || key_type & PICO_KEYS_KEY_RSA) {
*p++ = 0x2; *p++ = 0x2;
p += format_tlv_len(2, p); p += format_tlv_len(2, p);
*p++ = (keysize >> 8) & 0xff; p += put_uint16_t_be(keysize, p);
*p++ = keysize & 0xff;
} }
return (uint16_t)(p - buf); return (uint16_t)(p - buf);
} }

View file

@ -61,7 +61,7 @@ file_t file_entries[] = {
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
.ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //retries PIN (SOPIN) .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //retries PIN (SOPIN)
/* 15 */ { .fid = EF_DEVOPS, .parent = 5, .name = NULL, /* 15 */ { .fid = EF_DEVOPS, .parent = 5, .name = NULL,
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL,
.ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //Device options .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //Device options
/* 16 */ { .fid = EF_PRKDFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, /* 16 */ { .fid = EF_PRKDFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF,
.data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.PrKDFs .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.PrKDFs

View file

@ -50,6 +50,14 @@ uint32_t crc32c(const uint8_t *buf, size_t len) {
return ~crc; return ~crc;
} }
void mkek_masked(uint8_t *mkek, const uint8_t *mask) {
if (mask) {
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mask[i];
}
}
}
int load_mkek(uint8_t *mkek) { int load_mkek(uint8_t *mkek) {
if (has_session_pin == false && has_session_sopin == false) { if (has_session_pin == false && has_session_sopin == false) {
return PICOKEY_NO_LOGIN; return PICOKEY_NO_LOGIN;
@ -73,6 +81,10 @@ int load_mkek(uint8_t *mkek) {
return PICOKEY_EXEC_ERROR; return PICOKEY_EXEC_ERROR;
} }
if (has_mkek_mask) {
mkek_masked(mkek, mkek_mask);
}
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) { if (ret != 0) {
return PICOKEY_EXEC_ERROR; return PICOKEY_EXEC_ERROR;
@ -80,11 +92,8 @@ int load_mkek(uint8_t *mkek) {
if (crc32c(MKEK_KEY(mkek), MKEK_KEY_SIZE) != *(uint32_t *) MKEK_CHECKSUM(mkek)) { if (crc32c(MKEK_KEY(mkek), MKEK_KEY_SIZE) != *(uint32_t *) MKEK_CHECKSUM(mkek)) {
return PICOKEY_WRONG_DKEK; return PICOKEY_WRONG_DKEK;
} }
if (has_mkek_mask || otp_key_1) { if (otp_key_1) {
const uint8_t *mask = otp_key_1 ? otp_key_1 : mkek_mask; mkek_masked(mkek, otp_key_1);
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mask[i];
}
} }
return PICOKEY_OK; return PICOKEY_OK;
} }
@ -125,6 +134,9 @@ int store_mkek(const uint8_t *mkek) {
else { else {
memcpy(tmp_mkek, mkek, MKEK_SIZE); memcpy(tmp_mkek, mkek, MKEK_SIZE);
} }
if (otp_key_1) {
mkek_masked(tmp_mkek, otp_key_1);
}
*(uint32_t *) MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE); *(uint32_t *) MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE);
if (has_session_pin) { if (has_session_pin) {
uint8_t tmp_mkek_pin[MKEK_SIZE]; uint8_t tmp_mkek_pin[MKEK_SIZE];
@ -319,7 +331,7 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
return PICOKEY_WRONG_LENGTH; return PICOKEY_WRONG_LENGTH;
} }
put_uint16_t(kb_len, kb + 8); put_uint16_t_be(kb_len, kb + 8);
memcpy(kb + 10, key_ctx, kb_len); memcpy(kb + 10, key_ctx, kb_len);
kb_len += 2; kb_len += 2;
@ -332,15 +344,15 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
} }
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
kb_len = 0; kb_len = 0;
put_uint16_t((uint16_t)mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len);
put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&rsa->D, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->D)); mbedtls_mpi_write_binary(&rsa->D, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->D));
kb_len += (uint16_t)mbedtls_mpi_size(&rsa->D); kb_len += (uint16_t)mbedtls_mpi_size(&rsa->D);
put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&rsa->N, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->N)); mbedtls_mpi_write_binary(&rsa->N, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->N));
kb_len += (uint16_t)mbedtls_mpi_size(&rsa->N); kb_len += (uint16_t)mbedtls_mpi_size(&rsa->N);
put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&rsa->E, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->E)); mbedtls_mpi_write_binary(&rsa->E, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->E));
kb_len += (uint16_t)mbedtls_mpi_size(&rsa->E); kb_len += (uint16_t)mbedtls_mpi_size(&rsa->E);
@ -353,32 +365,32 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
} }
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
kb_len = 0; kb_len = 0;
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.A, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.A)); mbedtls_mpi_write_binary(&ecdsa->grp.A, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.A));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.A); kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.A);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.B, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.B)); mbedtls_mpi_write_binary(&ecdsa->grp.B, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.B));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.B); kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.B);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.P, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.P)); mbedtls_mpi_write_binary(&ecdsa->grp.P, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.P));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.P); kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.P);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.N, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.N)); mbedtls_mpi_write_binary(&ecdsa->grp.N, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.N));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N); kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N);
size_t olen = 0; 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 += put_uint16_t_be((uint16_t)olen, kb + 8 + kb_len);
kb_len += 2 + (uint16_t)olen; kb_len += (uint16_t)olen;
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len); kb_len += 2; kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d)); mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d));
kb_len += (uint16_t)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 += put_uint16_t_be((uint16_t)olen, kb + 8 + kb_len);
kb_len += 2 + (uint16_t)olen; kb_len += (uint16_t)olen;
algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03"; algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03";
algo_len = 12; algo_len = 12;
@ -409,7 +421,7 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
} }
if (allowed && allowed_len > 0) { if (allowed && allowed_len > 0) {
put_uint16_t(allowed_len, out + *out_len); *out_len += 2; *out_len += put_uint16_t_be(allowed_len, out + *out_len);
memcpy(out + *out_len, allowed, allowed_len); memcpy(out + *out_len, allowed, allowed_len);
*out_len += allowed_len; *out_len += allowed_len;
} }
@ -517,21 +529,21 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
uint16_t ofs = 9; uint16_t ofs = 9;
//OID //OID
uint16_t len = get_uint16_t(in, ofs); uint16_t len = get_uint16_t_be(in + ofs);
ofs += len + 2; ofs += len + 2;
//Allowed algorithms //Allowed algorithms
len = get_uint16_t(in, ofs); len = get_uint16_t_be(in + ofs);
*allowed = (uint8_t *) (in + ofs + 2); *allowed = (uint8_t *) (in + ofs + 2);
*allowed_len = len; *allowed_len = len;
ofs += len + 2; ofs += len + 2;
//Access conditions //Access conditions
len = get_uint16_t(in, ofs); len = get_uint16_t_be(in + ofs);
ofs += len + 2; ofs += len + 2;
//Key OID //Key OID
len = get_uint16_t(in, ofs); len = get_uint16_t_be(in + ofs);
ofs += len + 2; ofs += len + 2;
if ((in_len - 16 - ofs) % 16 != 0) { if ((in_len - 16 - ofs) % 16 != 0) {
@ -545,7 +557,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
return r; return r;
} }
int key_size = get_uint16_t(kb, 8); int key_size = get_uint16_t_be(kb + 8);
if (key_size_out) { if (key_size_out) {
*key_size_out = key_size; *key_size_out = key_size;
} }
@ -554,14 +566,14 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
mbedtls_rsa_init(rsa); mbedtls_rsa_init(rsa);
if (key_type == 5) { if (key_type == 5) {
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->D, kb + ofs, len); ofs += len; r = mbedtls_mpi_read_binary(&rsa->D, kb + ofs, len); ofs += len;
if (r != 0) { if (r != 0) {
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
return PICOKEY_WRONG_DATA; return PICOKEY_WRONG_DATA;
} }
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->N, kb + ofs, len); ofs += len; r = mbedtls_mpi_read_binary(&rsa->N, kb + ofs, len); ofs += len;
if (r != 0) { if (r != 0) {
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
@ -570,12 +582,12 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
} }
else if (key_type == 6) { else if (key_type == 6) {
//DP-1 //DP-1
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//DQ-1 //DQ-1
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->P, kb + ofs, len); ofs += len; r = mbedtls_mpi_read_binary(&rsa->P, kb + ofs, len); ofs += len;
if (r != 0) { if (r != 0) {
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
@ -583,19 +595,19 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
} }
//PQ //PQ
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->Q, kb + ofs, len); ofs += len; r = mbedtls_mpi_read_binary(&rsa->Q, kb + ofs, len); ofs += len;
if (r != 0) { if (r != 0) {
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
return PICOKEY_WRONG_DATA; return PICOKEY_WRONG_DATA;
} }
//N //N
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
} }
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->E, kb + ofs, len); ofs += len; r = mbedtls_mpi_read_binary(&rsa->E, kb + ofs, len); ofs += len;
if (r != 0) { if (r != 0) {
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
@ -633,13 +645,13 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
mbedtls_ecdsa_init(ecdsa); mbedtls_ecdsa_init(ecdsa);
//A //A
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//B //B
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//P //P
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(kb + ofs, len); mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(kb + ofs, len);
if (ec_id == MBEDTLS_ECP_DP_NONE) { if (ec_id == MBEDTLS_ECP_DP_NONE) {
mbedtls_ecdsa_free(ecdsa); mbedtls_ecdsa_free(ecdsa);
@ -648,10 +660,10 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
ofs += len; ofs += len;
//N //N
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//G //G
len = get_uint16_t(kb, ofs); len = get_uint16_t_be(kb + ofs);
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && kb[ofs + 2] != 0x09) { if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && kb[ofs + 2] != 0x09) {
ec_id = MBEDTLS_ECP_DP_ED25519; ec_id = MBEDTLS_ECP_DP_ED25519;
} }
@ -661,7 +673,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
ofs += len + 2; ofs += len + 2;
//d //d
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_ecp_read_key(ec_id, ecdsa, kb + ofs, len); r = mbedtls_ecp_read_key(ec_id, ecdsa, kb + ofs, len);
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(ecdsa); mbedtls_ecdsa_free(ecdsa);
@ -670,7 +682,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
ofs += len; ofs += len;
//Q //Q
len = get_uint16_t(kb, ofs); ofs += 2; len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_ecp_point_read_binary(&ecdsa->grp, &ecdsa->Q, kb + ofs, len); r = mbedtls_ecp_point_read_binary(&ecdsa->grp, &ecdsa->Q, kb + ofs, len);
if (r != 0) { if (r != 0) {
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) { if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) {

View file

@ -269,7 +269,7 @@ int sc_hsm_unload() {
uint16_t get_device_options() { uint16_t get_device_options() {
file_t *ef = search_file(EF_DEVOPS); file_t *ef = search_file(EF_DEVOPS);
if (file_has_data(ef)) { if (file_has_data(ef)) {
return (file_read_uint8(ef) << 8) | file_read_uint8_offset(ef, 1); return get_uint16_t_be(file_get_data(ef));
} }
return 0x0; return 0x0;
} }
@ -462,7 +462,7 @@ uint32_t get_key_counter(file_t *fkey) {
uint16_t tag_len = 0; uint16_t tag_len = 0;
const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len); const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len);
if (meta_tag) { if (meta_tag) {
return (meta_tag[0] << 24) | (meta_tag[1] << 16) | (meta_tag[2] << 8) | meta_tag[3]; return get_uint32_t_be(meta_tag);
} }
return 0xffffffff; return 0xffffffff;
} }
@ -498,14 +498,9 @@ uint32_t decrement_key_counter(file_t *fkey) {
asn1_ctx_init(meta_data, meta_size, &ctxi); asn1_ctx_init(meta_data, meta_size, &ctxi);
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
if (tag == 0x90) { // ofset tag if (tag == 0x90) { // ofset tag
uint32_t val = uint32_t val = get_uint32_t_be(tag_data);
(tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3];
val--; val--;
tag_data[0] = (val >> 24) & 0xff; put_uint32_t_be(val, tag_data);
tag_data[1] = (val >> 16) & 0xff;
tag_data[2] = (val >> 8) & 0xff;
tag_data[3] = val & 0xff;
int r = meta_add(fkey->fid, cmeta, (uint16_t)meta_size); int r = meta_add(fkey->fid, cmeta, (uint16_t)meta_size);
free(cmeta); free(cmeta);
if (r != 0) { if (r != 0) {

View file

@ -32,6 +32,9 @@
#include "file.h" #include "file.h"
#include "apdu.h" #include "apdu.h"
#include "pico_keys.h" #include "pico_keys.h"
#include "usb.h"
#define MAX_APDU_DATA (USB_BUFFER_SIZE - 20)
extern const uint8_t sc_hsm_aid[]; extern const uint8_t sc_hsm_aid[];

View file

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

Binary file not shown.

View file

@ -27,7 +27,7 @@ from cvc import oid
from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric import ec
from picohsm import DOPrefixes, APDUResponse, SWCodes from picohsm import DOPrefixes, APDUResponse, SWCodes
KDM = unhexlify(b'30820420060b2b0601040181c31f0402016181ed7f2181e97f4e81a25f290100421045535049434f48534d434130303030317f494f060a04007f0007020202020386410421ee4a21c16a10f737f12e78e5091b266612038cdabebb722b15bf6d41b877fbf64d9ab69c39b9831b1ae00bef2a4e81976f7688d45189bb232a24703d8a96a55f201045535049434f48534d445630303030317f4c12060904007f000703010202530580000000005f25060202000801085f24060203000601045f37403f75c08fffc9186b56e6147199e82bfc327ceef72495bc567961cd54d702f13e3c2766fcd1d11bd6a9d1f4a229b76b248ceb9af88d59a74d0ab149448705159b6281e97f2181e57f4e819e5f290100421045535049434f48534d445630303030317f494f060a04007f00070202020203864104c8561b41e54fea81bb80dd4a6d537e7c3904344e8ca90bc5f668111811e02c8d5d51ca93ca89558f2a8a9cbb147434e3441ec174505ff980fd7a7106286196915f201045535049434f48534d54524a444736387f4c0e060904007f0007030102025301005f25060203000300065f24060204000300055f3740983de63d0975b715ebd8a93cb38fa9638882c8b7064d51a6facabed693b92edc098e458b713203413ef6de0958c44772cbdbc264205c7b1bdb8b4fcb2516437f638201f1678201ed7f218201937f4e82014b5f290100421045535049434f48534d54524a444736387f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a78641048b1f450912a2e4d428b7eefc5fa05618a9ef295e90009a61cbb0970181b333474ea94f94cde5a11aba0589e85d4225002789ff1cdcf25756f059647b49fc2a158701015f201045535049434f48534d54524a444736385f3740372407c20de7257c89dae1e6606c8a046ca65efaa010c0a22b75c402ee243de51f5f1507457193679ed9db4fbbfe8efb9d695b684492b665ad8ba98c1f84ea38421045535049434f48534d54524a444736385f374098718e2e14a44386b689b71a101530316b65ab49a91bab0dd56099c5161ecb8aadff6cf27449f94034e58b7306f01e6ffa2766a2f5bb1281e12e5f1f9174733454400cf8926ca5bec9a91bcd47bf391c15d94ef6e3243d5fd1fffeaafd586766bc3221eafd808f17f8450f238cc1fe7ab1854443db31d622f53a2b3fdb3ad750d5ce') KDM = unhexlify(b'30820420060B2B0601040181C31F0402016181ED7F2181E97F4E81A25F290100421045535049434F48534D434130303030317F494F060A04007F0007020202020386410421EE4A21C16A10F737F12E78E5091B266612038CDABEBB722B15BF6D41B877FBF64D9AB69C39B9831B1AE00BEF2A4E81976F7688D45189BB232A24703D8A96A55F201045535049434F48534D445630303030317F4C12060904007F000703010202530580000000005F25060202000801085F24060203000601045F37403F75C08FFFC9186B56E6147199E82BFC327CEEF72495BC567961CD54D702F13E3C2766FCD1D11BD6A9D1F4A229B76B248CEB9AF88D59A74D0AB149448705159B6281E97F2181E57F4E819E5F290100421045535049434F48534D445630303030317F494F060A04007F000702020202038641043359F5234CE62E0EB80460046D8FD1AAE018CC8B9E687B40AA2C047E352409B45153D1AD888E4E7E780A3B1FA8C69CA8998BD271C8849137149142E96816A5A45F201045535049434F48534D54524A5A58314A7F4C0E060904007F0007030102025301005F25060205000100085F24060206000100085F374016F155B01CDE7FB902C8A631FCB6938458CB570EAB088DEFE1FFACD3AEFF069020256EECCF8E962461534ED682DB87BB9801E25556F87BF524385C536D19A7D1638201F1678201ED7F218201937F4E82014B5F290100421045535049434F48534D54524A5A58314A7F4982011D060A04007F000702020202038120A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E537782207D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9832026DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B68441048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F0469978520A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A786410443F0BAB3EB271E1B762BDB81C2CC10C21CF9E8A73241B86C9552614A8842DA00A556C20BC4250C275981FE196F8D2E8766DE06C609BA07AC3E6E1468EAC451408701015F201045535049434F48534D54524A5A58314A5F37402E79A552EA5ABE1B4244841CC55515F31CACFE9B3E0A3FC3FC178DFD5ED6ADC67E03FCC65C24A8A65658768A1A522F372E9897B87058E453A647FC58E089D30D421045535049434F48534D54524A5A58314A5F37400B54434EF57C6DD55D26B44F63940E9F15C10FBC8FC013528F76ACF917D74EF41D635D630F778862ADBD3EE8574F4ABC28B9A6044DFCB9C30D83C1A4DBE6437054400964DBAED86825DBA4E5BCEFF66DAF5739A71D4B2677FB1F53ABA23B3D1D1A686A06478C3CF7FF797FE7C8A4D090D881319BD15AABE709D3EA74A48C88E4387F')
def test_initialize(device): def test_initialize(device):
device.initialize(key_domains=1) device.initialize(key_domains=1)

View file

@ -151,6 +151,10 @@ def parse_args():
parser_otp.add_argument('--lock', help='Lock & protect (no other firmwares can be loaded)', action='store_true') parser_otp.add_argument('--lock', help='Lock & protect (no other firmwares can be loaded)', action='store_true')
parser_otp.add_argument('--index', help='Bootkey index [0-3]', type=int, default=0, choices=[0, 1, 2, 3]) parser_otp.add_argument('--index', help='Bootkey index [0-3]', type=int, default=0, choices=[0, 1, 2, 3])
parser_reboot = subparser.add_parser('reboot', help='Reboots the Pico HSM.')
parser_memory = subparser.add_parser('memory', help='Get memory usage.')
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -369,7 +373,7 @@ class SecureLock:
def disable_device_aut(self): def disable_device_aut(self):
ct = self.get_skey() ct = self.get_skey()
self.picohsm.send(cla=0x80, command=0x64, p1=0x3A, p2=0x04, p3=list(ct)) self.picohsm.send(cla=0x80, command=0x64, p1=0x3A, p2=0x04, data=list(ct))
def secure(picohsm, args): def secure(picohsm, args):
slck = SecureLock(picohsm) slck = SecureLock(picohsm)
@ -511,8 +515,20 @@ def otp(picohsm, args):
elif (args.subcommand == 'secure_boot'): elif (args.subcommand == 'secure_boot'):
picohsm.secure_boot(BOOTKEY, bootkey_index=args.index, lock=args.lock) picohsm.secure_boot(BOOTKEY, bootkey_index=args.index, lock=args.lock)
def reboot(picohsm, args):
picohsm.reboot()
def memory(picohsm, args):
mem = picohsm.memory()
print(f'Memory usage:')
print(f'\tFree: {mem["free"]/1024:.2f} kilobytes ({mem["free"]*100/mem["total"]:.2f}%)')
print(f'\tUsed: {mem["used"]/1024:.2f} kilobytes ({mem["used"]*100/mem["total"]:.2f}%)')
print(f'\tTotal: {mem["total"]/1024:.2f} kilobytes')
print(f'\tFlash size: {mem["size"]/1024:.2f} kilobytes')
print(f'\tFiles: {mem["files"]}')
def main(args): def main(args):
sys.stderr.buffer.write(b'Pico HSM Tool v2.0\n') sys.stderr.buffer.write(b'Pico HSM Tool v2.2\n')
sys.stderr.buffer.write(b'Author: Pol Henarejos\n') sys.stderr.buffer.write(b'Author: Pol Henarejos\n')
sys.stderr.buffer.write(b'Report bugs to https://github.com/polhenarejos/pico-hsm/issues\n') sys.stderr.buffer.write(b'Report bugs to https://github.com/polhenarejos/pico-hsm/issues\n')
sys.stderr.buffer.write(b'\n\n') sys.stderr.buffer.write(b'\n\n')
@ -541,6 +557,10 @@ def main(args):
phy(picohsm, args) phy(picohsm, args)
elif (args.command == 'otp'): elif (args.command == 'otp'):
otp(picohsm, args) otp(picohsm, args)
elif (args.command == 'reboot'):
reboot(picohsm, args)
elif (args.command == 'memory'):
memory(picohsm, args)
def run(): def run():
args = parse_args() args = parse_args()

View file

@ -7,6 +7,7 @@ if [[ $1 == "pico" ]]; then
sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
git clone https://github.com/raspberrypi/pico-sdk git clone https://github.com/raspberrypi/pico-sdk
cd pico-sdk cd pico-sdk
git checkout tags/2.1.0
git submodule update --init git submodule update --init
cd .. cd ..
git clone https://github.com/raspberrypi/picotool git clone https://github.com/raspberrypi/picotool
@ -22,6 +23,7 @@ mkdir build_pico
cd build_pico cd build_pico
cmake -DPICO_SDK_PATH=../pico-sdk .. cmake -DPICO_SDK_PATH=../pico-sdk ..
make make
cd ..
elif [[ $1 == "esp32" ]]; then elif [[ $1 == "esp32" ]]; then
sudo apt install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 sudo apt install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
git clone --recursive https://github.com/espressif/esp-idf.git git clone --recursive https://github.com/espressif/esp-idf.git
@ -31,6 +33,10 @@ cd esp-idf
cd .. cd ..
idf.py set-target esp32s3 idf.py set-target esp32s3
idf.py all idf.py all
mkdir -p release
cd build
esptool.py --chip ESP32-S3 merge_bin -o ../release/pico_hsm_esp32-s3.bin @flash_args
cd ..
else else
mkdir build mkdir build
cd build cd build