Compare commits
79 Commits
v5.0
...
v5.4-eddsa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17ca65a41b | ||
|
|
92fe26c1e1 | ||
|
|
5c2dce9e52 | ||
|
|
1cbcfce23f | ||
|
|
1f3cecea8b | ||
|
|
ac8d05b9e9 | ||
|
|
e00e620264 | ||
|
|
64d8dafa2b | ||
|
|
0f3bb8242c | ||
|
|
747e5fbe86 | ||
|
|
8eb4669c0f | ||
|
|
4c636e0ce5 | ||
|
|
297f2e6228 | ||
|
|
12a26f8506 | ||
|
|
45a96f8742 | ||
|
|
ca2e04af53 | ||
|
|
f0a9d03ca8 | ||
|
|
2502f99aff | ||
|
|
71636f4d66 | ||
|
|
310bcb8092 | ||
|
|
6c5735fc4b | ||
|
|
3430655897 | ||
|
|
3d9e806409 | ||
|
|
ff8b343df4 | ||
|
|
0c6b0d295f | ||
|
|
c6b03e54ca | ||
|
|
991f5fc960 | ||
|
|
6d516b1b78 | ||
|
|
2a3ac550ec | ||
|
|
73232b6de4 | ||
|
|
d56b540324 | ||
|
|
74b635fa3c | ||
|
|
07d9e225d2 | ||
|
|
3d960b931a | ||
|
|
ff7ef56cda | ||
|
|
320455815f | ||
|
|
859dec7e4a | ||
|
|
053ccf4a89 | ||
|
|
f88aad1e2c | ||
|
|
866aac8fe3 | ||
|
|
a242a28394 | ||
|
|
c33ed9b968 | ||
|
|
65a4474dec | ||
|
|
e243def565 | ||
|
|
78bc34827e | ||
|
|
a69cb8a95a | ||
|
|
bb45c9b3a8 | ||
|
|
5535f3ec10 | ||
|
|
f992a04142 | ||
|
|
d858a1e1d5 | ||
|
|
f450279370 | ||
|
|
b571b0b945 | ||
|
|
7493f9eb3e | ||
|
|
d44b780970 | ||
|
|
e7080d6f82 | ||
|
|
9258c9ff70 | ||
|
|
ad18577e98 | ||
|
|
fb5be153ed | ||
|
|
0ac71f2fff | ||
|
|
6ec5235cc3 | ||
|
|
ff74d6306e | ||
|
|
ba562da00e | ||
|
|
b94810d31d | ||
|
|
2c4be41ecf | ||
|
|
447d223de4 | ||
|
|
4f9f7f14fe | ||
|
|
6699913eff | ||
|
|
b0057bc3fe | ||
|
|
e3a773d145 | ||
|
|
10a47f9177 | ||
|
|
9f49a144ac | ||
|
|
e67a7091ff | ||
|
|
5e801fbae7 | ||
|
|
5bdba8e1e8 | ||
|
|
5df4e62f81 | ||
|
|
faef2dc278 | ||
|
|
22d8793683 | ||
|
|
32c8bc4a24 | ||
|
|
b5174d64af |
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -13,10 +13,10 @@ name: "CodeQL"
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "master", "development" ]
|
branches: [ "master", "development", "development-eddsa" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: [ "master", "development" ]
|
branches: [ "master", "development", "development-eddsa" ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '23 5 * * 4'
|
- cron: '23 5 * * 4'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -36,7 +36,7 @@ jobs:
|
|||||||
language: [ 'cpp', 'python' ]
|
language: [ 'cpp', 'python' ]
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||||
mode: [ 'pico', 'esp32', 'local' ]
|
mode: [ 'pico', 'local' ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
|||||||
1
.github/workflows/nightly.yml
vendored
1
.github/workflows/nightly.yml
vendored
@@ -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:
|
||||||
|
|||||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -13,10 +13,10 @@ name: "Emulation and test"
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "master", "development" ]
|
branches: [ "master", "development", "development-eddsa" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: [ "master", "development" ]
|
branches: [ "master", "development", "development-eddsa" ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '23 5 * * 4'
|
- cron: '23 5 * * 4'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ if(ESP_PLATFORM)
|
|||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
else()
|
else()
|
||||||
if(NOT ENABLE_EMULATION)
|
if(NOT ENABLE_EMULATION)
|
||||||
|
set(PICO_USE_FASTEST_SUPPORTED_CLOCK 1)
|
||||||
include(pico_sdk_import.cmake)
|
include(pico_sdk_import.cmake)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -80,7 +81,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 +126,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()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
VERSION_MAJOR="5"
|
VERSION_MAJOR="5"
|
||||||
VERSION_MINOR="0"
|
VERSION_MINOR="4-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}"
|
||||||
@@ -11,98 +11,13 @@ rm -rf release/*
|
|||||||
mkdir -p build_release
|
mkdir -p build_release
|
||||||
mkdir -p release
|
mkdir -p release
|
||||||
cd build_release
|
cd build_release
|
||||||
|
PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}"
|
||||||
for board in 0xcb_helios \
|
board_dir=${PICO_SDK_PATH}/src/boards/include/boards
|
||||||
adafruit_feather_rp2040_usb_host \
|
for board in "$board_dir"/*
|
||||||
adafruit_feather_rp2040 \
|
|
||||||
adafruit_itsybitsy_rp2040 \
|
|
||||||
adafruit_kb2040 \
|
|
||||||
adafruit_macropad_rp2040 \
|
|
||||||
adafruit_qtpy_rp2040 \
|
|
||||||
adafruit_trinkey_qt2040 \
|
|
||||||
amethyst_fpga \
|
|
||||||
archi \
|
|
||||||
arduino_nano_rp2040_connect \
|
|
||||||
cytron_maker_pi_rp2040 \
|
|
||||||
datanoisetv_rp2040_dsp \
|
|
||||||
eetree_gamekit_rp2040 \
|
|
||||||
garatronic_pybstick26_rp2040 \
|
|
||||||
gen4_rp2350_24 \
|
|
||||||
gen4_rp2350_24ct \
|
|
||||||
gen4_rp2350_24t \
|
|
||||||
gen4_rp2350_28 \
|
|
||||||
gen4_rp2350_28ct \
|
|
||||||
gen4_rp2350_28t \
|
|
||||||
gen4_rp2350_32 \
|
|
||||||
gen4_rp2350_32ct \
|
|
||||||
gen4_rp2350_32t \
|
|
||||||
gen4_rp2350_35 \
|
|
||||||
gen4_rp2350_35ct \
|
|
||||||
gen4_rp2350_35t \
|
|
||||||
hellbender_2350A_devboard \
|
|
||||||
ilabs_challenger_rp2350_bconnect \
|
|
||||||
ilabs_challenger_rp2350_wifi_ble \
|
|
||||||
ilabs_opendec02 \
|
|
||||||
melopero_perpetuo_rp2350_lora \
|
|
||||||
melopero_shake_rp2040 \
|
|
||||||
metrotech_xerxes_rp2040 \
|
|
||||||
net8086_usb_interposer \
|
|
||||||
nullbits_bit_c_pro \
|
|
||||||
phyx_rick_tny_rp2350 \
|
|
||||||
pi-plates_micropi \
|
|
||||||
pico \
|
|
||||||
pico_w \
|
|
||||||
pico2 \
|
|
||||||
pimoroni_badger2040 \
|
|
||||||
pimoroni_interstate75 \
|
|
||||||
pimoroni_keybow2040 \
|
|
||||||
pimoroni_motor2040 \
|
|
||||||
pimoroni_pga2040 \
|
|
||||||
pimoroni_pga2350 \
|
|
||||||
pimoroni_pico_plus2_rp2350 \
|
|
||||||
pimoroni_picolipo_4mb \
|
|
||||||
pimoroni_picolipo_16mb \
|
|
||||||
pimoroni_picosystem \
|
|
||||||
pimoroni_plasma2040 \
|
|
||||||
pimoroni_plasma2350 \
|
|
||||||
pimoroni_servo2040 \
|
|
||||||
pimoroni_tiny2040 \
|
|
||||||
pimoroni_tiny2040_2mb \
|
|
||||||
pimoroni_tiny2350 \
|
|
||||||
pololu_3pi_2040_robot \
|
|
||||||
pololu_zumo_2040_robot \
|
|
||||||
seeed_xiao_rp2040 \
|
|
||||||
seeed_xiao_rp2350 \
|
|
||||||
solderparty_rp2040_stamp \
|
|
||||||
solderparty_rp2040_stamp_carrier \
|
|
||||||
solderparty_rp2040_stamp_round_carrier \
|
|
||||||
solderparty_rp2350_stamp_xl \
|
|
||||||
solderparty_rp2350_stamp \
|
|
||||||
sparkfun_micromod \
|
|
||||||
sparkfun_promicro \
|
|
||||||
sparkfun_promicro_rp2350 \
|
|
||||||
sparkfun_thingplus \
|
|
||||||
switchscience_picossci2_conta_base \
|
|
||||||
switchscience_picossci2_dev_board \
|
|
||||||
switchscience_picossci2_micro \
|
|
||||||
switchscience_picossci2_rp2350_breakout \
|
|
||||||
switchscience_picossci2_tiny \
|
|
||||||
tinycircuits_thumby_color_rp2350 \
|
|
||||||
vgaboard \
|
|
||||||
waveshare_rp2040_lcd_0.96 \
|
|
||||||
waveshare_rp2040_lcd_1.28 \
|
|
||||||
waveshare_rp2040_one \
|
|
||||||
waveshare_rp2040_plus_4mb \
|
|
||||||
waveshare_rp2040_plus_16mb \
|
|
||||||
waveshare_rp2040_zero \
|
|
||||||
weact_studio_rp2040_2mb \
|
|
||||||
weact_studio_rp2040_4mb \
|
|
||||||
weact_studio_rp2040_8mb \
|
|
||||||
weact_studio_rp2040_16mb \
|
|
||||||
wiznet_w5100s_evb_pico
|
|
||||||
do
|
do
|
||||||
|
board_name="$(basename -- $board .h)"
|
||||||
rm -rf *
|
rm -rf *
|
||||||
PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" cmake .. -DPICO_BOARD=$board
|
PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name
|
||||||
make -j`nproc`
|
make -j`nproc`
|
||||||
mv pico_hsm.uf2 ../release/pico_hsm_$board-$SUFFIX.uf2
|
mv pico_hsm.uf2 ../release/pico_hsm_$board_name-$SUFFIX.uf2
|
||||||
done
|
done
|
||||||
|
|||||||
Submodule pico-keys-sdk updated: 8c25e9be87...4120a8c1a6
@@ -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"
|
||||||
|
|||||||
@@ -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(¶ms,
|
int r = mbedtls_pkcs5_pbes2_ext(¶ms, 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();
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,13 +52,13 @@ int cmd_derive_asym() {
|
|||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
}
|
}
|
||||||
if (apdu.data[0] == ALGO_EC_DERIVE) {
|
if (apdu.data[0] == ALGO_EC_DERIVE) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecp_keypair ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecp_keypair_init(&ctx);
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
r = load_private_key_ecdsa(&ctx, fkey);
|
r = load_private_key_ec(&ctx, fkey);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
if (r == PICOKEY_VERIFICATION_FAILED) {
|
if (r == PICOKEY_VERIFICATION_FAILED) {
|
||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ int cmd_derive_asym() {
|
|||||||
mbedtls_mpi_init(&nd);
|
mbedtls_mpi_init(&nd);
|
||||||
r = mbedtls_mpi_read_binary(&a, apdu.data + 1, apdu.nc - 1);
|
r = mbedtls_mpi_read_binary(&a, apdu.data + 1, apdu.nc - 1);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
mbedtls_mpi_free(&a);
|
mbedtls_mpi_free(&a);
|
||||||
mbedtls_mpi_free(&nd);
|
mbedtls_mpi_free(&nd);
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
@@ -77,22 +77,22 @@ int cmd_derive_asym() {
|
|||||||
r = mbedtls_mpi_add_mod(&ctx.grp, &nd, &ctx.d, &a);
|
r = mbedtls_mpi_add_mod(&ctx.grp, &nd, &ctx.d, &a);
|
||||||
mbedtls_mpi_free(&a);
|
mbedtls_mpi_free(&a);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
mbedtls_mpi_free(&nd);
|
mbedtls_mpi_free(&nd);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
r = mbedtls_mpi_copy(&ctx.d, &nd);
|
r = mbedtls_mpi_copy(&ctx.d, &nd);
|
||||||
mbedtls_mpi_free(&nd);
|
mbedtls_mpi_free(&nd);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
r = store_keys(&ctx, PICO_KEYS_KEY_EC, dest_id);
|
r = store_keys(&ctx, PICO_KEYS_KEY_EC, dest_id);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
|
|||||||
@@ -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,28 +230,23 @@ 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();
|
||||||
}
|
}
|
||||||
uint8_t tmp[PHY_MAX_SIZE];
|
if (phy_save() != PICOKEY_OK) {
|
||||||
uint16_t tmp_len = 0;
|
|
||||||
memset(tmp, 0, sizeof(tmp));
|
|
||||||
if (phy_serialize_data(&phy_data, tmp, &tmp_len) != PICOKEY_OK) {
|
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
file_put_data(ef_phy, tmp, tmp_len);
|
|
||||||
low_flash_available();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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 +284,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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ int cmd_general_authenticate() {
|
|||||||
if (!fkey) {
|
if (!fkey) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
mbedtls_ecdsa_context ectx;
|
mbedtls_ecp_keypair ectx;
|
||||||
mbedtls_ecdsa_init(&ectx);
|
mbedtls_ecp_keypair_init(&ectx);
|
||||||
r = load_private_key_ecdsa(&ectx, fkey);
|
r = load_private_key_ecdh(&ectx, fkey);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ectx);
|
mbedtls_ecp_keypair_free(&ectx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
mbedtls_ecdh_context ctx;
|
mbedtls_ecdh_context ctx;
|
||||||
@@ -56,12 +56,12 @@ int cmd_general_authenticate() {
|
|||||||
mbedtls_ecp_group_id gid = MBEDTLS_ECP_DP_SECP256R1;
|
mbedtls_ecp_group_id gid = MBEDTLS_ECP_DP_SECP256R1;
|
||||||
r = mbedtls_ecdh_setup(&ctx, gid);
|
r = mbedtls_ecdh_setup(&ctx, gid);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(&ectx);
|
mbedtls_ecp_keypair_free(&ectx);
|
||||||
mbedtls_ecdh_free(&ctx);
|
mbedtls_ecdh_free(&ctx);
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
}
|
}
|
||||||
r = mbedtls_mpi_copy(&ctx.ctx.mbed_ecdh.d, &ectx.d);
|
r = mbedtls_mpi_copy(&ctx.ctx.mbed_ecdh.d, &ectx.d);
|
||||||
mbedtls_ecdsa_free(&ectx);
|
mbedtls_ecp_keypair_free(&ectx);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdh_free(&ctx);
|
mbedtls_ecdh_free(&ctx);
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
@@ -67,21 +67,21 @@ int cmd_key_unwrap() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (key_type & PICO_KEYS_KEY_EC) {
|
else if (key_type & PICO_KEYS_KEY_EC) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecp_keypair ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecp_keypair_init(&ctx);
|
||||||
do {
|
do {
|
||||||
r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len);
|
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);
|
} while ((r == PICOKEY_ERR_FILE_NOT_FOUND || r == PICOKEY_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
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_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,18 +71,18 @@ int cmd_key_wrap() {
|
|||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
}
|
}
|
||||||
else if (*dprkd == P15_KEYTYPE_ECC) {
|
else if (*dprkd == P15_KEYTYPE_ECC) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecp_keypair ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecp_keypair_init(&ctx);
|
||||||
r = load_private_key_ecdsa(&ctx, ef);
|
r = load_private_key_ec(&ctx, ef);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
if (r == PICOKEY_VERIFICATION_FAILED) {
|
if (r == PICOKEY_VERIFICATION_FAILED) {
|
||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
return SW_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, PICO_KEYS_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len);
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
}
|
}
|
||||||
else if (*dprkd == P15_KEYTYPE_AES) {
|
else if (*dprkd == P15_KEYTYPE_AES) {
|
||||||
uint8_t kdata_aes[64]; //maximum AES key size
|
uint8_t kdata_aes[64]; //maximum AES key size
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -79,6 +78,19 @@ int cmd_keypair_gen() {
|
|||||||
if (ec_id == MBEDTLS_ECP_DP_NONE) {
|
if (ec_id == MBEDTLS_ECP_DP_NONE) {
|
||||||
return SW_FUNC_NOT_SUPPORTED();
|
return SW_FUNC_NOT_SUPPORTED();
|
||||||
}
|
}
|
||||||
|
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 || ec_id == MBEDTLS_ECP_DP_CURVE448) {
|
||||||
|
asn1_ctx_t g = { 0 };
|
||||||
|
if (asn1_find_tag(&ctxo, 0x83, &g) != true) {
|
||||||
|
return SW_WRONG_DATA();
|
||||||
|
}
|
||||||
|
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && (g.data[0] != 9)) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED25519;
|
||||||
|
}
|
||||||
|
else if (ec_id == MBEDTLS_ECP_DP_CURVE448 && (g.len != 56 || g.data[0] != 5)) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED448;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("KEYPAIR ECC %d\r\n", ec_id);
|
||||||
mbedtls_ecdsa_context ecdsa;
|
mbedtls_ecdsa_context ecdsa;
|
||||||
mbedtls_ecdsa_init(&ecdsa);
|
mbedtls_ecdsa_init(&ecdsa);
|
||||||
uint8_t index = 0;
|
uint8_t index = 0;
|
||||||
@@ -118,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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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++) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
#include "mbedtls/oid.h"
|
#include "mbedtls/oid.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
#include "mbedtls/eddsa.h"
|
||||||
|
|
||||||
extern mbedtls_ecp_keypair hd_context;
|
extern mbedtls_ecp_keypair hd_context;
|
||||||
extern uint8_t hd_keytype;
|
extern uint8_t hd_keytype;
|
||||||
@@ -228,8 +229,8 @@ int cmd_signature() {
|
|||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
}
|
}
|
||||||
else if (p2 >= ALGO_EC_RAW && p2 <= ALGO_EC_SHA512) {
|
else if (p2 >= ALGO_EC_RAW && p2 <= ALGO_EC_SHA512) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecp_keypair ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecp_keypair_init(&ctx);
|
||||||
md = MBEDTLS_MD_SHA256;
|
md = MBEDTLS_MD_SHA256;
|
||||||
if (p2 == ALGO_EC_RAW) {
|
if (p2 == ALGO_EC_RAW) {
|
||||||
if (apdu.nc == 32) {
|
if (apdu.nc == 32) {
|
||||||
@@ -263,9 +264,9 @@ int cmd_signature() {
|
|||||||
else if (p2 == ALGO_EC_SHA512) {
|
else if (p2 == ALGO_EC_SHA512) {
|
||||||
md = MBEDTLS_MD_SHA512;
|
md = MBEDTLS_MD_SHA512;
|
||||||
}
|
}
|
||||||
int r = load_private_key_ecdsa(&ctx, fkey);
|
int r = load_private_key_ec(&ctx, fkey);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
if (r == PICOKEY_VERIFICATION_FAILED) {
|
if (r == PICOKEY_VERIFICATION_FAILED) {
|
||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
@@ -273,14 +274,20 @@ int cmd_signature() {
|
|||||||
}
|
}
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
||||||
if (mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN,
|
if (ctx.grp.id == MBEDTLS_ECP_DP_ED25519 || ctx.grp.id == MBEDTLS_ECP_DP_ED448) {
|
||||||
&olen, random_gen, NULL) != 0) {
|
r = mbedtls_eddsa_write_signature(&ctx, apdu.data, apdu.nc, buf, sizeof(buf), &olen, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
mbedtls_ecdsa_free(&ctx);
|
}
|
||||||
|
else {
|
||||||
|
r = mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN,
|
||||||
|
&olen, random_gen, NULL);
|
||||||
|
}
|
||||||
|
if (r != 0) {
|
||||||
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
memcpy(res_APDU, buf, olen);
|
memcpy(res_APDU, buf, olen);
|
||||||
res_APDU_size = (uint16_t)olen;
|
res_APDU_size = (uint16_t)olen;
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
}
|
}
|
||||||
else if (p2 == ALGO_HD) {
|
else if (p2 == ALGO_HD) {
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "oid.h"
|
#include "oid.h"
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
#include "mbedtls/eddsa.h"
|
||||||
|
|
||||||
extern const uint8_t *dev_name;
|
extern const uint8_t *dev_name;
|
||||||
extern uint16_t dev_name_len;
|
extern uint16_t dev_name_len;
|
||||||
@@ -71,7 +72,7 @@ const uint8_t *pointA[] = {
|
|||||||
"\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC",
|
"\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC",
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, uint16_t buf_len) {
|
uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecp_keypair *ecdsa, uint8_t *buf, uint16_t buf_len) {
|
||||||
uint8_t Y_buf[MBEDTLS_ECP_MAX_PT_LEN], G_buf[MBEDTLS_ECP_MAX_PT_LEN];
|
uint8_t Y_buf[MBEDTLS_ECP_MAX_PT_LEN], G_buf[MBEDTLS_ECP_MAX_PT_LEN];
|
||||||
const uint8_t oid_ecdsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x03 };
|
const uint8_t oid_ecdsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x03 };
|
||||||
const uint8_t oid_ri[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x05, 0x02, 0x03 };
|
const uint8_t oid_ri[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x05, 0x02, 0x03 };
|
||||||
@@ -88,7 +89,7 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, u
|
|||||||
uint16_t ctot_size = asn1_len_tag(0x87, (uint16_t)c_size);
|
uint16_t ctot_size = asn1_len_tag(0x87, (uint16_t)c_size);
|
||||||
uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa));
|
uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa));
|
||||||
uint16_t tot_len = 0, tot_data_len = 0;
|
uint16_t tot_len = 0, tot_data_len = 0;
|
||||||
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
|
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY || mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) {
|
||||||
tot_data_len = oid_len + ptot_size + otot_size + gtot_size + ytot_size;
|
tot_data_len = oid_len + ptot_size + otot_size + gtot_size + ytot_size;
|
||||||
oid = oid_ri;
|
oid = oid_ri;
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,7 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, u
|
|||||||
//oid
|
//oid
|
||||||
*p++ = 0x6; p += format_tlv_len(sizeof(oid_ecdsa), p); memcpy(p, oid, sizeof(oid_ecdsa));
|
*p++ = 0x6; p += format_tlv_len(sizeof(oid_ecdsa), p); memcpy(p, oid, sizeof(oid_ecdsa));
|
||||||
p += sizeof(oid_ecdsa);
|
p += sizeof(oid_ecdsa);
|
||||||
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
|
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY || mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) {
|
||||||
//p
|
//p
|
||||||
*p++ = 0x81; p += format_tlv_len((uint16_t)p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size);
|
*p++ = 0x81; p += format_tlv_len((uint16_t)p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size);
|
||||||
p += p_size;
|
p += p_size;
|
||||||
@@ -293,11 +294,15 @@ uint16_t asn1_cvc_cert(void *rsa_ecdsa,
|
|||||||
else if (key_type & PICO_KEYS_KEY_EC) {
|
else if (key_type & PICO_KEYS_KEY_EC) {
|
||||||
mbedtls_mpi r, s;
|
mbedtls_mpi r, s;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) rsa_ecdsa;
|
mbedtls_ecp_keypair *ecdsa = (mbedtls_ecp_keypair *) rsa_ecdsa;
|
||||||
mbedtls_mpi_init(&r);
|
mbedtls_mpi_init(&r);
|
||||||
mbedtls_mpi_init(&s);
|
mbedtls_mpi_init(&s);
|
||||||
ret =
|
if (ecdsa->grp.id == MBEDTLS_ECP_DP_ED25519 || ecdsa->grp.id == MBEDTLS_ECP_DP_ED448) {
|
||||||
mbedtls_ecdsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, hsh, sizeof(hsh), random_gen, NULL);
|
ret = mbedtls_eddsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, body, body_size, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = mbedtls_ecdsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, hsh, sizeof(hsh), random_gen, NULL);
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
mbedtls_mpi_write_binary(&r, p, key_size / 2); p += key_size / 2;
|
mbedtls_mpi_write_binary(&r, p, key_size / 2); p += key_size / 2;
|
||||||
mbedtls_mpi_write_binary(&s, p, key_size / 2); p += key_size / 2;
|
mbedtls_mpi_write_binary(&s, p, key_size / 2); p += key_size / 2;
|
||||||
@@ -326,10 +331,10 @@ uint16_t asn1_cvc_aut(void *rsa_ecdsa,
|
|||||||
if (!fkey) {
|
if (!fkey) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mbedtls_ecdsa_context ectx;
|
mbedtls_ecp_keypair ectx;
|
||||||
mbedtls_ecdsa_init(&ectx);
|
mbedtls_ecp_keypair_init(&ectx);
|
||||||
if (load_private_key_ecdsa(&ectx, fkey) != PICOKEY_OK) {
|
if (load_private_key_ec(&ectx, fkey) != PICOKEY_OK) {
|
||||||
mbedtls_ecdsa_free(&ectx);
|
mbedtls_ecp_keypair_free(&ectx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -349,15 +354,20 @@ uint16_t asn1_cvc_aut(void *rsa_ecdsa,
|
|||||||
p += asn1_cvc_cert(rsa_ecdsa, key_type, p, cvcert_size, ext, ext_len, false);
|
p += asn1_cvc_cert(rsa_ecdsa, key_type, p, cvcert_size, ext, ext_len, false);
|
||||||
//outcar
|
//outcar
|
||||||
*p++ = 0x42; p += format_tlv_len(outcar_len, p); memcpy(p, outcar, outcar_len); p += outcar_len;
|
*p++ = 0x42; p += format_tlv_len(outcar_len, p); memcpy(p, outcar, outcar_len); p += outcar_len;
|
||||||
uint8_t hsh[32];
|
|
||||||
memcpy(p, "\x5f\x37", 2); p += 2;
|
memcpy(p, "\x5f\x37", 2); p += 2;
|
||||||
p += format_tlv_len(key_size, p);
|
p += format_tlv_len(key_size, p);
|
||||||
hash256(body, cvcert_size + outcar_size, hsh);
|
|
||||||
mbedtls_mpi r, s;
|
mbedtls_mpi r, s;
|
||||||
mbedtls_mpi_init(&r);
|
mbedtls_mpi_init(&r);
|
||||||
mbedtls_mpi_init(&s);
|
mbedtls_mpi_init(&s);
|
||||||
ret = mbedtls_ecdsa_sign(&ectx.grp, &r, &s, &ectx.d, hsh, sizeof(hsh), random_gen, NULL);
|
if (ectx.grp.id == MBEDTLS_ECP_DP_ED25519 || ectx.grp.id == MBEDTLS_ECP_DP_ED448) {
|
||||||
mbedtls_ecdsa_free(&ectx);
|
ret = mbedtls_eddsa_sign(&ectx.grp, &r, &s, &ectx.d, body, cvcert_size + outcar_size, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t hsh[32];
|
||||||
|
hash256(body, cvcert_size + outcar_size, hsh);
|
||||||
|
ret = mbedtls_ecdsa_sign(&ectx.grp, &r, &s, &ectx.d, hsh, sizeof(hsh), random_gen, NULL);
|
||||||
|
}
|
||||||
|
mbedtls_ecp_keypair_free(&ectx);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mbedtls_mpi_free(&r);
|
mbedtls_mpi_free(&r);
|
||||||
mbedtls_mpi_free(&s);
|
mbedtls_mpi_free(&s);
|
||||||
@@ -421,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,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
|
||||||
@@ -518,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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
110
src/hsm/kek.c
110
src/hsm/kek.c
@@ -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,13 +660,20 @@ 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); ofs += len + 2;
|
len = get_uint16_t_be(kb + ofs);
|
||||||
|
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && kb[ofs + 2] != 0x09) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED25519;
|
||||||
|
}
|
||||||
|
else if (ec_id == MBEDTLS_ECP_DP_CURVE448 && (len != 56 || kb[ofs + 2] != 0x05)) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED448;
|
||||||
|
}
|
||||||
|
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);
|
||||||
@@ -663,10 +682,15 @@ 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) {
|
||||||
r = mbedtls_ecp_mul(&ecdsa->grp, &ecdsa->Q, &ecdsa->d, &ecdsa->grp.G, random_gen, NULL);
|
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) {
|
||||||
|
r = mbedtls_ecp_point_edwards(&ecdsa->grp, &ecdsa->Q, &ecdsa->d, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = mbedtls_ecp_mul(&ecdsa->grp, &ecdsa->Q, &ecdsa->d, &ecdsa->grp.G, random_gen, NULL);
|
||||||
|
}
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(ecdsa);
|
mbedtls_ecdsa_free(ecdsa);
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEY_EXEC_ERROR;
|
||||||
|
|||||||
@@ -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) {
|
||||||
@@ -666,7 +661,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
|||||||
return PICOKEY_OK;
|
return PICOKEY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
int load_private_key_ec(mbedtls_ecp_keypair *ctx, file_t *fkey) {
|
||||||
if (wait_button_pressed() == true) { // timeout
|
if (wait_button_pressed() == true) { // timeout
|
||||||
return PICOKEY_VERIFICATION_FAILED;
|
return PICOKEY_VERIFICATION_FAILED;
|
||||||
}
|
}
|
||||||
@@ -681,17 +676,25 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
|||||||
int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1);
|
int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
||||||
mbedtls_ecdsa_free(ctx);
|
mbedtls_ecp_keypair_free(ctx);
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEY_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
||||||
r = mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL);
|
if (gid == MBEDTLS_ECP_DP_ED25519 || gid == MBEDTLS_ECP_DP_ED448) {
|
||||||
|
r = mbedtls_ecp_point_edwards(&ctx->grp, &ctx->Q, &ctx->d, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL);
|
||||||
|
}
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(ctx);
|
mbedtls_ecp_keypair_free(ctx);
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEY_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEY_OK;
|
||||||
}
|
}
|
||||||
|
int load_private_key_ecdh(mbedtls_ecp_keypair *ctx, file_t *fkey) {
|
||||||
|
return load_private_key_ec(ctx, fkey);
|
||||||
|
}
|
||||||
|
|
||||||
#define INS_VERIFY 0x20
|
#define INS_VERIFY 0x20
|
||||||
#define INS_MSE 0x22
|
#define INS_MSE 0x22
|
||||||
|
|||||||
@@ -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[];
|
||||||
|
|
||||||
@@ -120,7 +123,8 @@ extern int delete_file(file_t *ef);
|
|||||||
extern const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, uint16_t *tag_len);
|
extern const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, uint16_t *tag_len);
|
||||||
extern bool key_has_purpose(file_t *ef, uint8_t purpose);
|
extern bool key_has_purpose(file_t *ef, uint8_t purpose);
|
||||||
extern int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey);
|
extern int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey);
|
||||||
extern int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey);
|
extern int load_private_key_ec(mbedtls_ecp_keypair *ctx, file_t *fkey);
|
||||||
|
extern int load_private_key_ecdh(mbedtls_ecp_keypair *ctx, file_t *fkey);
|
||||||
extern bool wait_button_pressed();
|
extern bool wait_button_pressed();
|
||||||
extern int store_keys(void *key_ctx, int type, uint8_t key_id);
|
extern int store_keys(void *key_ctx, int type, uint8_t key_id);
|
||||||
extern int find_and_store_meta_key(uint8_t key_id);
|
extern int find_and_store_meta_key(uint8_t key_id);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#ifndef __VERSION_H_
|
#ifndef __VERSION_H_
|
||||||
#define __VERSION_H_
|
#define __VERSION_H_
|
||||||
|
|
||||||
#define HSM_VERSION 0x0500
|
#define HSM_VERSION 0x0504
|
||||||
|
|
||||||
#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.
@@ -24,7 +24,7 @@ def test_gen_initialize(device):
|
|||||||
device.initialize()
|
device.initialize()
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"curve", ['secp192r1', 'secp256r1', 'secp384r1', 'secp521r1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1', 'secp192k1', 'secp256k1', 'curve25519', 'curve448']
|
"curve", ['secp192r1', 'secp256r1', 'secp384r1', 'secp521r1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1', 'secp192k1', 'secp256k1', 'curve25519', 'curve448', 'ed25519', 'ed448']
|
||||||
)
|
)
|
||||||
def test_gen_ecc(device, curve):
|
def test_gen_ecc(device, curve):
|
||||||
keyid = device.key_generation(KeyType.ECC, curve)
|
keyid = device.key_generation(KeyType.ECC, curve)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import pytest
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
from picohsm import DOPrefixes
|
from picohsm import DOPrefixes
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa, ec, x25519, x448
|
from cryptography.hazmat.primitives.asymmetric import rsa, ec, x25519, x448, ed25519, ed448
|
||||||
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
||||||
from picohsm.const import DEFAULT_RETRIES, DEFAULT_DKEK_SHARES
|
from picohsm.const import DEFAULT_RETRIES, DEFAULT_DKEK_SHARES
|
||||||
from const import DEFAULT_DKEK
|
from const import DEFAULT_DKEK
|
||||||
@@ -70,6 +70,17 @@ def test_import_montgomery(device, curve):
|
|||||||
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
device.delete_file(DOPrefixes.EE_CERTIFICATE_PREFIX, keyid)
|
device.delete_file(DOPrefixes.EE_CERTIFICATE_PREFIX, keyid)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"curve", [ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey]
|
||||||
|
)
|
||||||
|
def test_import_edwards(device, curve):
|
||||||
|
pkey = curve.generate()
|
||||||
|
keyid = device.import_key(pkey)
|
||||||
|
pubkey = device.public_key(keyid, param=curve)
|
||||||
|
assert(pubkey.public_bytes(Encoding.Raw, PublicFormat.Raw) == pkey.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw))
|
||||||
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
|
device.delete_file(DOPrefixes.EE_CERTIFICATE_PREFIX, keyid)
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"size", [128, 192, 256]
|
"size", [128, 192, 256]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -55,3 +55,12 @@ def test_signature_rsa(device, modulus, scheme):
|
|||||||
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
device.verify(pubkey, data, signature, scheme)
|
device.verify(pubkey, data, signature, scheme)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"curve", ['ed25519', 'ed448']
|
||||||
|
)
|
||||||
|
def test_signature_edwards(device, curve):
|
||||||
|
keyid = device.key_generation(KeyType.ECC, curve)
|
||||||
|
pubkey = device.public_key(keyid=keyid)
|
||||||
|
signature = device.sign(keyid=keyid, scheme=Algorithm.ALGO_EC_RAW, data=data)
|
||||||
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
|
device.verify(pubkey, data, signature)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ def parse_args():
|
|||||||
parser_keygen_aes.add_argument('--size', help='Specifies the size of AES key [128, 192 or 256]', choices=[128, 192, 256], default=128, type=int)
|
parser_keygen_aes.add_argument('--size', help='Specifies the size of AES key [128, 192 or 256]', choices=[128, 192, 256], default=128, type=int)
|
||||||
parser_keygen_x25519 = subparser_keygen.add_parser('x25519', help='Generates a private X25519 keypair.')
|
parser_keygen_x25519 = subparser_keygen.add_parser('x25519', help='Generates a private X25519 keypair.')
|
||||||
parser_keygen_x448 = subparser_keygen.add_parser('x448', help='Generates a private X448 keypair.')
|
parser_keygen_x448 = subparser_keygen.add_parser('x448', help='Generates a private X448 keypair.')
|
||||||
|
parser_keygen_x25519 = subparser_keygen.add_parser('ed25519', help='Generates a private Ed25519 keypair.')
|
||||||
|
parser_keygen_x448 = subparser_keygen.add_parser('ed448', help='Generates a private Ed448 keypair.')
|
||||||
|
|
||||||
parser_otp = subparser.add_parser('otp', help='Read/write OTP values.')
|
parser_otp = subparser.add_parser('otp', help='Read/write OTP values.')
|
||||||
parser_otp.add_argument('subcommand', choices=['read', 'write', 'secure_boot'], help='Read, write or enable Secure Boot', nargs='?')
|
parser_otp.add_argument('subcommand', choices=['read', 'write', 'secure_boot'], help='Read, write or enable Secure Boot', nargs='?')
|
||||||
@@ -149,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
|
||||||
|
|
||||||
@@ -367,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)
|
||||||
@@ -465,8 +471,10 @@ def cipher(picohsm, args):
|
|||||||
def keygen(picohsm, args):
|
def keygen(picohsm, args):
|
||||||
if (args.subcommand == 'aes'):
|
if (args.subcommand == 'aes'):
|
||||||
ret = picohsm.key_generation(KeyType.AES, param=args.size)
|
ret = picohsm.key_generation(KeyType.AES, param=args.size)
|
||||||
elif (args.subcommand in ['x25519', 'x448']):
|
elif (args.subcommand in ['x25519', 'x448', 'ed25519', 'ed448']):
|
||||||
curve = 'curve' + args.subcommand[1:]
|
curve = args.subcommand
|
||||||
|
if (args.subcommand in ['x25519', 'x448']):
|
||||||
|
curve = 'curve' + args.subcommand[1:]
|
||||||
ret = picohsm.key_generation(KeyType.ECC, curve)
|
ret = picohsm.key_generation(KeyType.ECC, curve)
|
||||||
print('Key generated successfully.')
|
print('Key generated successfully.')
|
||||||
print(f'Key ID: {ret}')
|
print(f'Key ID: {ret}')
|
||||||
@@ -507,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')
|
||||||
@@ -537,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()
|
||||||
|
|||||||
@@ -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.1
|
||||||
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,20 @@ 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 ..
|
||||||
|
cd esp-idf
|
||||||
|
./install.sh esp32s2
|
||||||
|
. ./export.sh
|
||||||
|
cd ..
|
||||||
|
idf.py set-target esp32s2
|
||||||
|
idf.py all
|
||||||
|
mkdir -p release
|
||||||
|
cd build
|
||||||
|
esptool.py --chip ESP32-S2 merge_bin -o ../release/pico_hsm_esp32-s2.bin @flash_args
|
||||||
|
cd ..
|
||||||
else
|
else
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
|||||||
Reference in New Issue
Block a user