42 Commits
v8.0 ... v8.5

Author SHA1 Message Date
Pol Henarejos
61d4515ecc Pico Keys SDK 8.5
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-29 16:11:19 +01:00
Pol Henarejos
2cd21f7dd2 Add weak init callback.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-29 16:11:12 +01:00
Pol Henarejos
081f473815 Add a PHY marker for RP2040 to preserve the serial number in BOOTSEL.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-29 16:03:09 +01:00
Pol Henarejos
56f4fca657 Move crc to crypto utils.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-29 16:02:44 +01:00
Pol Henarejos
2f77e1c3fa Add 8K flash area for binding.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-29 15:48:33 +01:00
Pol Henarejos
da94e24b45 Add rescue support for RP2040.
Note, however, that this is a best-effort approach since it does not have OTP. All security attempts are flawled and shall not be used to keep security information.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-28 18:52:12 +01:00
Pol Henarejos
8075611f15 Pico Keys SDK 8.4
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-28 00:53:50 +01:00
Pol Henarejos
474e8b8b46 Fix crash when only CCID is enabled
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-28 00:53:34 +01:00
Pol Henarejos
668b1ac1dd Fix emulation build
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-26 01:27:07 +01:00
Pol Henarejos
20f2b3b74b Fix interface strings when are not all enabled.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-26 01:19:56 +01:00
Pol Henarejos
50488cc890 Add sanity check in case too large packets are sent.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-26 01:19:31 +01:00
Pol Henarejos
860f77a45b Move rtc
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-24 01:15:10 +01:00
Pol Henarejos
42267cb237 Use new descriptors allocated to picokeys.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-22 12:30:12 +01:00
Pol Henarejos
b5c2e55c71 Add missing files.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-22 12:09:27 +01:00
Pol Henarejos
68600291d0 Reorganize tree for ESP32
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-22 11:22:37 +01:00
Pol Henarejos
132ec29424 Fix SHA256 alt
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-22 11:22:37 +01:00
Pol Henarejos
1125b05f9c Add ML-KEM submodule
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-22 11:22:37 +01:00
Pol Henarejos
8412727e03 Rename methods for better description
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-22 11:22:37 +01:00
Pol Henarejos
8a0ef0b30c Add set/get RTC.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-19 16:36:21 +01:00
Pol Henarejos
f108eebb93 Fix LED default parameters in Pimoroni boards.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-15 01:17:13 +01:00
Pol Henarejos
263e554cc6 Upgrade to v8.2
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-05 19:50:58 +01:00
Pol Henarejos
7de98552d1 Fix button logic.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-05 19:39:35 +01:00
Pol Henarejos
08dc94a144 Disable button press by default since LED may not be properly configured until it is commissioned.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-05 19:37:18 +01:00
Pol Henarejos
7e6e3c8f3c Fix build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-29 20:36:09 +01:00
Pol Henarejos
6305ea11ab Blink led three times to acknowledge proper commissioning.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-29 20:15:45 +01:00
Pol Henarejos
4df616082e Fix led for pimoroni boards.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-27 22:03:35 +01:00
Pol Henarejos
3bf035d68a Zeroize pkey
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-27 22:02:58 +01:00
Pol Henarejos
7dc7be0909 Add device public key recovery and upload attestation certification.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-15 14:34:04 +01:00
Pol Henarejos
015fb61759 Add sign with keydev to rescue.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-15 01:17:26 +01:00
Pol Henarejos
1f4d638119 Build minimal picokey app.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-14 18:45:02 +01:00
Pol Henarejos
05fe0596ef Revert "Move EDDSA to another branch."
This reverts commit 09ec0767b6.
2025-12-11 15:42:30 +01:00
Pol Henarejos
d86371bb2c Revert "Move Secure Boot to another branch."
This reverts commit 8cb2484aa3.
2025-12-11 15:42:21 +01:00
Pol Henarejos
8cb2484aa3 Move Secure Boot to another branch.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-09 21:37:36 +01:00
Pol Henarejos
7583ecff18 Fix applet cmp
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-09 19:15:22 +01:00
Pol Henarejos
09ec0767b6 Move EDDSA to another branch.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-09 15:36:29 +01:00
Pol Henarejos
d0dea3d0c5 Fix MSOS/BOS descriptor.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-03 16:34:05 +01:00
Pol Henarejos
53d3a7ac91 Fix OTP button press in ESP32.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-02 14:38:07 +01:00
Pol Henarejos
2438356d83 Set anti-rollback version only when the binary is signed.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-02 09:39:17 +01:00
Pol Henarejos
79b69bfd7e Add WHOLE_ARCHIVE property.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-02 09:29:34 +01:00
Pol Henarejos
d189c2978c Add anti-rollback argument.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-01 23:41:29 +01:00
Pol Henarejos
c1cc33fd9d Upodate mbedtls only when necessary.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-01 17:02:47 +01:00
Pol Henarejos
2d72a157d5 Fix on AID selection. It should support shorter AID if matches.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-12-01 01:44:29 +01:00
37 changed files with 914 additions and 241 deletions

3
.gitmodules vendored
View File

@@ -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/

View File

@@ -17,66 +17,86 @@
cmake_minimum_required(VERSION 3.16)
if(ESP_PLATFORM)
set(EXTRA_COMPONENT_DIRS src)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(USB_ITF_CCID 1)
#set(USB_ITF_HID 1)
include(pico_keys_sdk_import.cmake)
project(pico_keys_sdk)
if(ESP_PLATFORM)
set(EXTRA_COMPONENT_DIRS src)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
else()
if(NOT ENABLE_EMULATION)
set(PICO_USE_FASTEST_SUPPORTED_CLOCK 1)
include(pico_sdk_import.cmake)
endif()
if(ENABLE_EMULATION)
else()
include(pico_sdk_import.cmake)
endif()
project(picokey C CXX ASM)
project(pico_keys C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
if(NOT DEFINED __FOR_CI)
set(__FOR_CI 0)
endif()
if(__FOR_CI)
add_definitions(-D__FOR_CI)
endif()
if(ENABLE_EMULATION)
else()
pico_sdk_init()
endif()
if (NOT DEFINED __FOR_CI)
set(__FOR_CI 0)
endif()
if (__FOR_CI)
add_definitions(-D__FOR_CI)
endif()
add_executable(picokey)
endif()
set(USB_ITF_CCID 1)
set(USB_ITF_HID 1)
set(USB_ITF_WCID 1)
include(cmake/version.cmake)
include(pico_keys_sdk_import.cmake)
add_executable(pico_keys_sdk_exe)
target_compile_options(pico_keys_sdk_exe PUBLIC
-Wall
-Werror
if(NOT ESP_PLATFORM)
set(SOURCES ${PICO_KEYS_SOURCES})
endif()
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fs/files.c
${CMAKE_CURRENT_LIST_DIR}/src/version.c
)
if(ENABLE_EMULATION)
target_compile_options(pico_keys_sdk_exe PUBLIC
-fdata-sections
-ffunction-sections
)
if(APPLE)
target_link_options(pico_keys_sdk_exe PUBLIC
-Wl,-dead_strip
)
else()
target_link_options(pico_keys_sdk_exe PUBLIC
-Wl,--gc-sections
)
endif (APPLE)
else()
pico_add_extra_outputs(pico_keys_sdk_exe)
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/pico_keys_version.h" 2)
target_link_libraries(pico_keys_sdk_exe PRIVATE pico_keys_sdk pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc tinyusb_device tinyusb_board)
if(ESP_PLATFORM)
project(picokey)
endif()
if(NOT ESP_PLATFORM)
target_sources(picokey PUBLIC ${SOURCES})
target_include_directories(picokey PUBLIC ${INCLUDES})
target_compile_options(picokey PUBLIC
-Wall
)
if(NOT MSVC)
target_compile_options(picokey PUBLIC
-Werror
)
endif()
if(ENABLE_EMULATION)
if(NOT MSVC)
target_compile_options(picokey PUBLIC
-fdata-sections
-ffunction-sections
)
endif()
if(APPLE)
target_link_options(picokey PUBLIC
-Wl,-dead_strip
)
elseif(MSVC)
target_compile_options(picokey PUBLIC
-WX
)
target_link_libraries(picokey PUBLIC wsock32 ws2_32 Bcrypt)
else()
target_link_options(picokey PUBLIC
-Wl,--gc-sections
)
endif(APPLE)
target_link_libraries(picokey PRIVATE pthread m)
else()
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
endif()
endif()

View File

@@ -33,7 +33,7 @@ macro(HEX2DEC VAR VAL)
endwhile()
endmacro(HEX2DEC)
macro(SET_VERSION MAJOR MINOR FILE)
macro(SET_VERSION MAJOR MINOR FILE ROLLBACK)
file(READ ${FILE} ver)
string(REGEX MATCHALL "0x([0-9A-F])([0-9A-F])([0-9A-F])([0-9A-F])" _ ${ver})
string(CONCAT ver_major ${CMAKE_MATCH_1}${CMAKE_MATCH_2})
@@ -42,8 +42,13 @@ macro(SET_VERSION MAJOR MINOR FILE)
HEX2DEC(ver_minor ${ver_minor})
message(STATUS "Found version:\t\t ${ver_major}.${ver_minor}")
if(PICO_PLATFORM)
pico_set_binary_version(${CMAKE_PROJECT_NAME} MAJOR ${ver_major} MINOR ${ver_minor})
if (PICO_RP2350 AND SECURE_BOOT_PKEY)
message(STATUS "Setting rollback version:\t ${ROLLBACK}")
pico_set_binary_version(${CMAKE_PROJECT_NAME} MAJOR ${ver_major} MINOR ${ver_minor} ROLLBACK ${ROLLBACK})
else()
pico_set_binary_version(${CMAKE_PROJECT_NAME} MAJOR ${ver_major} MINOR ${ver_minor})
endif()
endif()
SET(${MAJOR} ${ver_major})
SET(${MINOR} ${ver_minor})
set(${MAJOR} ${ver_major})
set(${MINOR} ${ver_minor})
endmacro(SET_VERSION)

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -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)

View File

@@ -1,5 +1,5 @@
## IDF Component Manager Manifest File
dependencies:
espressif/esp_tinyusb: "^1.7.2"
espressif/esp_tinyusb: "^1.7.6"
#espressif/tinyusb: "^0.15.0"
zorxx/neopixel: "^1.0.4"

View File

@@ -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)

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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
}
]
}

1
mlkem Submodule

Submodule mlkem added at 1453da5cd1

View File

@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
include(pico-keys-sdk/cmake/version.cmake)
include(pico-keys-sdk/cmake/version.cmake OPTIONAL)
option(VIDPID "Set specific VID/PID from a known platform {NitroHSM, NitroFIDO2, NitroStart, NitroPro, Nitro3, Yubikey5, YubikeyNeo, YubiHSM, Gnuk, GnuPG}" "None")
@@ -64,12 +64,12 @@ if(ESP_PLATFORM)
endif()
if(NOT DEFINED USB_VID)
set(USB_VID 0xFEFF)
set(USB_VID 0x2E8A)
endif()
add_definitions(-DUSB_VID=${USB_VID})
if(NOT DEFINED USB_PID)
set(USB_PID 0xFCFD)
set(USB_PID 0x10FD)
endif()
add_definitions(-DUSB_PID=${USB_PID})
@@ -109,6 +109,8 @@ endif()
message(STATUS "USB VID/PID:\t\t\t ${USB_VID}:${USB_PID}")
if(NOT ESP_PLATFORM)
set(NEED_UPDATE OFF)
option(ENABLE_EDDSA "Enable/disable EdDSA support" OFF)
if(ENABLE_EDDSA)
message(STATUS "EdDSA support:\t\t enabled")
@@ -117,49 +119,69 @@ if(NOT ESP_PLATFORM)
endif(ENABLE_EDDSA)
set(MBEDTLS_PATH "${CMAKE_SOURCE_DIR}/pico-keys-sdk/mbedtls")
if(ENABLE_EDDSA)
set(MBEDTLS_ORIGIN "https://github.com/polhenarejos/mbedtls.git")
set(MBEDTLS_REF "mbedtls-3.6-eddsa")
add_definitions(-DMBEDTLS_ECP_DP_ED25519_ENABLED=1 -DMBEDTLS_ECP_DP_ED448_ENABLED=1 -DMBEDTLS_EDDSA_C=1 -DMBEDTLS_SHA3_C=1)
else()
set(MBEDTLS_ORIGIN "https://github.com/Mbed-TLS/mbedtls.git")
set(MBEDTLS_REF "v3.6.5")
endif()
execute_process(
COMMAND git config --global --add safe.directory ${MBEDTLS_PATH}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_QUIET ERROR_QUIET
)
execute_process(
COMMAND git -C ${MBEDTLS_PATH} submodule update --init --recursive pico-keys-sdk
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_QUIET ERROR_QUIET
)
if(ENABLE_EDDSA)
set(MBEDTLS_ORIGIN "https://github.com/polhenarejos/mbedtls.git")
set(MBEDTLS_REF "mbedtls-3.6-eddsa")
execute_process(
COMMAND git -C ${MBEDTLS_PATH} remote get-url origin
OUTPUT_VARIABLE CURRENT_ORIGIN
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND git -C ${MBEDTLS_PATH} symbolic-ref --quiet --short HEAD
OUTPUT_VARIABLE CURRENT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE BRANCH_ERR
)
message(STATUS "Current branch for mbedTLS: ${CURRENT_BRANCH}")
message(STATUS "Target branch for mbedTLS: ${MBEDTLS_REF}")
if(NOT BRANCH_ERR EQUAL 0 OR NOT "${CURRENT_BRANCH}" STREQUAL "${MBEDTLS_REF}")
set(NEED_UPDATE ON)
else()
set(NEED_UPDATE OFF)
endif()
add_definitions(-DMBEDTLS_ECP_DP_ED25519_ENABLED=1 -DMBEDTLS_ECP_DP_ED448_ENABLED=1 -DMBEDTLS_EDDSA_C=1 -DMBEDTLS_SHA3_C=1)
else()
set(MBEDTLS_ORIGIN "https://github.com/Mbed-TLS/mbedtls.git")
set(MBEDTLS_REF "v3.6.5")
execute_process(
COMMAND git -C ${MBEDTLS_PATH} describe --tags --exact-match
OUTPUT_VARIABLE CURRENT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE TAG_ERR
)
message(STATUS "Current tag for mbedTLS: ${CURRENT_TAG}")
message(STATUS "Target tag for mbedTLS: ${MBEDTLS_REF}")
if(NOT TAG_ERR EQUAL 0 OR NOT "${CURRENT_TAG}" STREQUAL "${MBEDTLS_REF}")
set(NEED_UPDATE ON)
else()
set(NEED_UPDATE OFF)
endif()
endif()
if(NEED_UPDATE)
message(STATUS "Updating mbedTLS source code...")
execute_process(
COMMAND git -C ${MBEDTLS_PATH} submodule update --init --recursive --remote pico-keys-sdk
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_QUIET ERROR_QUIET
)
if(NOT "${CURRENT_ORIGIN}" STREQUAL "${MBEDTLS_ORIGIN}")
execute_process(
COMMAND git -C ${MBEDTLS_PATH} remote set-url origin ${MBEDTLS_ORIGIN}
OUTPUT_QUIET ERROR_QUIET
)
endif()
execute_process(
COMMAND git -C ${MBEDTLS_PATH} rev-parse --verify ${MBEDTLS_REF}
OUTPUT_VARIABLE CURRENT_REF
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE REF_EXISTS
)
if(NOT REF_EXISTS EQUAL 0 OR NOT CURRENT_REF STREQUAL "${MBEDTLS_REF}")
execute_process(
COMMAND git -C ${MBEDTLS_PATH} fetch origin +refs/heads/*:refs/remotes/origin/* --tags --force
@@ -186,10 +208,19 @@ if(NOT ESP_PLATFORM)
OUTPUT_QUIET ERROR_QUIET
)
endif()
else()
message(STATUS "mbedTLS source code is up to date.")
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
@@ -222,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
@@ -237,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
@@ -295,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
@@ -304,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)
@@ -380,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
@@ -400,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)
@@ -427,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)

View File

@@ -1,5 +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
)

View File

@@ -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;
}

View File

@@ -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

28
src/fs/files.c Normal file
View File

@@ -0,0 +1,28 @@
/*
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "file.h"
file_t file_entries[] = {
/* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL,
.ef_structure = 0, .acl = { 0 } }, // MF
/* 1 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_NOT_KNOWN, .data = NULL,
.ef_structure = 0, .acl = { 0 } } //end
};
const file_t *MF = &file_entries[0];
const file_t *file_last = &file_entries[sizeof(file_entries) / sizeof(file_t) - 1];

View File

@@ -22,6 +22,7 @@
#include "pico_keys.h"
#include <string.h>
#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,40 @@ 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));
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 *)&pm, sizeof(phymarker_t));
restore_interrupts(ints);
}
#endif

View File

@@ -327,6 +327,7 @@ void init_otp_files() {
if (ret != 0) {
printf("Error writing OTP key 2 [%d]\n", ret);
}
mbedtls_platform_zeroize(pkey, sizeof(pkey));
#ifdef PICO_RP2350
otp_chaff(OTP_KEY_2, 32);
#endif

View File

@@ -116,6 +116,7 @@ void led_init() {
#if defined(PIMORONI_TINY2040) || defined(PIMORONI_TINY2350)
led_driver = &led_driver_pimoroni;
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_PIMORONI;
phy_data.led_gpio = phy_data.led_gpio_present ? phy_data.led_gpio : PICO_DEFAULT_LED_PIN;
#elif defined(CYW43_WL_GPIO_LED_PIN)
led_driver = &led_driver_cyw43;
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_CYW43;

View File

@@ -18,9 +18,9 @@
#include "pico_keys.h"
#ifdef PICO_DEFAULT_LED_PIN
uint8_t gpio = PICO_DEFAULT_LED_PIN;
static uint8_t gpio = PICO_DEFAULT_LED_PIN;
#else
uint8_t gpio = 0;
static uint8_t gpio = 0;
#endif
#ifdef PICO_PLATFORM

View File

@@ -18,18 +18,10 @@
#include "pico_keys.h"
#ifdef PICO_PLATFORM
#ifdef PIMORONI_TINY2040
#define LED_R_PIN TINY2040_LED_R_PIN
#define LED_G_PIN TINY2040_LED_G_PIN
#define LED_B_PIN TINY2040_LED_B_PIN
#elif defined(PIMORONI_TINY2350)
#define LED_R_PIN TINY2350_LED_R_PIN
#define LED_G_PIN TINY2350_LED_G_PIN
#define LED_B_PIN TINY2350_LED_B_PIN
#ifdef PICO_DEFAULT_LED_PIN
static uint8_t gpio = PICO_DEFAULT_LED_PIN;
#else
#define LED_R_PIN 0
#define LED_G_PIN 0
#define LED_B_PIN 0
static uint8_t gpio = 0;
#endif
uint8_t pixel[][3] = {
@@ -44,21 +36,24 @@ uint8_t pixel[][3] = {
};
void led_driver_init_pimoroni() {
gpio_init(LED_R_PIN);
gpio_set_dir(LED_R_PIN, GPIO_OUT);
gpio_init(LED_G_PIN);
gpio_set_dir(LED_G_PIN, GPIO_OUT);
gpio_init(LED_B_PIN);
gpio_set_dir(LED_B_PIN, GPIO_OUT);
if (phy_data.led_gpio_present) {
gpio = phy_data.led_gpio;
}
gpio_init(gpio-1);
gpio_set_dir(gpio-1, GPIO_OUT);
gpio_init(gpio);
gpio_set_dir(gpio, GPIO_OUT);
gpio_init(gpio+1);
gpio_set_dir(gpio+1, GPIO_OUT);
}
void led_driver_color_pimoroni(uint8_t color, uint32_t led_brightness, float progress) {
if (progress < 0.5) {
color = LED_COLOR_OFF;
}
gpio_put(LED_R_PIN, pixel[color][0]);
gpio_put(LED_G_PIN, pixel[color][1]);
gpio_put(LED_B_PIN, pixel[color][2]);
gpio_put(gpio-1, pixel[color][0]);
gpio_put(gpio, pixel[color][1]);
gpio_put(gpio+1, pixel[color][2]);
}
led_driver_t led_driver_pimoroni = {

View File

@@ -58,7 +58,7 @@ const uint8_t *ccid_atr = NULL;
bool app_exists(const uint8_t *aid, size_t aid_len) {
for (int a = 0; a < num_apps; a++) {
if (apps[a].aid[0] == aid_len && !memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
if (aid_len >= apps[a].aid[0] && !memcmp(apps[a].aid + 1, aid, apps[a].aid[0])) {
return true;
}
}
@@ -79,14 +79,14 @@ int register_app(int (*select_aid)(app_t *, uint8_t), const uint8_t *aid) {
}
int select_app(const uint8_t *aid, size_t aid_len) {
if (current_app && current_app->aid && current_app->aid[0] == aid_len && (current_app->aid + 1 == aid || !memcmp(current_app->aid + 1, aid, MIN(current_app->aid[0], aid_len)))) {
if (current_app && current_app->aid && (current_app->aid + 1 == aid || (aid_len >= current_app->aid[0] && !memcmp(current_app->aid + 1, aid, current_app->aid[0])))) {
current_app->select_aid(current_app, 0);
return PICOKEY_OK;
}
for (int a = 0; a < num_apps; a++) {
if (apps[a].aid[0] == aid_len && !memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
if (aid_len >= apps[a].aid[0] && !memcmp(apps[a].aid + 1, aid, apps[a].aid[0])) {
if (current_app) {
if (current_app->aid && !memcmp(current_app->aid + 1, aid, MIN(current_app->aid[0], aid_len))) {
if (current_app->aid && aid_len >= current_app->aid[0] && !memcmp(current_app->aid + 1, aid, current_app->aid[0])) {
current_app->select_aid(current_app, 1);
return PICOKEY_OK;
}
@@ -197,12 +197,15 @@ bool button_pressed_state = false;
uint32_t button_pressed_time = 0;
uint8_t button_press = 0;
bool wait_button() {
uint32_t button_timeout = 15000;
/* Disabled by default. As LED may not be properly configured,
it will not be possible to indicate button press unless it
is commissioned. */
uint32_t button_timeout = 0;
if (phy_data.up_btn_present) {
button_timeout = phy_data.up_btn * 1000;
if (button_timeout == 0) {
return false;
}
}
if (button_timeout == 0) {
return false;
}
uint32_t start_button = board_millis();
bool timeout = false;
@@ -232,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() {
@@ -244,7 +281,7 @@ void init_rtc() {
#endif
}
extern void neug_task();
extern void hwrng_task();
extern void usb_task();
void execute_tasks()
{
@@ -258,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
@@ -361,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

View File

@@ -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 <sys/time.h>
#include <time.h>
#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

View File

@@ -18,7 +18,7 @@
#ifndef __VERSION_H_
#define __VERSION_H_
#define PICO_KEYS_SDK_VERSION 0x0800
#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)

View File

@@ -19,9 +19,14 @@
#include "apdu.h"
#include "pico_keys_version.h"
#include "otp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "random.h"
#include "crypto_utils.h"
#ifdef PICO_PLATFORM
#include "pico/bootrom.h"
#include "hardware/watchdog.h"
extern char __flash_binary_start;
extern char __flash_binary_end;
#endif
int rescue_process_apdu();
@@ -42,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;
@@ -54,6 +61,8 @@ int rescue_select(app_t *a, uint8_t force) {
res_APDU[res_APDU_size++] = PICO_PRODUCT;
res_APDU[res_APDU_size++] = PICO_VERSION_MAJOR;
res_APDU[res_APDU_size++] = PICO_VERSION_MINOR;
memcpy(res_APDU + res_APDU_size, pico_serial.id, sizeof(pico_serial.id));
res_APDU_size += sizeof(pico_serial.id);
apdu.ne = res_APDU_size;
if (force) {
scan_flash();
@@ -69,12 +78,153 @@ 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) {
int ret = load_internal_keydev(&ecp, ec_id);
if (ret != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ecp);
return ret;
}
}
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(ec_id)->bit_size + 7) / 8);
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
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_ecp_keypair_free(&ecp);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
return SW_EXEC_ERROR();
}
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_ecp_keypair_free(&ecp);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
}
else if (p1 == 0x02) {
// Return public key
if (apdu.nc != 0) {
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) {
int ret = load_internal_keydev(&ecp, ec_id);
if (ret != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ecp);
return ret;
}
}
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);
if (ret != 0) {
mbedtls_ecp_keypair_free(&ecp);
return SW_EXEC_ERROR();
}
res_APDU_size = (uint16_t)olen;
mbedtls_ecp_keypair_free(&ecp);
}
else if (p1 == 0x03) {
// Upload device attestation certificate
if (apdu.nc == 0) {
return SW_WRONG_LENGTH();
}
file_t *ef_devcert = file_new(0x2F02); // EF_DEVCERT
if (!ef_devcert) {
return SW_FILE_NOT_FOUND();
}
file_put_data(ef_devcert, apdu.data, (uint16_t)apdu.nc);
res_APDU_size = 0;
low_flash_available();
}
else {
return SW_INCORRECT_P1P2();
}
return SW_OK();
}
// Blocking CORE1
void led_3_blinks() {
#ifndef ENABLE_EMULATION
uint32_t mode = led_get_mode();
led_set_mode(MODE_PROCESSING);
sleep_ms(500);
led_set_mode(mode);
#endif
}
int cmd_write() {
if (apdu.nc < 2) {
return SW_WRONG_LENGTH();
}
if (P1(apdu) == 0x1) { // PHY
uint8_t p1 = P1(apdu), p2 = P2(apdu);
if (p1 == 0x1) { // PHY
#ifndef ENABLE_EMULATION
int ret = phy_unserialize_data(apdu.data, (uint16_t)apdu.nc, &phy_data);
if (ret == PICOKEY_OK) {
@@ -84,6 +234,35 @@ int cmd_write() {
}
#endif
}
else if (p1 == 0x2) { // SET TIME
time_t tv_sec = 0;
if (p2 != 0x1 && p2 != 0x2) {
return SW_INCORRECT_P1P2();
}
if (p2 == 0x1) {
if (apdu.nc != 8) {
return SW_WRONG_LENGTH();
}
struct tm tm;
tm.tm_year = get_uint16_t_be(apdu.data) - 1900;
tm.tm_mon = apdu.data[2];
tm.tm_mday = apdu.data[3];
tm.tm_wday = apdu.data[4];
tm.tm_hour = apdu.data[5];
tm.tm_min = apdu.data[6];
tm.tm_sec = apdu.data[7];
tv_sec = mktime(&tm);
}
else if (p2 == 0x2) {
if (apdu.nc != 4) {
return SW_WRONG_LENGTH();
}
uint32_t t = (apdu.data[0] << 24) | (apdu.data[1] << 16) | (apdu.data[2] << 8) | apdu.data[3];
tv_sec = (time_t)t;
}
set_rtc_time(tv_sec);
}
led_3_blinks();
return SW_OK();
}
@@ -92,7 +271,7 @@ int cmd_read() {
return SW_WRONG_LENGTH();
}
uint8_t p1 = P1(apdu);
uint8_t p1 = P1(apdu), p2 = P2(apdu);
if (p1 == 0x1) { // PHY
#ifndef ENABLE_EMULATION
uint16_t len = 0;
@@ -111,6 +290,12 @@ int cmd_read() {
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);
#ifdef PICO_PLATFORM
uintptr_t start = (uintptr_t) &__flash_binary_start;
uintptr_t end = (uintptr_t) &__flash_binary_end;
uint32_t fw_size = (uint32_t)(end - start);
res_APDU_size += put_uint32_t_be(fw_size, res_APDU + res_APDU_size);
#endif
}
else if (p1 == 0x3) { // OTP SECURE BOOT STATUS
res_APDU_size = 0;
@@ -121,6 +306,34 @@ int cmd_read() {
res_APDU[res_APDU_size++] = locked ? 0x1 : 0x0;
res_APDU[res_APDU_size++] = bootkey;
}
else if (p1 == 0x4) { // GET TIME
if (p2 != 0x1 && p2 != 0x2) {
return SW_INCORRECT_P1P2();
}
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 = {.tv_sec = tv_sec, .tv_nsec = 0};
#else
struct timeval tv = {.tv_sec = tv_sec, .tv_usec = 0};
#endif
if (p2 == 0x1) {
struct tm *tm = localtime(&tv.tv_sec);
res_APDU_size += put_uint16_t_be(tm->tm_year + 1900, res_APDU);
res_APDU[res_APDU_size++] = tm->tm_mon;
res_APDU[res_APDU_size++] = tm->tm_mday;
res_APDU[res_APDU_size++] = tm->tm_wday;
res_APDU[res_APDU_size++] = tm->tm_hour;
res_APDU[res_APDU_size++] = tm->tm_min;
res_APDU[res_APDU_size++] = tm->tm_sec;
}
else if (p2 == 0x2) {
res_APDU_size += put_uint32_t_be((uint32_t)tv.tv_sec, res_APDU);
}
}
return SW_OK();
}
@@ -137,6 +350,7 @@ int cmd_secure() {
if (ret != 0) {
return SW_EXEC_ERROR();
}
led_3_blinks();
return SW_OK();
}
#endif
@@ -163,12 +377,14 @@ int cmd_reboot_bootsel() {
}
#endif
#define INS_KEYDEV_SIGN 0x10
#define INS_WRITE 0x1C
#define INS_SECURE 0x1D
#define INS_READ 0x1E
#define INS_REBOOT_BOOTSEL 0x1F
static const cmd_t cmds[] = {
{ INS_KEYDEV_SIGN, cmd_keydev_sign },
{ INS_WRITE, cmd_write },
#if defined(PICO_RP2350) || defined(ESP_PLATFORM)
{ INS_SECURE, cmd_secure },

View File

@@ -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();
}
}

View File

@@ -17,17 +17,11 @@
#ifndef _NEUG_H_
#define _NEUG_H_
#include <stdint.h>
#define NEUG_PRE_LOOP 32
#include <stdlib.h>
#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

View File

@@ -15,8 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define HWRNG_PRE_LOOP 32
#include <stdint.h>
#include <stdlib.h>
#if defined(PICO_PLATFORM)
#include "pico/stdlib.h"
#endif
#include <string.h>
#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

View File

@@ -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);

View File

@@ -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;

View File

@@ -28,14 +28,14 @@
#include "usb.h"
#ifndef USB_VID
#define USB_VID 0xFEFF
#define USB_VID 0x2E8A
#endif
#ifndef USB_PID
#define USB_PID 0xFCFD
#define USB_PID 0x10FD
#endif
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
#define USB_BCD 0x0200
#define USB_BCD 0x0210
#else
#define USB_BCD 0x0110
#endif
@@ -107,7 +107,7 @@ uint8_t const desc_hid_report_kb[] = {
#endif
enum {
EPNUM_DUMMY = 1,
EPNUM_DUMMY = 0,
#ifdef USB_ITF_CCID
EPNUM_CCID,
#if TUSB_SMARTCARD_CCID_EPS == 3
@@ -136,7 +136,7 @@ enum {
#if TUSB_SMARTCARD_CCID_EPS == 3
#define TUD_SMARTCARD_DESCRIPTOR(_itf, _strix, _epout, _epin, _epint, _epsize) \
TUD_SMARTCARD_DESCRIPTOR_2EP(_itf, _strix, _epout, _epin, _epsize), \
7, TUSB_DESC_ENDPOINT, _epint, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), 0
7, TUSB_DESC_ENDPOINT, _epint, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), 10
#else
#define TUD_SMARTCARD_DESCRIPTOR(_itf, _strix, _epout, _epin, _epint, _epsize) \
TUD_SMARTCARD_DESCRIPTOR_2EP(_itf, _strix, _epout, _epin, _epsize)
@@ -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)
"Pol Henarejos", // 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) {

23
src/version.c Normal file
View File

@@ -0,0 +1,23 @@
/*
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "pico_keys.h"
#include "pico_keys_version.h"
const uint8_t PICO_PRODUCT = 0;
const uint8_t PICO_VERSION_MAJOR = PICO_KEYS_SDK_VERSION_MAJOR;
const uint8_t PICO_VERSION_MINOR = PICO_KEYS_SDK_VERSION_MINOR;