diff --git a/.gitmodules b/.gitmodules index b28b159..8fde71a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "tinycbor"] path = tinycbor url = https://github.com/intel/tinycbor.git +[submodule "mlkem"] + path = mlkem + url = https://github.com/pq-code-package/mlkem-native/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 0adf96b..42e9437 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ else() include(pico_sdk_import.cmake) endif() - project(picokey C CXX ASM) + project(pico_rescue C CXX ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) @@ -38,7 +38,7 @@ else() add_definitions(-D__FOR_CI) endif() - add_executable(picokey) + add_executable(pico_rescue) endif() set(USB_ITF_CCID 1) @@ -53,48 +53,48 @@ set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/version.c ) -SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/pico_keys_version.h" 2) +SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/pico_keys_version.h" 3) if(ESP_PLATFORM) - project(picokey) + project(pico_rescue) endif() if(NOT ESP_PLATFORM) - target_sources(picokey PUBLIC ${SOURCES}) - target_include_directories(picokey PUBLIC ${INCLUDES}) + target_sources(pico_rescue PUBLIC ${SOURCES}) + target_include_directories(pico_rescue PUBLIC ${INCLUDES}) - target_compile_options(picokey PUBLIC + target_compile_options(pico_rescue PUBLIC -Wall ) if(NOT MSVC) - target_compile_options(picokey PUBLIC + target_compile_options(pico_rescue PUBLIC -Werror ) endif() if(ENABLE_EMULATION) if(NOT MSVC) - target_compile_options(picokey PUBLIC + target_compile_options(pico_rescue PUBLIC -fdata-sections -ffunction-sections ) endif() if(APPLE) - target_link_options(picokey PUBLIC + target_link_options(pico_rescue PUBLIC -Wl,-dead_strip ) elseif(MSVC) - target_compile_options(picokey PUBLIC + target_compile_options(pico_rescue PUBLIC -WX ) - target_link_libraries(picokey PUBLIC wsock32 ws2_32 Bcrypt) + target_link_libraries(pico_rescue PUBLIC wsock32 ws2_32 Bcrypt) else() - target_link_options(picokey PUBLIC + target_link_options(pico_rescue PUBLIC -Wl,--gc-sections ) endif(APPLE) - target_link_libraries(picokey PRIVATE pthread m) + target_link_libraries(pico_rescue PRIVATE pthread m) else() pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) endif() diff --git a/LICENSE b/LICENSE index bae94e1..714397f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,23 @@ +Unless stated otherwise at the top of a file, all the files of this +project are licensed under the GNU Affero General Public License v3 +(AGPLv3). The full text of this license is reproduced at the bottom of +this document. +The copyright holders are indicated at the top of each file. + +The project is using the following libraries, sdk or portions of code: +- mdebtls, licensed under Apache-2.0 and GPL-2.0-or-later licenses, + https://github.com/Mbed-TLS/mbedtls +- tinyUSB, licensed under the MIT License, + https://github.com/hathach/tinyusb +- tinycbor, licensed under the MIT license, + https://github.com/intel/tinycbor +- mlkem-native, the Apache-2.0 license OR the ISC license OR the MIT + license, https://github.com/pq-code-package/mlkem-native +- USB CCID from Raspberry Pi (Trading) Ltd, licensed under the BSD + license, + +________________________________________________________________________ + GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 @@ -658,4 +678,4 @@ specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see -. \ No newline at end of file +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2bf33f --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Pico Keys SDK +This is a fork of the community edition of the project located at https://github.com/polhenarejos/pico-keys-sdk + +For licensing information and credits, see the LICENSE file diff --git a/config/esp32/components/mlkem1024/CMakeLists.txt b/config/esp32/components/mlkem1024/CMakeLists.txt new file mode 100644 index 0000000..22033d4 --- /dev/null +++ b/config/esp32/components/mlkem1024/CMakeLists.txt @@ -0,0 +1,23 @@ +set(MLKEM_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../mlkem/mlkem) + +file(GLOB_RECURSE MLKEM_SOURCES + ${MLKEM_DIR}/src/*.c +) +list(FILTER MLKEM_SOURCES EXCLUDE REGEX "/native/") + +idf_component_register( + SRCS ${MLKEM_SOURCES} + INCLUDE_DIRS ${MLKEM_DIR} +) + +target_compile_definitions(${COMPONENT_LIB} PRIVATE + MLK_CONFIG_PARAMETER_SET=1024 + MLK_CONFIG_MULTILEVEL_NO_SHARED + MLK_CONFIG_NAMESPACE_PREFIX=mlkem +) + +target_compile_options(${COMPONENT_LIB} PRIVATE + -O2 + -fno-builtin + -fno-strict-aliasing +) diff --git a/config/esp32/components/mlkem512/CMakeLists.txt b/config/esp32/components/mlkem512/CMakeLists.txt new file mode 100644 index 0000000..65357c5 --- /dev/null +++ b/config/esp32/components/mlkem512/CMakeLists.txt @@ -0,0 +1,23 @@ +set(MLKEM_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../mlkem/mlkem) + +file(GLOB_RECURSE MLKEM_SOURCES + ${MLKEM_DIR}/src/*.c +) +list(FILTER MLKEM_SOURCES EXCLUDE REGEX "/native/") + +idf_component_register( + SRCS ${MLKEM_SOURCES} + INCLUDE_DIRS ${MLKEM_DIR} +) + +target_compile_definitions(${COMPONENT_LIB} PRIVATE + MLK_CONFIG_PARAMETER_SET=512 + MLK_CONFIG_MULTILEVEL_WITH_SHARED + MLK_CONFIG_NAMESPACE_PREFIX=mlkem +) + +target_compile_options(${COMPONENT_LIB} PRIVATE + -O2 + -fno-builtin + -fno-strict-aliasing +) diff --git a/config/esp32/components/mlkem768/CMakeLists.txt b/config/esp32/components/mlkem768/CMakeLists.txt new file mode 100644 index 0000000..0085303 --- /dev/null +++ b/config/esp32/components/mlkem768/CMakeLists.txt @@ -0,0 +1,23 @@ +set(MLKEM_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../mlkem/mlkem) + +file(GLOB_RECURSE MLKEM_SOURCES + ${MLKEM_DIR}/src/*.c +) +list(FILTER MLKEM_SOURCES EXCLUDE REGEX "/native/") + +idf_component_register( + SRCS ${MLKEM_SOURCES} + INCLUDE_DIRS ${MLKEM_DIR} +) + +target_compile_definitions(${COMPONENT_LIB} PRIVATE + MLK_CONFIG_PARAMETER_SET=768 + MLK_CONFIG_MULTILEVEL_NO_SHARED + MLK_CONFIG_NAMESPACE_PREFIX=mlkem +) + +target_compile_options(${COMPONENT_LIB} PRIVATE + -O2 + -fno-builtin + -fno-strict-aliasing +) diff --git a/config/esp32/components/pico-keys-sdk/CMakeLists.txt b/config/esp32/components/pico-keys-sdk/CMakeLists.txt new file mode 100755 index 0000000..653fd87 --- /dev/null +++ b/config/esp32/components/pico-keys-sdk/CMakeLists.txt @@ -0,0 +1,7 @@ +set(PICO_KEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..) +idf_component_register( + SRCS ${PICO_KEYS_SOURCES} + INCLUDE_DIRS ${PICO_KEYS_SDK_DIR}/src ${PICO_KEYS_SDK_DIR}/src/fs ${PICO_KEYS_SDK_DIR}/src/rng ${PICO_KEYS_SDK_DIR}/src/usb ${PICO_KEYS_SDK_DIR}/src/led ${PICO_KEYS_SDK_DIR}/tinycbor/src ${PICO_KEYS_SDK_DIR}/mlkem/mlkem ${PICO_KEYS_SDK_DIR}/config/mlkem + REQUIRES bootloader_support esp_partition esp_tinyusb efuse mbedtls mlkem512 mlkem768 mlkem1024 tinycbor +) +idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/src/idf_component.yml b/config/esp32/components/pico-keys-sdk/idf_component.yml similarity index 100% rename from src/idf_component.yml rename to config/esp32/components/pico-keys-sdk/idf_component.yml diff --git a/config/esp32/components/tinycbor/CMakeLists.txt b/config/esp32/components/tinycbor/CMakeLists.txt new file mode 100755 index 0000000..76ecf22 --- /dev/null +++ b/config/esp32/components/tinycbor/CMakeLists.txt @@ -0,0 +1,6 @@ +set(PICO_KEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..) +idf_component_register( + SRCS ${CBOR_SOURCES} + INCLUDE_DIRS ${PICO_KEYS_SDK_DIR}/tinycbor/src +) +idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/config/mbedtls_config.h b/config/mbedtls_config.h index 0311975..6da7bd8 100644 --- a/config/mbedtls_config.h +++ b/config/mbedtls_config.h @@ -330,7 +330,7 @@ //#define MBEDTLS_RSA_ALT //#define MBEDTLS_SHA1_ALT #ifdef PICO_RP2350 -#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA256_ALT #endif //#define MBEDTLS_SHA512_ALT diff --git a/config/mlkem/mlkem_native_all.h b/config/mlkem/mlkem_native_all.h new file mode 100644 index 0000000..5fb5ba5 --- /dev/null +++ b/config/mlkem/mlkem_native_all.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#if !defined(MLK_ALL_H) +#define MLK_ALL_H + +/* API for MLKEM-512 */ +#define MLK_CONFIG_PARAMETER_SET 512 +#include "mlkem_native.h" +#undef MLK_CONFIG_PARAMETER_SET +#undef MLK_H + +/* API for MLKEM-768 */ +#define MLK_CONFIG_PARAMETER_SET 768 +#include "mlkem_native.h" +#undef MLK_CONFIG_PARAMETER_SET +#undef MLK_H + +/* API for MLKEM-1024 */ +#define MLK_CONFIG_PARAMETER_SET 1024 +#include "mlkem_native.h" +#undef MLK_CONFIG_PARAMETER_SET +#undef MLK_H + +#endif /* !MLK_ALL_H */ diff --git a/config/mlkem/mlkem_native_config.h b/config/mlkem/mlkem_native_config.h new file mode 100644 index 0000000..b75c37a --- /dev/null +++ b/config/mlkem/mlkem_native_config.h @@ -0,0 +1,13 @@ +#pragma once + +/* Disable all native/asm backends */ +#define MLK_NO_NATIVE_BACKENDS 1 + +/* No CBMC */ +#undef CBMC + +/* Platform characteristics */ +#define MLK_LITTLE_ENDIAN 1 + +/* Memory model */ +#define MLK_NO_MALLOC 1 diff --git a/config/rp2350/alt/sha256_alt.c b/config/rp2350/alt/sha256_alt.c index 17f5517..82bcd4d 100644 --- a/config/rp2350/alt/sha256_alt.c +++ b/config/rp2350/alt/sha256_alt.c @@ -286,3 +286,9 @@ int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char *output) { } return 0; } + +void mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + *dst = *src; +} diff --git a/config/rp2350/alt/sha256_alt.h b/config/rp2350/alt/sha256_alt.h index 0e1ada4..d480ce6 100644 --- a/config/rp2350/alt/sha256_alt.h +++ b/config/rp2350/alt/sha256_alt.h @@ -18,7 +18,6 @@ #ifndef _SHA256_ALT_H_ #define _SHA256_ALT_H_ -#include "pico_keys.h" #include "pico/sha256.h" typedef struct mbedtls_sha256_context { diff --git a/config/rp2350/pt.json b/config/rp2350/pt.json index a6cf59f..48acfc5 100644 --- a/config/rp2350/pt.json +++ b/config/rp2350/pt.json @@ -10,7 +10,7 @@ }, "partitions": [ { - "name": "Pico Keys Firmware", + "name": "PicoKeys Firmware", "id": 0, "start": 0, "size": "1024K", @@ -22,10 +22,10 @@ } }, { - "name": "Pico Keys Data", + "name": "PicoKeys Data", "id": 1, - "start": "1024K", - "size": "3072K", + "start": "1032K", + "size": "3064K", "families": ["data"], "permissions": { "secure": "rw", @@ -35,6 +35,21 @@ "link": ["owner", 0], "ignored_during_arm_boot": true, "ignored_during_riscv_boot": true + }, + { + "name": "PicoKeys Binding", + "id": 2, + "start": "1024K", + "size": "8K", + "families": ["data"], + "permissions": { + "secure": "r", + "nonsecure": "", + "bootloader": "w" + }, + "link": ["owner", 0], + "ignored_during_arm_boot": true, + "ignored_during_riscv_boot": true } ] } diff --git a/mlkem b/mlkem new file mode 160000 index 0000000..1453da5 --- /dev/null +++ b/mlkem @@ -0,0 +1 @@ +Subproject commit 1453da5cd11ea6be7ae83d619d1a72b21e48ec7d diff --git a/pico_keys_sdk_import.cmake b/pico_keys_sdk_import.cmake index 346febf..d1df2e0 100644 --- a/pico_keys_sdk_import.cmake +++ b/pico_keys_sdk_import.cmake @@ -64,12 +64,12 @@ if(ESP_PLATFORM) endif() if(NOT DEFINED USB_VID) - set(USB_VID 0xFEFF) + set(USB_VID 0x1D50) endif() add_definitions(-DUSB_VID=${USB_VID}) if(NOT DEFINED USB_PID) - set(USB_PID 0xFCFD) + set(USB_PID 0x619B) endif() add_definitions(-DUSB_PID=${USB_PID}) @@ -126,7 +126,7 @@ if(NOT ESP_PLATFORM) ) if(ENABLE_EDDSA) - set(MBEDTLS_ORIGIN "https://github.com/polhenarejos/mbedtls.git") + set(MBEDTLS_ORIGIN "https://github.com/librekeys/mbedtls.git") set(MBEDTLS_REF "mbedtls-3.6-eddsa") execute_process( @@ -213,6 +213,14 @@ if(NOT ESP_PLATFORM) endif() endif(NOT ESP_PLATFORM) +option(ENABLE_PQC "Enable/disable PQC support" OFF) +if(ENABLE_PQC) + message(STATUS "PQC support:\t\t\t enabled") + add_definitions(-DENABLE_PQC) +else() + message(STATUS "PQC support:\t\t\t disabled") +endif(ENABLE_PQC) + set(MBEDTLS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aes.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/asn1parse.c @@ -245,9 +253,12 @@ set(MBEDTLS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/poly1305.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ripemd160.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/des.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write_crt.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509_create.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write_csr.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/base64.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pem.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk_wrap.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkwrite.c @@ -260,6 +271,54 @@ if (ENABLE_EDDSA) ) endif() +if(ENABLE_PQC) +if (NOT ESP_PLATFORM) + file(GLOB_RECURSE MLKEM_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/mlkem/mlkem/src/*.c + ) + list(FILTER MLKEM_SOURCES EXCLUDE REGEX "/native/") + + add_library(mlkem512 STATIC ${MLKEM_SOURCES}) + target_include_directories(mlkem512 PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/mlkem/mlkem/src + ${CMAKE_CURRENT_LIST_DIR}/config/mlkem + ) + target_compile_definitions(mlkem512 PRIVATE + MLK_CONFIG_PARAMETER_SET=512 + MLK_CONFIG_MULTILEVEL_WITH_SHARED + MLK_CONFIG_NAMESPACE_PREFIX=mlkem + ) + + add_library(mlkem768 STATIC ${MLKEM_SOURCES}) + target_include_directories(mlkem768 PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/mlkem/mlkem/src + ${CMAKE_CURRENT_LIST_DIR}/config/mlkem + ) + target_compile_definitions(mlkem768 PRIVATE + MLK_CONFIG_PARAMETER_SET=768 + MLK_CONFIG_MULTILEVEL_NO_SHARED + MLK_CONFIG_NAMESPACE_PREFIX=mlkem + ) + + add_library(mlkem1024 STATIC ${MLKEM_SOURCES}) + target_include_directories(mlkem1024 PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/mlkem/mlkem/src + ${CMAKE_CURRENT_LIST_DIR}/config/mlkem + ) + target_compile_definitions(mlkem1024 PRIVATE + MLK_CONFIG_PARAMETER_SET=1024 + MLK_CONFIG_MULTILEVEL_NO_SHARED + MLK_CONFIG_NAMESPACE_PREFIX=mlkem + ) +endif() + + set(INCLUDES ${INCLUDES} + ${CMAKE_CURRENT_LIST_DIR}/mlkem/mlkem + ${CMAKE_CURRENT_LIST_DIR}/config/mlkem + ) + add_definitions(-DMLK_CONFIG_NAMESPACE_PREFIX=mlkem -DMLK_CONFIG_MULTILEVEL_BUILD=1) +endif() + set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/main.c ${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c @@ -318,6 +377,9 @@ if(USB_ITF_HID) ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk_wrap.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkwrite.c ) + +endif() + set(CBOR_SOURCES ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborencoder.c ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborparser.c @@ -327,19 +389,41 @@ if(USB_ITF_HID) set(INCLUDES ${INCLUDES} ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src ) +set(LIBRARIES + mbedtls +) + +if (NOT ESP_PLATFORM) + add_library(mbedtls STATIC ${MBEDTLS_SOURCES}) + target_include_directories(mbedtls PUBLIC ${CMAKE_CURRENT_LIST_DIR}/mbedtls/include) + if(USB_ITF_HID) + add_library(tinycbor STATIC ${CBOR_SOURCES}) + target_include_directories(tinycbor PUBLIC ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src) + set(LIBRARIES ${LIBRARIES} tinycbor) + endif() endif() -set(LIBRARIES - pico_stdlib - pico_multicore - pico_rand - pico_aon_timer - hardware_flash - pico_unique_id - tinyusb_device - tinyusb_board - hardware_pio -) +if (PICO_PLATFORM) + list(APPEND LIBRARIES + pico_stdlib + pico_multicore + pico_rand + pico_aon_timer + hardware_flash + pico_unique_id + tinyusb_device + tinyusb_board + hardware_pio + ) +endif() + +if (ENABLE_PQC) + list(APPEND LIBRARIES + mlkem512 + mlkem768 + mlkem1024 + ) +endif() set(IS_CYW43 0) if (PICO_PLATFORM) @@ -403,10 +487,7 @@ else() ${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c ) endif() -set(EXTERNAL_SOURCES ${CBOR_SOURCES}) -if(NOT ESP_PLATFORM) - set(EXTERNAL_SOURCES ${EXTERNAL_SOURCES} ${MBEDTLS_SOURCES}) -endif() + if(MSVC) set( CMAKE_C_FLAGS @@ -423,11 +504,6 @@ if(MSVC) _WIN32_WINNT_WIN10_RS5=0 _STRALIGN_USE_SECURE_CRT=0 NTDDI_WIN11_DT=0) - set_source_files_properties( - ${EXTERNAL_SOURCES} - PROPERTIES - COMPILE_FLAGS " -W3 -wd4242 -wd4065" - ) endif() if(PICO_PLATFORM) @@ -450,13 +526,17 @@ if(PICO_RP2350) set(INCLUDES ${INCLUDES} ${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt ) + target_include_directories(mbedtls PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt + ) + target_link_libraries(mbedtls PRIVATE pico_sha256) set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt/sha256_alt.c ) + add_definitions(-DMBEDTLS_SHA256_ALT=1) set(LIBRARIES ${LIBRARIES} pico_sha256) endif() set(INTERNAL_SOURCES ${PICO_KEYS_SOURCES}) -set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${EXTERNAL_SOURCES}) if(NOT TARGET pico_keys_sdk) if(PICO_PLATFORM) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100755 index 4ccd9f1..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -idf_component_register( - SRCS ${PICO_KEYS_SOURCES} - INCLUDE_DIRS . fs rng usb led ../tinycbor/src - REQUIRES bootloader_support esp_partition esp_tinyusb efuse mbedtls -) -idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/src/apdu.c b/src/apdu.c index 3eeffd8..8ac596d 100644 --- a/src/apdu.c +++ b/src/apdu.c @@ -30,7 +30,7 @@ uint8_t *rdata_gr = NULL; uint16_t rdata_bk = 0x0; extern uint32_t timeout; bool is_chaining = false; -uint8_t chain_buf[4096]; +uint8_t chain_buf[2038]; uint8_t *chain_ptr = NULL; int process_apdu() { diff --git a/src/crypto_utils.c b/src/crypto_utils.c index 7adba39..84a3213 100644 --- a/src/crypto_utils.c +++ b/src/crypto_utils.c @@ -278,3 +278,16 @@ mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_ } return MBEDTLS_ECP_DP_NONE; } + +#define POLY 0xedb88320 + +uint32_t crc32c(const uint8_t *buf, size_t len) { + uint32_t crc = 0xffffffff; + while (len--) { + crc ^= *buf++; + for (int k = 0; k < 8; k++) { + crc = (crc >> 1) ^ (POLY & (0 - (crc & 1))); + } + } + return ~crc; +} diff --git a/src/crypto_utils.h b/src/crypto_utils.h index 83631fb..c2952b9 100644 --- a/src/crypto_utils.h +++ b/src/crypto_utils.h @@ -56,5 +56,6 @@ extern int aes_decrypt(const uint8_t *key, const uint8_t *iv, uint16_t key_size, extern int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len); extern int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len); extern mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len); +extern uint32_t crc32c(const uint8_t *buf, size_t len); #endif diff --git a/src/fs/low_flash.c b/src/fs/low_flash.c index bfd43d9..3c72333 100644 --- a/src/fs/low_flash.c +++ b/src/fs/low_flash.c @@ -22,6 +22,7 @@ #include "pico_keys.h" #include +#include "crypto_utils.h" #ifdef PICO_PLATFORM #include "pico/stdlib.h" #include "hardware/flash.h" @@ -158,8 +159,14 @@ void do_flash() { sem_release(&sem_flash); } +#ifdef PICO_RP2040 +void phymarker_write(); +#endif //this function has to be called from the core 0 void low_flash_init() { +#ifdef PICO_RP2040 + phymarker_write(); +#endif memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES); mutex_init(&mtx_flash); sem_init(&sem_flash, 0, 1); @@ -371,3 +378,42 @@ bool flash_check_blank(const uint8_t *p_start, size_t size) { } return true; } + +#ifdef PICO_RP2040 +typedef struct { + uint64_t magic; + uint16_t version; + uint16_t flags; + uint8_t uid[PICO_UNIQUE_BOARD_ID_SIZE_BYTES]; + uint32_t crc32; +} __attribute__ ((packed)) phymarker_t; + +uintptr_t __phymarker_start = (uintptr_t)0x10100000; + +const uint64_t PHYSICAL_MARKER_MAGIC = 0x5049434F4B455953ULL; // "PICOKEYS" + +void phymarker_write() { + const uint64_t magic = *(uint64_t *)__phymarker_start; + if (magic == PHYSICAL_MARKER_MAGIC) { + return; + } + phymarker_t pm = { + .magic = PHYSICAL_MARKER_MAGIC, // "PICOKEYS" + .version = 0x0001, + .flags = 0x0000, + .crc32 = 0x00000000 + }; + memcpy(pm.uid, pico_serial.id, PICO_UNIQUE_BOARD_ID_SIZE_BYTES); + pm.crc32 = crc32c((const uint8_t *)&pm, sizeof(phymarker_t) - sizeof(uint32_t)); + + uint8_t buf[FLASH_PAGE_SIZE] = {0}; + memcpy(buf, &pm, sizeof(phymarker_t)); + uint32_t ints = save_and_disable_interrupts(); + + flash_range_erase((uint32_t)__phymarker_start - XIP_BASE, FLASH_SECTOR_SIZE); + flash_range_program((uint32_t)__phymarker_start - XIP_BASE, (const uint8_t *)buf, sizeof(buf)); + + restore_interrupts(ints); +} + +#endif diff --git a/src/main.c b/src/main.c index ecdc873..064e622 100644 --- a/src/main.c +++ b/src/main.c @@ -235,8 +235,42 @@ bool wait_button() { req_button_pending = false; return timeout || cancel_button; } + +__attribute__((weak)) int picokey_init() { + return 0; +} + #endif +bool set_rtc = false; + +bool has_set_rtc() { + return set_rtc; +} + +void set_rtc_time(time_t t) { +#ifdef PICO_PLATFORM + struct timespec tv = {.tv_sec = t, .tv_nsec = 0}; + aon_timer_set_time(&tv); +#else + struct timeval tv = {.tv_sec = t, .tv_usec = 0}; + settimeofday(&tv, NULL); +#endif + set_rtc = true; +} + +time_t get_rtc_time() { +#ifdef PICO_PLATFORM + struct timespec tv; + aon_timer_get_time(&tv); + return tv.tv_sec; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec; +#endif +} + struct apdu apdu; void init_rtc() { @@ -247,7 +281,7 @@ void init_rtc() { #endif } -extern void neug_task(); +extern void hwrng_task(); extern void usb_task(); void execute_tasks() { @@ -261,7 +295,7 @@ void execute_tasks() void core0_loop() { while (1) { execute_tasks(); - neug_task(); + hwrng_task(); do_flash(); #ifndef ENABLE_EMULATION if (button_pressed_cb && board_millis() > 1000 && !is_busy()) { // wait 1 second to boot up @@ -364,6 +398,10 @@ int main(void) { #endif #endif +#ifndef ENABLE_EMULATION + picokey_init(); +#endif + #ifdef ESP_PLATFORM xTaskCreatePinnedToCore(core0_loop, "core0", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, ESP32_CORE0); #else diff --git a/src/pico_keys.h b/src/pico_keys.h index 3859ac2..d9e6bfa 100644 --- a/src/pico_keys.h +++ b/src/pico_keys.h @@ -18,6 +18,8 @@ #ifndef _PICO_KEYS_H_ #define _PICO_KEYS_H_ +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + #if defined(PICO_RP2040) || defined(PICO_RP2350) #define PICO_PLATFORM #endif @@ -59,6 +61,15 @@ #include "pico/util/queue.h" #endif +#ifdef PICO_PLATFORM +#include "pico/bootrom.h" +#include "hardware/watchdog.h" +#include "pico/aon_timer.h" +#else +#include +#include +#endif + extern bool wait_button(); extern void low_flash_init_core1(); @@ -240,4 +251,8 @@ extern uint8_t pico_serial_hash[32]; #define multicore_launch_func_core1(a) multicore_launch_core1((void (*) (void))a) #endif +extern bool has_set_rtc(); +extern time_t get_rtc_time(); +extern void set_rtc_time(time_t tv_sec); + #endif diff --git a/src/pico_keys_version.h b/src/pico_keys_version.h index c803d56..607649d 100644 --- a/src/pico_keys_version.h +++ b/src/pico_keys_version.h @@ -18,7 +18,7 @@ #ifndef __VERSION_H_ #define __VERSION_H_ -#define PICO_KEYS_SDK_VERSION 0x0802 +#define PICO_KEYS_SDK_VERSION 0x0805 #define PICO_KEYS_SDK_VERSION_MAJOR ((PICO_KEYS_SDK_VERSION >> 8) & 0xff) #define PICO_KEYS_SDK_VERSION_MINOR (PICO_KEYS_SDK_VERSION & 0xff) diff --git a/src/rescue.c b/src/rescue.c index 603c781..a0cfa73 100644 --- a/src/rescue.c +++ b/src/rescue.c @@ -19,17 +19,10 @@ #include "apdu.h" #include "pico_keys_version.h" #include "otp.h" -#ifdef PICO_PLATFORM -#include "pico/bootrom.h" -#include "hardware/watchdog.h" -#include "pico/aon_timer.h" -#else -#include -#include -#endif #include "mbedtls/ecdsa.h" #include "mbedtls/sha256.h" #include "random.h" +#include "crypto_utils.h" #ifdef PICO_PLATFORM extern char __flash_binary_start; @@ -38,7 +31,6 @@ extern char __flash_binary_end; int rescue_process_apdu(); int rescue_unload(); -bool set_rtc = false; const uint8_t rescue_aid[] = { 8, @@ -55,6 +47,8 @@ const uint8_t rescue_aid[] = { #define PICO_MCU 0 #endif +#define EF_DEVCERT_KEY 0xE0C1 + extern uint8_t PICO_PRODUCT; extern uint8_t PICO_VERSION_MAJOR; extern uint8_t PICO_VERSION_MINOR; @@ -84,30 +78,69 @@ int rescue_unload() { return PICOKEY_OK; } +static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id ec_id) { + file_t *ef_devcert_key = file_new(EF_DEVCERT_KEY); + if (!ef_devcert_key) { + return SW_FILE_NOT_FOUND(); + } + uint8_t kbase[32] = {0}; + derive_kbase(kbase); + if (file_has_data(ef_devcert_key)) { + uint8_t pkey[32] = {0}; + memcpy(pkey, file_get_data(ef_devcert_key), 32); + aes_decrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32); + int ret = mbedtls_ecp_read_key(ec_id, ecp, pkey, 32); + mbedtls_platform_zeroize(pkey, sizeof(pkey)); + if (ret != 0) { + return SW_EXEC_ERROR(); + } + } + else { + // Generate new key + uint8_t pkey[MBEDTLS_ECP_MAX_BYTES] = {0}; + size_t olen = 0; + mbedtls_ecp_gen_key(ec_id, ecp, random_gen, NULL); + mbedtls_ecp_write_key_ext(ecp, &olen, pkey, sizeof(pkey)); + + aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32); + file_put_data(ef_devcert_key, pkey, (uint16_t)olen); + mbedtls_platform_zeroize(pkey, sizeof(pkey)); + low_flash_available(); + } + return PICOKEY_OK; +} + int cmd_keydev_sign() { uint8_t p1 = P1(apdu); if (p1 == 0x01) { if (apdu.nc != 32) { return SW_WRONG_LENGTH(); } + mbedtls_ecp_keypair ecp; + mbedtls_ecp_keypair_init(&ecp); + mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1; if (!otp_key_2) { - return SW_INS_NOT_SUPPORTED(); + int ret = load_internal_keydev(&ecp, ec_id); + if (ret != PICOKEY_OK) { + mbedtls_ecp_keypair_free(&ecp); + return ret; + } } - mbedtls_ecdsa_context ecdsa; - mbedtls_ecdsa_init(&ecdsa); - int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecdsa, otp_key_2, 32); - if (ret != 0) { - mbedtls_ecdsa_free(&ecdsa); - return SW_EXEC_ERROR(); + else { + int ret = mbedtls_ecp_read_key(ec_id, &ecp, otp_key_2, 32); + if (ret != 0) { + mbedtls_ecp_keypair_free(&ecp); + return SW_EXEC_ERROR(); + } } - uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(MBEDTLS_ECP_DP_SECP256K1)->bit_size + 7) / 8); + uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(ec_id)->bit_size + 7) / 8); mbedtls_mpi r, s; mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); - ret = mbedtls_ecdsa_sign(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL); + int ret = mbedtls_ecdsa_sign(&ecp.MBEDTLS_PRIVATE(grp), &r, &s, &ecp.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL); if (ret != 0) { - mbedtls_ecdsa_free(&ecdsa); + mbedtls_ecp_keypair_free(&ecp); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); return SW_EXEC_ERROR(); @@ -115,32 +148,39 @@ int cmd_keydev_sign() { mbedtls_mpi_write_binary(&r, res_APDU, key_size / 2); res_APDU_size = key_size / 2; mbedtls_mpi_write_binary(&s, res_APDU + res_APDU_size, key_size / 2); res_APDU_size += key_size / 2; - mbedtls_ecdsa_free(&ecdsa); + mbedtls_ecp_keypair_free(&ecp); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); } else if (p1 == 0x02) { // Return public key - if (!otp_key_2) { - return SW_INS_NOT_SUPPORTED(); - } if (apdu.nc != 0) { return SW_WRONG_LENGTH(); } mbedtls_ecp_keypair ecp; mbedtls_ecp_keypair_init(&ecp); - int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecp, otp_key_2, 32); - if (ret != 0) { - mbedtls_ecp_keypair_free(&ecp); - return SW_EXEC_ERROR(); + mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1; + if (!otp_key_2) { + int ret = load_internal_keydev(&ecp, ec_id); + if (ret != PICOKEY_OK) { + mbedtls_ecp_keypair_free(&ecp); + return ret; + } } - ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL); + else { + int ret = mbedtls_ecp_read_key(ec_id, &ecp, otp_key_2, 32); + if (ret != 0) { + mbedtls_ecp_keypair_free(&ecp); + return SW_EXEC_ERROR(); + } + } + int ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL); if (ret != 0) { mbedtls_ecp_keypair_free(&ecp); return SW_EXEC_ERROR(); } size_t olen = 0; - ret = mbedtls_ecp_point_write_binary(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 4096); + ret = mbedtls_ecp_point_write_binary(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 2038); if (ret != 0) { mbedtls_ecp_keypair_free(&ecp); return SW_EXEC_ERROR(); @@ -220,14 +260,7 @@ int cmd_write() { uint32_t t = (apdu.data[0] << 24) | (apdu.data[1] << 16) | (apdu.data[2] << 8) | apdu.data[3]; tv_sec = (time_t)t; } -#ifdef PICO_PLATFORM - struct timespec tv = {.tv_sec = tv_sec, .tv_nsec = 0}; - aon_timer_set_time(&tv); -#else - struct timeval tv = {.tv_sec = tv_sec, .tv_usec = 0}; - settimeofday(&tv, NULL); -#endif - set_rtc = true; + set_rtc_time(tv_sec); } led_3_blinks(); return SW_OK(); @@ -277,16 +310,15 @@ int cmd_read() { if (p2 != 0x1 && p2 != 0x2) { return SW_INCORRECT_P1P2(); } - if (!set_rtc) { + if (!has_set_rtc()) { return SW_CONDITIONS_NOT_SATISFIED(); } res_APDU_size = 0; + time_t tv_sec = get_rtc_time(); #ifdef PICO_PLATFORM - struct timespec tv; - aon_timer_get_time(&tv); + struct timespec tv = {.tv_sec = tv_sec, .tv_nsec = 0}; #else - struct timeval tv; - gettimeofday(&tv, NULL); + struct timeval tv = {.tv_sec = tv_sec, .tv_usec = 0}; #endif if (p2 == 0x1) { struct tm *tm = localtime(&tv.tv_sec); diff --git a/src/rng/hwrng.c b/src/rng/hwrng.c index cec2871..c83c437 100644 --- a/src/rng/hwrng.c +++ b/src/rng/hwrng.c @@ -44,17 +44,17 @@ void hwrng_start() { } static uint64_t random_word = 0xcbf29ce484222325; -static uint8_t ep_round = 0; +static uint8_t hwrng_mix_round = 0; -static void ep_init() { +static void hwrng_mix_init() { random_word = 0xcbf29ce484222325; - ep_round = 0; + hwrng_mix_round = 0; } /* Here, we assume a little endian architecture. */ -static int ep_process() { - if (ep_round == 0) { - ep_init(); +static int hwrng_mix_process() { + if (hwrng_mix_round == 0) { + hwrng_mix_init(); } uint64_t word = 0x0; @@ -69,14 +69,14 @@ static int ep_process() { #endif random_word ^= word ^ board_millis(); random_word *= 0x00000100000001B3; - if (++ep_round == 8) { - ep_round = 0; - return 2; //2 words + if (++hwrng_mix_round == 8) { + hwrng_mix_round = 0; + return sizeof(uint64_t) / sizeof(uint32_t); //2 words } return 0; } -struct rng_rb { +struct hwrng_buf { uint32_t *buf; uint8_t head, tail; uint8_t size; @@ -84,7 +84,7 @@ struct rng_rb { unsigned int empty : 1; }; -static void rb_init(struct rng_rb *rb, uint32_t *p, uint8_t size) { +static void hwrng_buf_init(struct hwrng_buf *rb, uint32_t *p, uint8_t size) { rb->buf = p; rb->size = size; rb->head = rb->tail = 0; @@ -92,7 +92,7 @@ static void rb_init(struct rng_rb *rb, uint32_t *p, uint8_t size) { rb->empty = 1; } -static void rb_add(struct rng_rb *rb, uint32_t v) { +static void hwrng_buf_add(struct hwrng_buf *rb, uint32_t v) { rb->buf[rb->tail++] = v; if (rb->tail == rb->size) { rb->tail = 0; @@ -103,7 +103,7 @@ static void rb_add(struct rng_rb *rb, uint32_t v) { rb->empty = 0; } -static uint32_t rb_del(struct rng_rb *rb) { +static uint32_t hwrng_buf_del(struct hwrng_buf *rb) { uint32_t v = rb->buf[rb->head++]; if (rb->head == rb->size) { @@ -117,19 +117,18 @@ static uint32_t rb_del(struct rng_rb *rb) { return v; } -static struct rng_rb the_ring_buffer; +static struct hwrng_buf ring_buffer; -void *neug_task() { - struct rng_rb *rb = &the_ring_buffer; +void *hwrng_task() { + struct hwrng_buf *rb = &ring_buffer; int n; - if ((n = ep_process())) { - int i; + if ((n = hwrng_mix_process())) { const uint32_t *vp = (const uint32_t *) &random_word; - for (i = 0; i < n; i++) { - rb_add(rb, *vp++); + for (int i = 0; i < n; i++) { + hwrng_buf_add(rb, *vp++); if (rb->full) { break; } @@ -138,38 +137,37 @@ void *neug_task() { return NULL; } -void neug_init(uint32_t *buf, uint8_t size) { - struct rng_rb *rb = &the_ring_buffer; +void hwrng_init(uint32_t *buf, uint8_t size) { + struct hwrng_buf *rb = &ring_buffer; - rb_init(rb, buf, size); + hwrng_buf_init(rb, buf, size); hwrng_start(); - ep_init(); + hwrng_mix_init(); } -void neug_flush(void) { - struct rng_rb *rb = &the_ring_buffer; - +void hwrng_flush(void) { + struct hwrng_buf *rb = &ring_buffer; while (!rb->empty) { - rb_del(rb); + hwrng_buf_del(rb); } } -uint32_t neug_get() { - struct rng_rb *rb = &the_ring_buffer; +uint32_t hwrng_get() { + struct hwrng_buf *rb = &ring_buffer; uint32_t v; while (rb->empty) { - neug_task(); + hwrng_task(); } - v = rb_del(rb); + v = hwrng_buf_del(rb); return v; } -void neug_wait_full() { - struct rng_rb *rb = &the_ring_buffer; +void hwrng_wait_full() { + struct hwrng_buf *rb = &ring_buffer; #ifdef ESP_PLATFORM uint8_t core = xTaskGetCurrentTaskHandle() == hcore1 ? 1 : 0; #elif defined(PICO_PLATFORM) @@ -182,6 +180,6 @@ void neug_wait_full() { } else #endif - neug_task(); + hwrng_task(); } } diff --git a/src/rng/hwrng.h b/src/rng/hwrng.h index e510d93..4229eb9 100644 --- a/src/rng/hwrng.h +++ b/src/rng/hwrng.h @@ -17,17 +17,11 @@ #ifndef _NEUG_H_ #define _NEUG_H_ +#include -#define NEUG_PRE_LOOP 32 - -#include -#if defined(PICO_PLATFORM) -#include "pico/stdlib.h" -#endif - -void neug_init(uint32_t *buf, uint8_t size); -uint32_t neug_get(); -void neug_flush(void); -void neug_wait_full(); +void hwrng_init(uint32_t *buf, uint8_t size); +uint32_t hwrng_get(); +void hwrng_flush(void); +void hwrng_wait_full(); #endif diff --git a/src/rng/random.c b/src/rng/random.c index 3c46d81..bc75434 100644 --- a/src/rng/random.c +++ b/src/rng/random.c @@ -15,8 +15,12 @@ * along with this program. If not, see . */ +#define HWRNG_PRE_LOOP 32 -#include +#include +#if defined(PICO_PLATFORM) +#include "pico/stdlib.h" +#endif #include #include "hwrng.h" @@ -25,42 +29,38 @@ static uint32_t random_word[RANDOM_BYTES_LENGTH / sizeof(uint32_t)]; void random_init(void) { - int i; + hwrng_init(random_word, RANDOM_BYTES_LENGTH / sizeof(uint32_t)); - neug_init(random_word, RANDOM_BYTES_LENGTH / sizeof(uint32_t)); - - for (i = 0; i < NEUG_PRE_LOOP; i++) { - neug_get(); + for (int i = 0; i < HWRNG_PRE_LOOP; i++) { + hwrng_get(); } } -/* - * Return pointer to random 32-byte - */ -void random_bytes_free(const uint8_t *p); -#define MAX_RANDOM_BUFFER 1024 -const uint8_t *random_bytes_get(size_t len) { - if (len > MAX_RANDOM_BUFFER) { - return NULL; - } - static uint32_t return_word[MAX_RANDOM_BUFFER / sizeof(uint32_t)]; - for (size_t ix = 0; ix < len; ix += RANDOM_BYTES_LENGTH) { - neug_wait_full(); - memcpy(return_word + ix / sizeof(uint32_t), random_word, RANDOM_BYTES_LENGTH); - random_bytes_free((const uint8_t *) random_word); - } - return (const uint8_t *) return_word; -} - /* * Free pointer to random 32-byte */ void random_bytes_free(const uint8_t *p) { (void) p; memset(random_word, 0, RANDOM_BYTES_LENGTH); - neug_flush(); + hwrng_flush(); } +/* + * Return pointer to random 32-byte + */ +#define MAX_RANDOM_BUFFER 1024 +const uint8_t *random_bytes_get(size_t len) { + if (len > MAX_RANDOM_BUFFER) { + return NULL; + } + static uint32_t return_word[MAX_RANDOM_BUFFER / sizeof(uint32_t)]; + for (size_t ix = 0; ix < len; ix += RANDOM_BYTES_LENGTH) { + hwrng_wait_full(); + memcpy(return_word + ix / sizeof(uint32_t), random_word, RANDOM_BYTES_LENGTH); + random_bytes_free((const uint8_t *) random_word); + } + return (const uint8_t *) return_word; +} /* * Random byte iterator @@ -71,7 +71,7 @@ int random_gen(void *arg, unsigned char *out, size_t out_len) { uint8_t n; while (out_len) { - neug_wait_full(); + hwrng_wait_full(); n = RANDOM_BYTES_LENGTH - index; if (n > out_len) { @@ -85,7 +85,7 @@ int random_gen(void *arg, unsigned char *out, size_t out_len) { if (index >= RANDOM_BYTES_LENGTH) { index = 0; - neug_flush(); + hwrng_flush(); } } @@ -95,3 +95,9 @@ int random_gen(void *arg, unsigned char *out, size_t out_len) { return 0; } + +#ifdef ENABLE_PQC +void randombytes(uint8_t *buf, size_t n) { + random_gen(NULL, buf, n); +} +#endif diff --git a/src/usb/ccid/ccid.c b/src/usb/ccid/ccid.c index 4bc4657..fd16ae3 100644 --- a/src/usb/ccid/ccid.c +++ b/src/usb/ccid/ccid.c @@ -201,6 +201,20 @@ int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read) { (void) rx_read; if (ccid_rx[itf].w_ptr - ccid_rx[itf].r_ptr >= 10) { driver_init_ccid(itf); + if (ccid_header[itf]->dwLength > USB_BUFFER_SIZE - 10) { + //Invalid length + ccid_rx[itf].r_ptr = ccid_rx[itf].w_ptr = 0; + + ccid_resp_fast[itf]->bMessageType = CCID_DATA_BLOCK_RET; + ccid_resp_fast[itf]->dwLength = 2; + ccid_resp_fast[itf]->bSlot = 0; + ccid_resp_fast[itf]->bSeq = ccid_header[itf]->bSeq; + ccid_resp_fast[itf]->abRFU0 = ccid_status; + ccid_resp_fast[itf]->abRFU1 = 0; + memcpy(&ccid_resp_fast[itf]->apdu, "\x6F\x00", 2); + ccid_write_fast(itf, (const uint8_t *)ccid_resp_fast[itf], 12); + return 0; + } //printf("ccid_process %ld %d %x %x %d\n",ccid_header[itf]->dwLength,rx_read-10,ccid_header[itf]->bMessageType,ccid_header[itf]->bSeq,ccid_rx[itf].w_ptr - ccid_rx[itf].r_ptr - 10); if (ccid_header[itf]->dwLength <= (uint32_t)(ccid_rx[itf].w_ptr - ccid_rx[itf].r_ptr - 10)){ ccid_rx[itf].r_ptr += (uint16_t)(ccid_header[itf]->dwLength + 10); diff --git a/src/usb/usb.c b/src/usb/usb.c index e040e8b..9bdd08c 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -73,8 +73,10 @@ queue_t card_to_usb_q = {0}; #ifndef ENABLE_EMULATION extern tusb_desc_device_t desc_device; +extern char *string_desc_itf[4], *string_desc_arr[]; #endif -void usb_init() { +void usb_init() +{ #ifndef ENABLE_EMULATION if (phy_data.vidpid_present) { desc_device.idVendor = phy_data.vid; @@ -108,20 +110,32 @@ void usb_init() { if (enabled_usb_itf & PHY_USB_ITF_HID) { ITF_HID_CTAP = ITF_HID_TOTAL++; ITF_HID = ITF_TOTAL++; +#ifndef ENABLE_EMULATION + string_desc_itf[ITF_TOTAL - 1] = string_desc_arr[5]; +#endif } if (enabled_usb_itf & PHY_USB_ITF_KB) { ITF_HID_KB = ITF_HID_TOTAL++; ITF_KEYBOARD = ITF_TOTAL++; +#ifndef ENABLE_EMULATION + string_desc_itf[ITF_TOTAL - 1] = string_desc_arr[6]; +#endif } #endif #ifdef USB_ITF_CCID if (enabled_usb_itf & PHY_USB_ITF_CCID) { ITF_SC_CCID = ITF_SC_TOTAL++; ITF_CCID = ITF_TOTAL++; +#ifndef ENABLE_EMULATION + string_desc_itf[ITF_TOTAL - 1] = string_desc_arr[7]; +#endif } if (enabled_usb_itf & PHY_USB_ITF_WCID) { ITF_SC_WCID = ITF_SC_TOTAL++; ITF_WCID = ITF_TOTAL++; +#ifndef ENABLE_EMULATION + string_desc_itf[ITF_TOTAL - 1] = string_desc_arr[8]; +#endif } #endif card_locked_itf = ITF_TOTAL; diff --git a/src/usb/usb_descriptors.c b/src/usb/usb_descriptors.c index f2f2734..90e4e16 100644 --- a/src/usb/usb_descriptors.c +++ b/src/usb/usb_descriptors.c @@ -28,10 +28,10 @@ #include "usb.h" #ifndef USB_VID -#define USB_VID 0xFEFF +#define USB_VID 0x1D50 #endif #ifndef USB_PID -#define USB_PID 0xFCFD +#define USB_PID 0x619B #endif #if defined(PICO_PLATFORM) || defined(ESP_PLATFORM) @@ -316,20 +316,17 @@ uint8_t const *tud_descriptor_bos_cb(void) { //--------------------------------------------------------------------+ // array of pointer to string descriptors +char *string_desc_itf[4] = {0}; char const *string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "Libre Keys", // 1: Manufacturer "Pico Key", // 2: Product "11223344", // 3: Serials, should use chip ID "Config" // 4: Vendor Interface -#ifdef USB_ITF_HID , "HID Interface" , "HID Keyboard Interface" -#endif -#ifdef USB_ITF_CCID , "CCID OTP FIDO Interface" , "WebCCID Interface" -#endif }; #ifdef ESP_PLATFORM @@ -369,6 +366,9 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { str = phy_data.usb_product; } } + else if (index >= 5 && string_desc_itf[index - 5] != NULL) { + str = string_desc_itf[index - 5]; + } uint8_t buff_avail = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; if (index >= 4) {