Skip to content

Commit

Permalink
Upgrade to v5.2
Browse files Browse the repository at this point in the history
Signed-off-by: Pol Henarejos <[email protected]>
  • Loading branch information
polhenarejos committed Jan 15, 2025
2 parents bb45c9b + 297f2e6 commit 4c636e0
Show file tree
Hide file tree
Showing 24 changed files with 164 additions and 120 deletions.
1 change: 1 addition & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
run: |
./workflows/autobuild.sh pico
./build_pico_hsm.sh
./workflows/autobuild.sh esp32
- name: Update nightly release
uses: pyTooling/Actions/releaser@main
with:
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ set(USB_ITF_CCID 1)
set(USB_ITF_WCID 1)
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)
project(pico_hsm)
Expand Down Expand Up @@ -125,5 +125,7 @@ if(NOT ESP_PLATFORM)
)
endif(APPLE)
target_link_libraries(pico_hsm PRIVATE pthread m)
else()
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
endif()
endif()
2 changes: 1 addition & 1 deletion build_pico_hsm.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

VERSION_MAJOR="5"
VERSION_MINOR="0-eddsa1"
VERSION_MINOR="2-eddsa1"
SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}"
#if ! [[ -z "${GITHUB_SHA}" ]]; then
# SUFFIX="${SUFFIX}.${GITHUB_SHA}"
Expand Down
3 changes: 3 additions & 0 deletions sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#
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_FILENAME="pico-keys-sdk/config/esp32/partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/config/esp32/partitions.csv"
Expand Down
13 changes: 2 additions & 11 deletions src/hsm/cmd_cipher_sym.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,7 @@ 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
counter_buf[0] = (uint8_t) ((counter >> 24) & 0xff);
counter_buf[1] = (uint8_t) ((counter >> 16) & 0xff);
counter_buf[2] = (uint8_t) ((counter >> 8) & 0xff);
counter_buf[3] = (uint8_t) ((counter >> 0) & 0xff);
put_uint32_t_be(counter, counter_buf);

mbedtls_md_update(&md_ctx, counter_buf, 4);

Expand Down Expand Up @@ -413,13 +410,7 @@ int cmd_cipher_sym() {
size_t olen = 0;
mbedtls_asn1_buf params =
{.p = aad.data, .len = aad.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)};
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, 4096, &olen);
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);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) {
return SW_WRONG_DATA();
Expand Down
2 changes: 1 addition & 1 deletion src/hsm/cmd_delete_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int cmd_delete_file() {
}
}
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))) {
return SW_FILE_NOT_FOUND();
}
Expand Down
58 changes: 38 additions & 20 deletions src/hsm/cmd_extras.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "mbedtls/ecdh.h"
#ifdef PICO_PLATFORM
#include "pico/aon_timer.h"
#include "hardware/watchdog.h"
#else
#include <sys/time.h>
#include <time.h>
Expand All @@ -35,25 +36,28 @@
#define CMD_DATETIME 0xA
#define CMD_DYNOPS 0x6
#define CMD_SECURE_LOCK 0x3A
#define CMD_REBOOT 0xFB
#define SECURE_LOCK_KEY_AGREEMENT 0x1
#define SECURE_LOCK_ENABLE 0x2
#define SECURE_LOCK_MASK 0x3
#define SECURE_LOCK_DISABLE 0x4
#define CMD_PHY 0x1B
#define CMD_OTP 0x4C
#define CMD_MEMORY 0x5

int cmd_extras() {
int cmd = P1(apdu);
#ifndef ENABLE_EMULATION
// 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();
}
#endif
//check button (if enabled)
if (wait_button_pressed() == true) {
return SW_SECURE_MESSAGE_EXEC_ERROR();
}
if (P1(apdu) == CMD_DATETIME) { //datetime operations
if (cmd == CMD_DATETIME) { //datetime operations
if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2();
}
Expand All @@ -66,8 +70,7 @@ int cmd_extras() {
gettimeofday(&tv, NULL);
#endif
struct tm *tm = localtime(&tv.tv_sec);
res_APDU[res_APDU_size++] = (tm->tm_year + 1900) >> 8;
res_APDU[res_APDU_size++] = (tm->tm_year + 1900) & 0xff;
res_APDU_size += put_uint16_t_be(tm->tm_year + 1900, res_APDU);
res_APDU[res_APDU_size++] = tm->tm_mon;
res_APDU[res_APDU_size++] = tm->tm_mday;
res_APDU[res_APDU_size++] = tm->tm_wday;
Expand All @@ -80,7 +83,7 @@ int cmd_extras() {
return SW_WRONG_LENGTH();
}
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_mday = apdu.data[3];
tm.tm_wday = apdu.data[4];
Expand All @@ -97,7 +100,7 @@ int cmd_extras() {
#endif
}
}
else if (P1(apdu) == CMD_DYNOPS) { //dynamic options
else if (cmd == CMD_DYNOPS) { //dynamic options
if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2();
}
Expand All @@ -106,8 +109,7 @@ int cmd_extras() {
}
uint16_t opts = get_device_options();
if (apdu.nc == 0) {
res_APDU[res_APDU_size++] = opts >> 8;
res_APDU[res_APDU_size++] = opts & 0xff;
res_APDU_size += put_uint16_t_be(opts, res_APDU);
}
else {
uint8_t newopts[] = { apdu.data[0], (opts & 0xff) };
Expand All @@ -116,7 +118,7 @@ int cmd_extras() {
low_flash_available();
}
}
else if (P1(apdu) == CMD_SECURE_LOCK) { // secure lock
else if (cmd == CMD_SECURE_LOCK) { // secure lock
if (apdu.nc == 0) {
return SW_WRONG_LENGTH();
}
Expand Down Expand Up @@ -148,7 +150,7 @@ int cmd_extras() {
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);
if (ret != 0) {
return SW_EXEC_ERROR();
Expand All @@ -160,13 +162,12 @@ int cmd_extras() {
if (mse.init == false) {
return SW_COMMAND_NOT_ALLOWED();
}

uint16_t opts = get_device_options();
int ret = mse_decrypt_ct(apdu.data, apdu.nc);
if (ret != 0) {
return SW_WRONG_DATA();
}
if (P2(apdu) == SECURE_LOCK_ENABLE || P2(apdu) == SECURE_LOCK_DISABLE) { // Enable
uint16_t opts = get_device_options();
uint8_t newopts[] = { opts >> 8, (opts & 0xff) };
if ((P2(apdu) == SECURE_LOCK_ENABLE && !(opts & HSM_OPT_SECURE_LOCK)) ||
(P2(apdu) == SECURE_LOCK_DISABLE && (opts & HSM_OPT_SECURE_LOCK))) {
Expand Down Expand Up @@ -194,14 +195,14 @@ int cmd_extras() {
file_put_data(tf, newopts, sizeof(newopts));
low_flash_available();
}
else if (P2(apdu) == SECURE_LOCK_MASK) {
memcpy(mkek_mask, apdu.data, apdu.nc);
else if (P2(apdu) == SECURE_LOCK_MASK && (opts & HSM_OPT_SECURE_LOCK)) {
memcpy(mkek_mask, apdu.data, MKEK_KEY_SIZE);
has_mkek_mask = true;
}
}
}
#ifndef ENABLE_EMULATION
else if (P1(apdu) == CMD_PHY) { // Set PHY
else if (cmd == CMD_PHY) { // Set PHY
if (apdu.nc == 0) {
if (file_has_data(ef_phy)) {
res_APDU_size = file_get_size(ef_phy);
Expand All @@ -213,8 +214,8 @@ int cmd_extras() {
if (apdu.nc != 4) {
return SW_WRONG_LENGTH();
}
phy_data.vid = (apdu.data[0] << 8) | apdu.data[1];
phy_data.pid = (apdu.data[2] << 8) | apdu.data[3];
phy_data.vid = get_uint16_t_be(apdu.data);
phy_data.pid = get_uint16_t_be(apdu.data + 2);
phy_data.vidpid_present = true;
}
else if (P2(apdu) == PHY_LED_GPIO) {
Expand All @@ -229,7 +230,7 @@ int cmd_extras() {
if (apdu.nc != 2) {
return SW_WRONG_LENGTH();
}
phy_data.opts = (apdu.data[0] << 8) | apdu.data[1];
phy_data.opts = get_uint16_t_be(apdu.data);
}
else {
return SW_INCORRECT_P1P2();
Expand All @@ -246,11 +247,11 @@ int cmd_extras() {
}
#endif
#if PICO_RP2350
else if (P1(apdu) == CMD_OTP) {
else if (cmd == CMD_OTP) {
if (apdu.nc < 2) {
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;
if (apdu.nc == 2) {
if (row > 0xbf && row < 0xf48) {
Expand Down Expand Up @@ -288,6 +289,23 @@ int cmd_extras() {
}
}
#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 {
return SW_INCORRECT_P1P2();
}
Expand Down
17 changes: 9 additions & 8 deletions src/hsm/cmd_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,14 @@ extern void reset_puk_store();
int cmd_initialize() {
if (apdu.nc > 0) {
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
initialize_flash(true);
scan_all();
has_session_pin = has_session_sopin = false;
has_session_pin = has_session_sopin = has_mkek_mask = false;
uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL;
uint16_t tag_len = 0;
Expand Down Expand Up @@ -206,7 +210,7 @@ int cmd_initialize() {
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, 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);
return SW_EXEC_ERROR();
}
Expand All @@ -218,7 +222,7 @@ int cmd_initialize() {
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);
return SW_EXEC_ERROR();
}
Expand All @@ -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",
*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);
ret = file_put_data(fpk, res_APDU, prkd_len);
}
Expand All @@ -243,10 +247,7 @@ int cmd_initialize() {
}
else { //free memory bytes request
int heap_left = heapLeft();
res_APDU[0] = ((heap_left >> 24) & 0xff);
res_APDU[1] = ((heap_left >> 16) & 0xff);
res_APDU[2] = ((heap_left >> 8) & 0xff);
res_APDU[3] = ((heap_left >> 0) & 0xff);
res_APDU_size += put_uint32_t_be(heap_left, res_APDU);
res_APDU[4] = 0;
res_APDU[5] = HSM_VERSION_MAJOR;
res_APDU[6] = HSM_VERSION_MINOR;
Expand Down
4 changes: 2 additions & 2 deletions src/hsm/cmd_key_unwrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ int cmd_key_unwrap() {
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, 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);
return SW_EXEC_ERROR();
}
Expand All @@ -77,7 +77,7 @@ int cmd_key_unwrap() {
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, 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);
return SW_EXEC_ERROR();
}
Expand Down
6 changes: 2 additions & 4 deletions src/hsm/cmd_keypair_gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ int cmd_keypair_gen() {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
if ((res_APDU_size =
(uint16_t)asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) {
if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, MAX_APDU_DATA, NULL, 0)) == 0) {
return SW_EXEC_ERROR();
}
ret = store_keys(&rsa, PICO_KEYS_KEY_RSA, key_id);
Expand Down Expand Up @@ -131,8 +130,7 @@ int cmd_keypair_gen() {
}
}
}
if ((res_APDU_size =
(uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext.data, ext.len)) == 0) {
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 (ext.data) {
free(ext.data);
}
Expand Down
6 changes: 2 additions & 4 deletions src/hsm/cmd_list_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ int cmd_list_keys() {
/* First we send DEV private key */
/* Both below conditions should be always TRUE */
if (search_file(EF_PRKD_DEV)) {
res_APDU[res_APDU_size++] = EF_PRKD_DEV >> 8;
res_APDU[res_APDU_size++] = EF_PRKD_DEV & 0xff;
res_APDU_size += put_uint16_t_be(EF_PRKD_DEV, res_APDU + res_APDU_size);
}
if (search_file(EF_KEY_DEV)) {
res_APDU[res_APDU_size++] = EF_KEY_DEV >> 8;
res_APDU[res_APDU_size++] = EF_KEY_DEV & 0xff;
res_APDU_size += put_uint16_t_be(EF_KEY_DEV, res_APDU + res_APDU_size);
}
//first CC
for (int i = 0; i < dynamic_files; i++) {
Expand Down
4 changes: 2 additions & 2 deletions src/hsm/cmd_read_binary.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int cmd_read_binary() {
offset = p2;
}
else {
offset = make_uint16_t(p1, p2) & 0x7fff;
offset = make_uint16_t_be(p1, p2) & 0x7fff;
ef = currentEF;
}
}
Expand All @@ -41,7 +41,7 @@ int cmd_read_binary() {
}
}
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) {
ef = currentEF;
}
Expand Down
Loading

0 comments on commit 4c636e0

Please sign in to comment.