mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-28 17:11:23 +02:00
Compare commits
78 Commits
v7.0
...
113e720fca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
113e720fca | ||
|
|
c45c97ee1f | ||
|
|
d66d1c85b9 | ||
|
|
f01aca5518 | ||
|
|
da3a7f25d0 | ||
|
|
eb75ad4efa | ||
|
|
11d8a5343c | ||
|
|
a324477a8a | ||
|
|
580b0acffa | ||
|
|
3990e7643a | ||
|
|
5718c83083 | ||
|
|
a75fd6b815 | ||
|
|
499e8fafaa | ||
|
|
5f79a8c8ed | ||
|
|
a08abaed0f | ||
|
|
4ef641b8d3 | ||
|
|
c185b35ca3 | ||
|
|
f1b1382300 | ||
|
|
f18f761234 | ||
|
|
1a4ca13cc7 | ||
|
|
ef9b66f990 | ||
|
|
7191cda6d3 | ||
|
|
2c3fe5bebf | ||
|
|
9e9632f297 | ||
|
|
259c4854df | ||
|
|
0a4c7b0981 | ||
|
|
db338842b9 | ||
|
|
71af710568 | ||
|
|
e18f192edf | ||
|
|
07415e6e8b | ||
|
|
a9eff9fb17 | ||
|
|
6e6b524878 | ||
|
|
bfa085cae9 | ||
|
|
94a842fa04 | ||
|
|
90fb86be64 | ||
|
|
f06cb3a96d | ||
|
|
5985548c97 | ||
|
|
3f5cbf6542 | ||
|
|
29c0d078c3 | ||
|
|
1723613b4e | ||
|
|
44ca760e1c | ||
|
|
4992d8e273 | ||
|
|
80fa13a19c | ||
|
|
b4c67d2fa5 | ||
|
|
18eb3e6ef2 | ||
|
|
350f0da763 | ||
|
|
a081a2bde6 | ||
|
|
3d912878f1 | ||
|
|
68a816895e | ||
|
|
1d89c14268 | ||
|
|
5508c082e5 | ||
|
|
0bed03e522 | ||
|
|
9e2b6ac4b6 | ||
|
|
046bac42e3 | ||
|
|
c59fb91540 | ||
|
|
f8cb36c2cf | ||
|
|
d78e977926 | ||
|
|
8e68e6cae9 | ||
|
|
d530ea6979 | ||
|
|
f509833a3c | ||
|
|
4f5f2a8854 | ||
|
|
ffaf20da5d | ||
|
|
e627b3fc86 | ||
|
|
585a6d77e3 | ||
|
|
7805131d92 | ||
|
|
86999d8cdd | ||
|
|
6859cedcbf | ||
|
|
1431f91281 | ||
|
|
f58bcaecf1 | ||
|
|
cb4e2ba0eb | ||
|
|
e9875b358c | ||
|
|
fcae98eecc | ||
|
|
a61f7683b6 | ||
|
|
a271785814 | ||
|
|
49758c6ac7 | ||
|
|
9f79693025 | ||
|
|
812f075ee4 | ||
|
|
6a18e3aa83 |
@@ -1,70 +0,0 @@
|
||||
include(pico-keys-sdk/cmake/dict.cmake)
|
||||
|
||||
dict(SET led_driver 0xcb_helios led_ws2812)
|
||||
dict(SET led_driver adafruit_feather_rp2040_usb_host led_pico)
|
||||
dict(SET led_driver adafruit_feather_rp2040 led_ws2812)
|
||||
dict(SET led_driver adafruit_itsybitsy_rp2040 led_ws2812)
|
||||
dict(SET led_driver adafruit_kb2040 led_ws2812)
|
||||
dict(SET led_driver adafruit_macropad_rp2040 led_ws2812)
|
||||
dict(SET led_driver adafruit_qtpy_rp2040 led_ws2812)
|
||||
dict(SET led_driver adafruit_trinkey_qt2040 led_ws2812)
|
||||
dict(SET led_driver amethyst_fpga led_pico)
|
||||
dict(SET led_driver archi led_ws2812)
|
||||
dict(SET led_driver arduino_nano_rp2040_connect led_pico)
|
||||
dict(SET led_driver cytron_maker_pi_rp2040 led_ws2812)
|
||||
dict(SET led_driver datanoisetv_rp2040_dsp led_pico)
|
||||
dict(SET led_driver eetree_gamekit_rp2040 led_pico)
|
||||
dict(SET led_driver garatronic_pybstick26_rp2040 led_pico)
|
||||
dict(SET led_driver ilabs_challenger_rp2350_bconnect led_ws2812)
|
||||
dict(SET led_driver ilabs_challenger_rp2350_wifi_ble led_pico)
|
||||
dict(SET led_driver ilabs_opendec02 led_pico)
|
||||
dict(SET led_driver melopero_perpetuo_rp2350_lora led_pico)
|
||||
dict(SET led_driver melopero_shake_rp2040 led_ws2812)
|
||||
dict(SET led_driver metrotech_xerxes_rp2040 led_pico)
|
||||
dict(SET led_driver net8086_usb_interposer led_pico)
|
||||
dict(SET led_driver nullbits_bit_c_pro led_pico) # rgb
|
||||
dict(SET led_driver phyx_rick_tny_rp2350 led_ws2812)
|
||||
dict(SET led_driver pi-plates_micropi led_pico)
|
||||
dict(SET led_driver pico led_pico)
|
||||
dict(SET led_driver pico_w led_cyw43)
|
||||
dict(SET led_driver pico2 led_pico)
|
||||
dict(SET led_driver pimoroni_badger2040 led_pico)
|
||||
dict(SET led_driver pimoroni_interstate75 led_pico) # rgb
|
||||
dict(SET led_driver pimoroni_motor2040 led_ws2812)
|
||||
dict(SET led_driver pimoroni_pga2350 led_pico)
|
||||
dict(SET led_driver pimoroni_pico_plus2_rp2350 led_pico)
|
||||
dict(SET led_driver pimoroni_picolipo_4mb led_pico)
|
||||
dict(SET led_driver pimoroni_picolipo_16mb led_pico)
|
||||
dict(SET led_driver pimoroni_picosystem led_pico) # rgb
|
||||
dict(SET led_driver pimoroni_plasma2040 led_pico) # rgb
|
||||
dict(SET led_driver pimoroni_plasma2350 led_pico) # rgb
|
||||
dict(SET led_driver pimoroni_servo2040 led_ws2812)
|
||||
dict(SET led_driver pimoroni_tiny2040 led_pimoroni)
|
||||
dict(SET led_driver pimoroni_tiny2040_2mb led_pimoroni)
|
||||
dict(SET led_driver pimoroni_tiny2350 led_pimoroni)
|
||||
dict(SET led_driver pololu_3pi_2040_robot led_pico)
|
||||
dict(SET led_driver pololu_zumo_2040_robot led_pico)
|
||||
dict(SET led_driver seeed_xiao_rp2040 led_ws2812)
|
||||
dict(SET led_driver seeed_xiao_rp2350 led_ws2812)
|
||||
dict(SET led_driver solderparty_rp2040_stamp led_ws2812)
|
||||
dict(SET led_driver solderparty_rp2040_stamp_carrier led_ws2812)
|
||||
dict(SET led_driver solderparty_rp2040_stamp_round_carrier led_ws2812)
|
||||
dict(SET led_driver sparkfun_micromod led_pico)
|
||||
dict(SET led_driver sparkfun_promicro led_ws2812)
|
||||
dict(SET led_driver sparkfun_promicro_rp2350 led_ws2812)
|
||||
dict(SET led_driver sparkfun_thingplus led_ws2812)
|
||||
dict(SET led_driver switchscience_picossci2_conta_base led_pico)
|
||||
dict(SET led_driver switchscience_picossci2_dev_board led_pico)
|
||||
dict(SET led_driver switchscience_picossci2_rp2350_breakout led_pico)
|
||||
dict(SET led_driver switchscience_picossci2_tiny led_pico)
|
||||
dict(SET led_driver tinycircuits_thumby_color_rp2350 led_pico)
|
||||
dict(SET led_driver vgaboard led_pico)
|
||||
dict(SET led_driver waveshare_rp2040_one led_ws2812)
|
||||
dict(SET led_driver waveshare_rp2040_plus_4mb led_pico)
|
||||
dict(SET led_driver waveshare_rp2040_plus_16mb led_pico)
|
||||
dict(SET led_driver waveshare_rp2040_zero led_ws2812)
|
||||
dict(SET led_driver weact_studio_rp2040_2mb led_pico)
|
||||
dict(SET led_driver weact_studio_rp2040_4mb led_pico)
|
||||
dict(SET led_driver weact_studio_rp2040_8mb led_pico)
|
||||
dict(SET led_driver weact_studio_rp2040_16mb led_pico)
|
||||
dict(SET led_driver wiznet_w5100s_evb_pico led_pico)
|
||||
@@ -24,7 +24,8 @@
|
||||
{
|
||||
"name": "Pico Keys Data",
|
||||
"id": 1,
|
||||
"size": "3072K",
|
||||
"start": "2048K",
|
||||
"size": "2048K",
|
||||
"families": ["data"],
|
||||
"permissions": {
|
||||
"secure": "rw",
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
#
|
||||
|
||||
include(pico-keys-sdk/cmake/version.cmake)
|
||||
include(pico-keys-sdk/cmake/boards.cmake)
|
||||
|
||||
if(PICO_BOARD)
|
||||
dict(GET led_driver ${PICO_BOARD} LED_DRIVER)
|
||||
endif()
|
||||
|
||||
option(VIDPID "Set specific VID/PID from a known platform {NitroHSM, NitroFIDO2, NitroStart, NitroPro, Nitro3, Yubikey5, YubikeyNeo, YubiHSM, Gnuk, GnuPG}" "None")
|
||||
|
||||
@@ -113,6 +108,88 @@ endif()
|
||||
|
||||
message(STATUS "USB VID/PID:\t\t\t ${USB_VID}:${USB_PID}")
|
||||
|
||||
if(NOT ESP_PLATFORM)
|
||||
option(ENABLE_EDDSA "Enable/disable EdDSA support" OFF)
|
||||
if(ENABLE_EDDSA)
|
||||
message(STATUS "EdDSA support:\t\t enabled")
|
||||
else()
|
||||
message(STATUS "EdDSA support:\t\t disabled")
|
||||
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.3")
|
||||
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
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND git -C ${MBEDTLS_PATH} remote get-url origin
|
||||
OUTPUT_VARIABLE CURRENT_ORIGIN
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
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
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND rm -rf ${MBEDTLS_PATH}/framework
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
)
|
||||
|
||||
if(ENABLE_EDDSA)
|
||||
execute_process(
|
||||
COMMAND git -C ${MBEDTLS_PATH} checkout -B ${MBEDTLS_REF} --track origin/${MBEDTLS_REF}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
)
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND git -C ${MBEDTLS_PATH} checkout ${MBEDTLS_REF}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif(NOT ESP_PLATFORM)
|
||||
|
||||
set(MBEDTLS_SOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aes.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/asn1parse.c
|
||||
@@ -153,7 +230,14 @@ set(MBEDTLS_SOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkwrite.c
|
||||
)
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
if (ENABLE_EDDSA)
|
||||
set(MBEDTLS_SOURCES ${MBEDTLS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/eddsa.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha3.c
|
||||
)
|
||||
endif()
|
||||
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
||||
@@ -169,14 +253,14 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/apdu.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/rescue.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_cyw43.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pico.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pimoroni.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_ws2812.c
|
||||
)
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
set(LED_DRIVER led_neopixel)
|
||||
endif()
|
||||
if (LED_DRIVER)
|
||||
message(STATUS "LED driver:\t\t\t ${LED_DRIVER}")
|
||||
set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/led/${LED_DRIVER}.c)
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/led/led_neopixel.c)
|
||||
endif()
|
||||
|
||||
## mbedTLS reports an stringop overflow for cmac.c
|
||||
@@ -229,8 +313,15 @@ set(LIBRARIES
|
||||
hardware_pio
|
||||
)
|
||||
|
||||
if(PICO_BOARD STREQUAL "pico_w")
|
||||
set(LIBRARIES ${LIBRARIES} pico_cyw43_arch_none)
|
||||
set(IS_CYW43 0)
|
||||
if (NOT ENABLE_EMULATION AND NOT ESP_PLATFORM)
|
||||
file(READ ${PICO_SDK_PATH}/src/boards/include/boards/${PICO_BOARD}.h content)
|
||||
string(REGEX MATCHALL "CYW43_WL_GPIO_LED_PIN" _ ${content})
|
||||
if (CMAKE_MATCH_0)
|
||||
message(STATUS "Found cyw43 LED:\t\t true")
|
||||
set(LIBRARIES ${LIBRARIES} pico_cyw43_arch_none)
|
||||
set(IS_CYW43 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
function(add_impl_library target)
|
||||
@@ -238,24 +329,37 @@ function(add_impl_library target)
|
||||
string(TOUPPER ${target} TARGET_UPPER)
|
||||
target_compile_definitions(${target} INTERFACE LIB_${TARGET_UPPER}=1)
|
||||
endfunction()
|
||||
if(${USB_ITF_HID})
|
||||
set(SOURCES ${SOURCES}
|
||||
|
||||
if(USB_ITF_HID)
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c
|
||||
)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/hid
|
||||
)
|
||||
endif()
|
||||
|
||||
if(USB_ITF_CCID)
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c
|
||||
)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions("-fmacro-prefix-map=${CMAKE_CURRENT_LIST_DIR}/=")
|
||||
|
||||
if(ENABLE_EMULATION)
|
||||
if(APPLE)
|
||||
add_definitions("-Wno-deprecated-declarations")
|
||||
elseif(MSVC)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/mman.c
|
||||
)
|
||||
endif()
|
||||
add_definitions(-DENABLE_EMULATION)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/emulation.c
|
||||
)
|
||||
set(MBEDTLS_SOURCES ${MBEDTLS_SOURCES}
|
||||
@@ -265,15 +369,7 @@ if(ENABLE_EMULATION)
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation
|
||||
)
|
||||
else()
|
||||
if(USB_ITF_CCID)
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c
|
||||
)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid
|
||||
)
|
||||
endif()
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c
|
||||
)
|
||||
endif()
|
||||
@@ -306,7 +402,9 @@ endif()
|
||||
if(PICO_RP2350)
|
||||
pico_set_uf2_family(${CMAKE_PROJECT_NAME} "rp2350-arm-s")
|
||||
pico_embed_pt_in_binary(${CMAKE_PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/config/rp2350/pt.json")
|
||||
pico_set_binary_type(${CMAKE_PROJECT_NAME} copy_to_ram)
|
||||
if (NOT IS_CYW43)
|
||||
pico_set_binary_type(${CMAKE_PROJECT_NAME} copy_to_ram)
|
||||
endif()
|
||||
if (SECURE_BOOT_PKEY)
|
||||
message(STATUS "Secure Boot Key ${SECURE_BOOT_PKEY}")
|
||||
pico_sign_binary(${CMAKE_PROJECT_NAME} ${SECURE_BOOT_PKEY})
|
||||
@@ -317,23 +415,22 @@ if(PICO_RP2350)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt
|
||||
)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt/sha256_alt.c
|
||||
)
|
||||
set(LIBRARIES ${LIBRARIES} pico_sha256)
|
||||
endif()
|
||||
set(INTERNAL_SOURCES ${SOURCES})
|
||||
set(SOURCES ${SOURCES} ${EXTERNAL_SOURCES})
|
||||
set(INTERNAL_SOURCES ${PICO_KEYS_SOURCES})
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${EXTERNAL_SOURCES})
|
||||
if(NOT TARGET pico_keys_sdk)
|
||||
if(ENABLE_EMULATION OR ESP_PLATFORM)
|
||||
add_impl_library(pico_keys_sdk)
|
||||
else()
|
||||
pico_add_library(pico_keys_sdk)
|
||||
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
|
||||
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${LIBRARIES})
|
||||
endif()
|
||||
target_sources(pico_keys_sdk INTERFACE ${SOURCES})
|
||||
target_sources(pico_keys_sdk INTERFACE ${PICO_KEYS_SOURCES})
|
||||
target_include_directories(pico_keys_sdk INTERFACE ${INCLUDES})
|
||||
target_link_libraries(pico_keys_sdk INTERFACE ${LIBRARIES})
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
idf_component_register(
|
||||
SRCS ${INTERNAL_SOURCES}
|
||||
INCLUDE_DIRS . fs rng usb led ../mbedtls/include ../tinycbor/src
|
||||
REQUIRES bootloader_support esp_partition esp_tinyusb efuse
|
||||
SRCS ${PICO_KEYS_SOURCES}
|
||||
INCLUDE_DIRS . fs rng usb led ../tinycbor/src
|
||||
REQUIRES bootloader_support esp_partition esp_tinyusb efuse mbedtls
|
||||
)
|
||||
|
||||
20
src/apdu.c
20
src/apdu.c
@@ -85,17 +85,17 @@ uint16_t apdu_process(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size)
|
||||
}
|
||||
else if (apdu.header[4] == 0x0 && buffer_size >= 7) {
|
||||
if (buffer_size == 7) {
|
||||
apdu.ne = (apdu.header[5] << 8) | apdu.header[6];
|
||||
apdu.ne = get_uint16_t_be(apdu.header + 5);
|
||||
if (apdu.ne == 0) {
|
||||
apdu.ne = 65536;
|
||||
}
|
||||
}
|
||||
else {
|
||||
apdu.ne = 0;
|
||||
apdu.nc = (apdu.header[5] << 8) | apdu.header[6];
|
||||
apdu.nc = get_uint16_t_be(apdu.header + 5);
|
||||
apdu.data = apdu.header + 7;
|
||||
if (apdu.nc + 7 + 2 == buffer_size) {
|
||||
apdu.ne = (apdu.header[buffer_size - 2] << 8) | apdu.header[buffer_size - 1];
|
||||
apdu.ne = get_uint16_t_be(apdu.header + buffer_size - 2);
|
||||
if (apdu.ne == 0) {
|
||||
apdu.ne = 65536;
|
||||
}
|
||||
@@ -175,11 +175,11 @@ uint16_t apdu_process(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size)
|
||||
}
|
||||
|
||||
uint16_t set_res_sw(uint8_t sw1, uint8_t sw2) {
|
||||
apdu.sw = (sw1 << 8) | sw2;
|
||||
apdu.sw = make_uint16_t_be(sw1, sw2);
|
||||
if (sw1 != 0x90) {
|
||||
res_APDU_size = 0;
|
||||
}
|
||||
return make_uint16_t(sw1, sw2);
|
||||
return make_uint16_t_be(sw1, sw2);
|
||||
}
|
||||
|
||||
void apdu_thread(void) {
|
||||
@@ -221,13 +221,13 @@ done: ;
|
||||
}
|
||||
|
||||
void apdu_finish() {
|
||||
apdu.rdata[apdu.rlen] = apdu.sw >> 8;
|
||||
apdu.rdata[apdu.rlen + 1] = apdu.sw & 0xff;
|
||||
put_uint16_t_be(apdu.sw, apdu.rdata + apdu.rlen);
|
||||
// timeout_stop();
|
||||
#ifndef ENABLE_EMULATION
|
||||
if ((apdu.rlen + 2 + 10) % 64 == 0) { // FIX for strange behaviour with PSCS and multiple of 64
|
||||
apdu.ne = apdu.rlen - 2;
|
||||
}
|
||||
/* It was fixed in the USB handling. Keep it just in case */
|
||||
//if ((apdu.rlen + 2 + 10) % 64 == 0) { // FIX for strange behaviour with PSCS and multiple of 64
|
||||
// apdu.ne = apdu.rlen - 2;
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "compat.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct app {
|
||||
const uint8_t *aid;
|
||||
@@ -33,6 +34,7 @@ typedef struct app {
|
||||
int (*unload)();
|
||||
} app_t;
|
||||
|
||||
extern bool app_exists(const uint8_t *aid, size_t aid_len);
|
||||
extern int register_app(int (*)(app_t *, uint8_t), const uint8_t *);
|
||||
extern int select_app(const uint8_t *aid, size_t aid_len);
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ uint8_t format_tlv_len(uint16_t len, uint8_t *out) {
|
||||
}
|
||||
if (out) {
|
||||
*out++ = 0x82;
|
||||
*out++ = (len >> 8) & 0xff;
|
||||
*out++ = len & 0xff;
|
||||
put_uint16_t_be(len, out);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#if defined(DEBUG_APDU) && DEBUG_APDU == 1
|
||||
#define DEBUG_PAYLOAD(_p, _s) { \
|
||||
printf("Payload %s (%d bytes):\n", #_p, (int) (_s)); \
|
||||
printf("Payload %s (%d bytes) [%s:%d]:\n", #_p, (int) (_s), __FILE__, __LINE__); \
|
||||
for (int _i = 0; _i < _s; _i += 16) { \
|
||||
printf("%" PRIxPTR "h : ", (uintptr_t) (_i + _p)); \
|
||||
for (int _j = 0; _j < 16; _j++) { \
|
||||
@@ -37,7 +37,7 @@
|
||||
} printf("\n"); \
|
||||
}
|
||||
#define DEBUG_DATA(_p, _s) { \
|
||||
printf("Data %s (%d bytes):\n", #_p, (int) (_s)); \
|
||||
printf("Data %s (%d bytes) [%s:%d]:\n", #_p, (int) (_s), __FILE__, __LINE__); \
|
||||
char *_tmp = (char *) calloc(1, 2 * _s + 1); \
|
||||
for (int _i = 0; _i < _s; _i++) { \
|
||||
sprintf(&_tmp[2 * _i], "%02X", (_p)[_i]); \
|
||||
|
||||
13
src/eac.c
13
src/eac.c
@@ -144,7 +144,7 @@ int sm_wrap() {
|
||||
if (sm_indicator == 0) {
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
uint8_t input[4096];
|
||||
uint8_t input[2048];
|
||||
size_t input_len = 0;
|
||||
memset(input, 0, sizeof(input));
|
||||
mbedtls_mpi ssc;
|
||||
@@ -181,16 +181,15 @@ int sm_wrap() {
|
||||
else {
|
||||
memmove(res_APDU + 4, res_APDU, res_APDU_size);
|
||||
res_APDU[1] = 0x82;
|
||||
res_APDU[2] = (uint8_t)(res_APDU_size >> 8);
|
||||
res_APDU[3] = (uint8_t)(res_APDU_size & 0xff);
|
||||
put_uint16_t_be(res_APDU_size, res_APDU + 2);
|
||||
res_APDU_size += 4;
|
||||
}
|
||||
res_APDU[0] = 0x87;
|
||||
}
|
||||
res_APDU[res_APDU_size++] = 0x99;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
res_APDU[res_APDU_size++] = apdu.sw >> 8;
|
||||
res_APDU[res_APDU_size++] = apdu.sw & 0xff;
|
||||
put_uint16_t_be(apdu.sw, res_APDU + res_APDU_size);
|
||||
res_APDU_size += 2;
|
||||
memcpy(input + input_len, res_APDU, res_APDU_size);
|
||||
input_len += res_APDU_size;
|
||||
input[input_len++] = 0x80;
|
||||
@@ -233,7 +232,7 @@ void sm_update_iv() {
|
||||
}
|
||||
|
||||
int sm_verify() {
|
||||
uint8_t input[4096];
|
||||
uint8_t input[2048];
|
||||
memset(input, 0, sizeof(input));
|
||||
uint16_t input_len = 0;
|
||||
int r = 0;
|
||||
@@ -242,7 +241,7 @@ int sm_verify() {
|
||||
if (data_len % sm_blocksize) {
|
||||
data_len += sm_blocksize;
|
||||
}
|
||||
if (data_len + (add_header ? sm_blocksize : 0) > 4096) {
|
||||
if (data_len + (add_header ? sm_blocksize : 0) > sizeof(input)) {
|
||||
return PICOKEY_WRONG_LENGTH;
|
||||
}
|
||||
mbedtls_mpi ssc;
|
||||
|
||||
@@ -30,7 +30,14 @@ typedef QueueHandle_t queue_t;
|
||||
#define queue_is_empty(a) (uxQueueMessagesWaiting(*(a)) == 0)
|
||||
#define queue_try_remove(a,b) xQueueReceive(*(a), b, 0)
|
||||
extern TaskHandle_t hcore0, hcore1;
|
||||
#define multicore_launch_core1(a) xTaskCreatePinnedToCore((void(*)(void *))a, "core1", 4096*5, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 2, &hcore1, 1)
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ESP32_CORE0 0
|
||||
#define ESP32_CORE1 1
|
||||
#else
|
||||
#define ESP32_CORE0 tskNO_AFFINITY
|
||||
#define ESP32_CORE1 tskNO_AFFINITY
|
||||
#endif
|
||||
#define multicore_launch_core1(a) xTaskCreatePinnedToCore((void(*)(void *))a, "core1", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 2, &hcore1, ESP32_CORE1)
|
||||
#define multicore_reset_core1() do { if (hcore1) { eTaskState e = eTaskGetState(hcore1); if (e <= eSuspended) { vTaskDelete(hcore1); }} }while(0)
|
||||
#define sleep_ms(a) vTaskDelay(a / portTICK_PERIOD_MS)
|
||||
static inline uint32_t board_millis(void) {
|
||||
|
||||
@@ -56,13 +56,11 @@ void process_fci(const file_t *pe, int fmd) {
|
||||
if (pe->data) {
|
||||
if ((pe->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) {
|
||||
uint16_t len = (uint16_t)((int (*)(const file_t *, int))(pe->data))(pe, 0);
|
||||
res_APDU[res_APDU_size++] = (len >> 8) & 0xff;
|
||||
res_APDU[res_APDU_size++] = len & 0xff;
|
||||
res_APDU_size += put_uint16_t_be(len, res_APDU + res_APDU_size);
|
||||
}
|
||||
else {
|
||||
uint16_t v = file_get_size(pe);
|
||||
res_APDU[res_APDU_size++] = v >> 8;
|
||||
res_APDU[res_APDU_size++] = v & 0xff;
|
||||
res_APDU_size += put_uint16_t_be(v, res_APDU + res_APDU_size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -88,8 +86,7 @@ void process_fci(const file_t *pe, int fmd) {
|
||||
|
||||
res_APDU[res_APDU_size++] = 0x83;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
put_uint16_t(pe->fid, res_APDU + res_APDU_size);
|
||||
res_APDU_size += 2;
|
||||
res_APDU_size += put_uint16_t_be(pe->fid, res_APDU + res_APDU_size);
|
||||
if (pe->name) {
|
||||
res_APDU[res_APDU_size++] = 0x84;
|
||||
res_APDU[res_APDU_size++] = MIN(pe->name[0], 16);
|
||||
@@ -113,7 +110,6 @@ void process_fci(const file_t *pe, int fmd) {
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_DYNAMIC_FILES 128
|
||||
uint16_t dynamic_files = 0;
|
||||
file_t dynamic_file[MAX_DYNAMIC_FILES];
|
||||
|
||||
@@ -177,13 +173,13 @@ uint8_t make_path_buf(const file_t *pe, uint8_t *buf, uint8_t buflen, const file
|
||||
if (pe == top) { //MF or relative DF
|
||||
return 0;
|
||||
}
|
||||
put_uint16_t(pe->fid, buf);
|
||||
put_uint16_t_be(pe->fid, buf);
|
||||
return make_path_buf(&file_entries[pe->parent], buf + 2, buflen - 2, top) + 2;
|
||||
}
|
||||
|
||||
uint8_t make_path(const file_t *pe, const file_t *top, uint8_t *path) {
|
||||
uint8_t buf[MAX_DEPTH * 2], *p = path;
|
||||
put_uint16_t(pe->fid, buf);
|
||||
put_uint16_t_be(pe->fid, buf);
|
||||
uint8_t depth = make_path_buf(&file_entries[pe->parent], buf + 2, sizeof(buf) - 2, top) + 2;
|
||||
for (int d = depth - 2; d >= 0; d -= 2) {
|
||||
memcpy(p, buf + d, 2);
|
||||
@@ -245,29 +241,40 @@ void initialize_flash(bool hard) {
|
||||
dynamic_files = 0;
|
||||
}
|
||||
|
||||
void scan_region(bool persistent) {
|
||||
extern uintptr_t last_base;
|
||||
extern uint32_t num_files;
|
||||
void scan_region(bool persistent)
|
||||
{
|
||||
uintptr_t endp = end_data_pool, startp = start_data_pool;
|
||||
if (persistent) {
|
||||
endp = end_rom_pool;
|
||||
startp = start_rom_pool;
|
||||
}
|
||||
else {
|
||||
last_base = endp;
|
||||
num_files = 0;
|
||||
}
|
||||
for (uintptr_t base = flash_read_uintptr(endp); base >= startp; base = flash_read_uintptr(base)) {
|
||||
if (base == 0x0) { //all is empty
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t fid = flash_read_uint16(base + sizeof(uintptr_t) + sizeof(uintptr_t));
|
||||
printf("[%x] scan fid %x, len %d\n", (unsigned int) base, fid,
|
||||
flash_read_uint16(base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t)));
|
||||
printf("[%x] scan fid %x, len %d\n", (unsigned int) base, fid, flash_read_uint16(base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t)));
|
||||
file_t *file = (file_t *) search_by_fid(fid, NULL, SPECIFY_EF);
|
||||
if (!file) {
|
||||
file = file_new(fid);
|
||||
}
|
||||
if (file) {
|
||||
file->data =
|
||||
(uint8_t *) (base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t));
|
||||
file->data = (uint8_t *) (base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t));
|
||||
}
|
||||
if (!persistent) {
|
||||
num_files++;
|
||||
}
|
||||
if (flash_read_uintptr(base) == 0x0) {
|
||||
if (base < last_base) {
|
||||
last_base = base;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -383,7 +390,7 @@ uint16_t meta_find(uint16_t fid, uint8_t **out) {
|
||||
if (tag_len < 2) {
|
||||
continue;
|
||||
}
|
||||
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
|
||||
uint16_t cfid = get_uint16_t_be(tag_data);
|
||||
if (cfid == fid) {
|
||||
if (out) {
|
||||
*out = tag_data + 2;
|
||||
@@ -409,7 +416,7 @@ int meta_delete(uint16_t fid) {
|
||||
if (tag_len < 2) {
|
||||
continue;
|
||||
}
|
||||
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
|
||||
uint16_t cfid = get_uint16_t_be(tag_data);
|
||||
if (cfid == fid) {
|
||||
uint16_t new_len = ctxi.len - 1 - tag_len - format_tlv_len(tag_len, NULL);
|
||||
if (new_len == 0) {
|
||||
@@ -453,7 +460,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||
if (tag_len < 2) {
|
||||
continue;
|
||||
}
|
||||
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
|
||||
uint16_t cfid = get_uint16_t_be(tag_data);
|
||||
if (cfid == fid) {
|
||||
if (tag_len - 2 == len) { //an update
|
||||
memcpy(p - tag_len + 2, data, len);
|
||||
@@ -483,8 +490,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||
uint8_t *f = fdata + meta_offset;
|
||||
*f++ = fid & 0xff;
|
||||
f += format_tlv_len(len + 2, f);
|
||||
*f++ = fid >> 8;
|
||||
*f++ = fid & 0xff;
|
||||
f += put_uint16_t_be(fid, f);
|
||||
memcpy(f, data, len);
|
||||
r = file_put_data(ef, fdata, ef_size);
|
||||
free(fdata);
|
||||
@@ -499,8 +505,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||
uint8_t *f = fdata + ef_size;
|
||||
*f++ = fid & 0x1f;
|
||||
f += format_tlv_len(len + 2, f);
|
||||
*f++ = fid >> 8;
|
||||
*f++ = fid & 0xff;
|
||||
f += put_uint16_t_be(fid, f);
|
||||
memcpy(f, data, len);
|
||||
r = file_put_data(ef, fdata, ef_size + (uint16_t)asn1_len_tag(fid & 0x1f, len + 2));
|
||||
free(fdata);
|
||||
|
||||
@@ -69,15 +69,20 @@
|
||||
|
||||
#define MAX_DEPTH 4
|
||||
|
||||
#define MAX_DYNAMIC_FILES 256
|
||||
|
||||
typedef struct file {
|
||||
const uint16_t fid;
|
||||
const uint8_t parent; //entry number in the whole table!!
|
||||
const uint8_t *name;
|
||||
uint8_t *data; //should include 2 bytes len at begining
|
||||
const uint16_t fid;
|
||||
const uint8_t acl[7];
|
||||
const uint8_t parent; //entry number in the whole table!!
|
||||
const uint8_t type;
|
||||
const uint8_t ef_structure;
|
||||
uint8_t *data; //should include 2 bytes len at begining
|
||||
const uint8_t acl[7];
|
||||
} file_t;
|
||||
#ifdef ENABLE_EMULATION
|
||||
uint32_t _padding;
|
||||
#endif
|
||||
} __attribute__ ((packed)) file_t;
|
||||
|
||||
extern bool file_has_data(file_t *);
|
||||
|
||||
@@ -128,6 +133,12 @@ extern int meta_delete(uint16_t fid);
|
||||
extern int meta_add(uint16_t fid, const uint8_t *data, uint16_t len);
|
||||
extern int delete_file(file_t *ef);
|
||||
|
||||
extern uint32_t flash_free_space();
|
||||
extern uint32_t flash_used_space();
|
||||
extern uint32_t flash_total_space();
|
||||
extern uint32_t flash_num_files();
|
||||
extern uint32_t flash_size();
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
extern file_t *ef_phy;
|
||||
#endif
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
#define XIP_BASE 0
|
||||
#define FLASH_SECTOR_SIZE 4096
|
||||
#ifdef ESP_PLATFORM
|
||||
#define PICO_FLASH_SIZE_BYTES (1 * 1024 * 1024)
|
||||
uint32_t FLASH_SIZE_BYTES = (1 * 1024 * 1024);
|
||||
#else
|
||||
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#define FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#endif
|
||||
#else
|
||||
uint32_t FLASH_SIZE_BYTES = (2 * 1024 * 1024);
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/flash.h"
|
||||
#endif
|
||||
@@ -42,27 +43,12 @@
|
||||
* | |
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
#ifdef ESP_PLATFORM
|
||||
#define FLASH_TARGET_OFFSET 0
|
||||
#else
|
||||
#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES >> 1) // DATA starts at the mid of flash
|
||||
#endif
|
||||
|
||||
#define FLASH_DATA_HEADER_SIZE (sizeof(uintptr_t) + sizeof(uint32_t))
|
||||
#define FLASH_PERMANENT_REGION (4 * FLASH_SECTOR_SIZE) // 4 sectors (16kb) of permanent memory
|
||||
|
||||
//To avoid possible future allocations, data region starts at the end of flash and goes upwards to the center region
|
||||
|
||||
#ifdef PICO_RP2350
|
||||
// Table partition for RP2350 needs 8kb
|
||||
const uintptr_t end_flash = (XIP_BASE + PICO_FLASH_SIZE_BYTES - 2 * FLASH_SECTOR_SIZE);
|
||||
#else
|
||||
const uintptr_t end_flash = (XIP_BASE + PICO_FLASH_SIZE_BYTES);
|
||||
#endif
|
||||
|
||||
const uintptr_t end_rom_pool = end_flash - FLASH_DATA_HEADER_SIZE - 4; //This is a fixed value. DO NOT CHANGE
|
||||
const uintptr_t start_rom_pool = end_rom_pool - FLASH_PERMANENT_REGION; //This is a fixed value. DO NOT CHANGE
|
||||
const uintptr_t end_data_pool = start_rom_pool - FLASH_DATA_HEADER_SIZE; //This is a fixed value. DO NOT CHANGE
|
||||
const uintptr_t start_data_pool = (XIP_BASE + FLASH_TARGET_OFFSET);
|
||||
uintptr_t end_flash, end_rom_pool, start_rom_pool, end_data_pool, start_data_pool;
|
||||
|
||||
extern int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len);
|
||||
extern int flash_program_halfword(uintptr_t addr, uint16_t data);
|
||||
@@ -73,12 +59,24 @@ extern uint8_t *flash_read(uintptr_t addr);
|
||||
|
||||
extern void low_flash_available();
|
||||
|
||||
uintptr_t last_base;
|
||||
uint32_t num_files = 0;
|
||||
|
||||
void flash_set_bounds(uintptr_t start, uintptr_t end) {
|
||||
end_flash = end;
|
||||
end_rom_pool = end_flash - FLASH_DATA_HEADER_SIZE - 4;
|
||||
start_rom_pool = end_rom_pool - FLASH_PERMANENT_REGION;
|
||||
end_data_pool = start_rom_pool - FLASH_DATA_HEADER_SIZE;
|
||||
start_data_pool = start;
|
||||
|
||||
last_base = end_data_pool;
|
||||
}
|
||||
|
||||
uintptr_t allocate_free_addr(uint16_t size, bool persistent) {
|
||||
if (size > FLASH_SECTOR_SIZE) {
|
||||
return 0x0; //ERROR
|
||||
}
|
||||
size_t real_size = size + sizeof(uint16_t) + sizeof(uintptr_t) + sizeof(uint16_t) +
|
||||
sizeof(uintptr_t); //len+len size+next address+fid+prev_addr size
|
||||
size_t real_size = size + sizeof(uint16_t) + sizeof(uintptr_t) + sizeof(uint16_t) + sizeof(uintptr_t); //len+len size+next address+fid+prev_addr size
|
||||
uintptr_t next_base = 0x0, endp = end_data_pool, startp = start_data_pool;
|
||||
if (persistent) {
|
||||
endp = end_rom_pool;
|
||||
@@ -108,14 +106,9 @@ uintptr_t allocate_free_addr(uint16_t size, bool persistent) {
|
||||
return 0x0;
|
||||
}
|
||||
//we check if |base-(next_addr+size_next_addr)| > |base-potential_addr| only if fid != 1xxx (not size blocked)
|
||||
else if (addr_alg <= potential_addr &&
|
||||
base -
|
||||
(next_base +
|
||||
flash_read_uint16(next_base + sizeof(uintptr_t) + sizeof(uintptr_t) +
|
||||
sizeof(uint16_t)) +
|
||||
2 *
|
||||
sizeof(uint16_t) + 2 * sizeof(uintptr_t)) > base - potential_addr &&
|
||||
(flash_read_uint16(next_base + 2 * sizeof(uintptr_t)) & 0x1000) != 0x1000) {
|
||||
else if (addr_alg <= potential_addr
|
||||
&& base - (next_base + flash_read_uint16(next_base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t)) + 2 * sizeof(uint16_t) + 2 * sizeof(uintptr_t)) > base - potential_addr
|
||||
&& (flash_read_uint16(next_base + 2 * sizeof(uintptr_t)) & 0x1000) != 0x1000) {
|
||||
flash_program_uintptr(potential_addr, next_base);
|
||||
flash_program_uintptr(next_base + sizeof(uintptr_t), potential_addr);
|
||||
flash_program_uintptr(potential_addr + sizeof(uintptr_t), base);
|
||||
@@ -130,8 +123,7 @@ int flash_clear_file(file_t *file) {
|
||||
if (file == NULL || file->data == NULL) {
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
uintptr_t base_addr =
|
||||
(uintptr_t)(file->data - sizeof(uintptr_t) - sizeof(uint16_t) - sizeof(uintptr_t));
|
||||
uintptr_t base_addr = (uintptr_t)(file->data - sizeof(uintptr_t) - sizeof(uint16_t) - sizeof(uintptr_t));
|
||||
uintptr_t prev_addr = flash_read_uintptr(base_addr + sizeof(uintptr_t));
|
||||
uintptr_t next_addr = flash_read_uintptr(base_addr);
|
||||
//printf("nc %lx->%lx %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr),base_addr,next_addr);
|
||||
@@ -143,12 +135,12 @@ int flash_clear_file(file_t *file) {
|
||||
flash_program_uintptr(base_addr, 0);
|
||||
flash_program_uintptr(base_addr + sizeof(uintptr_t), 0);
|
||||
file->data = NULL;
|
||||
num_files--;
|
||||
//printf("na %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr));
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len,
|
||||
uint16_t offset) {
|
||||
int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len, uint16_t offset) {
|
||||
if (!file) {
|
||||
return PICOKEY_ERR_NULL_PARAM;
|
||||
}
|
||||
@@ -182,6 +174,9 @@ int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t
|
||||
if (new_addr == 0x0) {
|
||||
return PICOKEY_ERR_NO_MEMORY;
|
||||
}
|
||||
if (new_addr < last_base) {
|
||||
last_base = new_addr;
|
||||
}
|
||||
file->data = (uint8_t *) new_addr + sizeof(uintptr_t) + sizeof(uint16_t) + sizeof(uintptr_t); //next addr+fid+prev addr
|
||||
flash_program_halfword(new_addr + sizeof(uintptr_t) + sizeof(uintptr_t), file->fid);
|
||||
flash_program_halfword((uintptr_t) file->data, len);
|
||||
@@ -191,8 +186,30 @@ int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t
|
||||
if (old_data) {
|
||||
free(old_data);
|
||||
}
|
||||
num_files++;
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
|
||||
return flash_write_data_to_file_offset(file, data, len, 0);
|
||||
}
|
||||
|
||||
uint32_t flash_free_space() {
|
||||
return last_base - start_data_pool;
|
||||
}
|
||||
|
||||
uint32_t flash_used_space() {
|
||||
return end_data_pool - last_base;
|
||||
}
|
||||
|
||||
uint32_t flash_total_space() {
|
||||
return end_data_pool - start_data_pool;
|
||||
}
|
||||
|
||||
uint32_t flash_num_files() {
|
||||
return num_files;
|
||||
}
|
||||
|
||||
uint32_t flash_size() {
|
||||
return FLASH_SIZE_BYTES;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "pico/mutex.h"
|
||||
#include "pico/sem.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/bootrom.h"
|
||||
#include "boot/picobin.h"
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
@@ -56,19 +58,24 @@
|
||||
#endif
|
||||
#endif
|
||||
#define FLASH_SECTOR_SIZE 4096
|
||||
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#define XIP_BASE 0
|
||||
int fd_map = 0;
|
||||
uint8_t *map = NULL;
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifndef ENABLE_EMULATION
|
||||
extern uint32_t FLASH_SIZE_BYTES;
|
||||
#else
|
||||
#define FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#define TOTAL_FLASH_PAGES 6
|
||||
|
||||
extern void flash_set_bounds(uintptr_t start, uintptr_t end);
|
||||
|
||||
extern const uintptr_t start_data_pool;
|
||||
extern const uintptr_t end_rom_pool;
|
||||
|
||||
|
||||
typedef struct page_flash {
|
||||
uint8_t page[FLASH_SECTOR_SIZE];
|
||||
uintptr_t address;
|
||||
@@ -126,10 +133,7 @@ void do_flash() {
|
||||
;
|
||||
}
|
||||
//printf("WRITTING\n");
|
||||
flash_range_erase(flash_pages[r].address - XIP_BASE,
|
||||
flash_pages[r].page_size ? ((int) (flash_pages[r].page_size /
|
||||
FLASH_SECTOR_SIZE)) *
|
||||
FLASH_SECTOR_SIZE : FLASH_SECTOR_SIZE);
|
||||
flash_range_erase(flash_pages[r].address - XIP_BASE, flash_pages[r].page_size ? ((int) (flash_pages[r].page_size / FLASH_SECTOR_SIZE)) * FLASH_SECTOR_SIZE : FLASH_SECTOR_SIZE);
|
||||
while (multicore_lockout_end_timeout_us(1000) == false) {
|
||||
;
|
||||
}
|
||||
@@ -141,7 +145,7 @@ void do_flash() {
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_EMULATION
|
||||
msync(map, PICO_FLASH_SIZE_BYTES, MS_SYNC);
|
||||
msync(map, FLASH_SIZE_BYTES, MS_SYNC);
|
||||
#endif
|
||||
if (ready_pages != 0) {
|
||||
printf("ERROR: DO FLASH DOES NOT HAVE ZERO PAGES\n");
|
||||
@@ -162,17 +166,57 @@ void low_flash_init() {
|
||||
memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES);
|
||||
mutex_init(&mtx_flash);
|
||||
sem_init(&sem_flash, 0, 1);
|
||||
|
||||
uint32_t data_start_addr;
|
||||
uint32_t data_end_addr;
|
||||
#if defined(ENABLE_EMULATION)
|
||||
fd_map = open("memory.flash", O_RDWR | O_CREAT, (mode_t) 0600);
|
||||
lseek(fd_map, PICO_FLASH_SIZE_BYTES - 1, SEEK_SET);
|
||||
lseek(fd_map, FLASH_SIZE_BYTES - 1, SEEK_SET);
|
||||
write(fd_map, "", 1);
|
||||
map = mmap(0, PICO_FLASH_SIZE_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd_map, 0);
|
||||
#else
|
||||
#if defined(ESP_PLATFORM)
|
||||
map = mmap(0, FLASH_SIZE_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd_map, 0);
|
||||
data_start_addr = 0;
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
#elif defined(ESP_PLATFORM)
|
||||
part0 = esp_partition_find_first(0x40, 0x1, "part0");
|
||||
esp_partition_mmap(part0, 0, part0->size, ESP_PARTITION_MMAP_DATA, (const void **)&map, (esp_partition_mmap_handle_t *)&fd_map);
|
||||
data_start_addr = 0;
|
||||
data_end_addr = part0->size;
|
||||
FLASH_SIZE_BYTES = part0->size;
|
||||
#elif defined(PICO_PLATFORM)
|
||||
uint8_t txbuf[6] = {0x9f};
|
||||
uint8_t rxbuf[6] = {0};
|
||||
flash_do_cmd(txbuf, rxbuf, 4);
|
||||
|
||||
FLASH_SIZE_BYTES = (1 << rxbuf[3]);
|
||||
#ifdef PICO_RP2350
|
||||
__attribute__((aligned(4))) uint8_t workarea[4 * 1024];
|
||||
int rc = rom_load_partition_table(workarea, sizeof(workarea), false);
|
||||
if (rc) {
|
||||
reset_usb_boot(0, 0);
|
||||
}
|
||||
|
||||
uint8_t boot_partition = 1;
|
||||
rc = rom_get_partition_table_info((uint32_t*)workarea, 0x8, PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_SINGLE_PARTITION | (boot_partition << 24));
|
||||
|
||||
if (rc != 3) {
|
||||
data_start_addr = (FLASH_SIZE_BYTES >> 1);
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
} else {
|
||||
uint16_t first_sector_number = (((uint32_t*)workarea)[1] & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB;
|
||||
uint16_t last_sector_number = (((uint32_t*)workarea)[1] & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB;
|
||||
data_start_addr = first_sector_number * FLASH_SECTOR_SIZE;
|
||||
data_end_addr = (last_sector_number + 1) * FLASH_SECTOR_SIZE;
|
||||
}
|
||||
data_end_addr -= 2 * FLASH_SECTOR_SIZE;
|
||||
#else
|
||||
data_start_addr = (FLASH_SIZE_BYTES >> 1);
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
#endif
|
||||
|
||||
data_start_addr += XIP_BASE;
|
||||
data_end_addr += XIP_BASE;
|
||||
#endif
|
||||
flash_set_bounds(data_start_addr, data_end_addr);
|
||||
}
|
||||
|
||||
void low_flash_init_core1() {
|
||||
@@ -205,10 +249,7 @@ page_flash_t *find_free_page(uintptr_t addr) {
|
||||
#ifdef PICO_PLATFORM
|
||||
memcpy(p->page, (uint8_t *) addr_alg, FLASH_SECTOR_SIZE);
|
||||
#else
|
||||
memcpy(p->page,
|
||||
(addr >= start_data_pool &&
|
||||
addr <= end_rom_pool + sizeof(uintptr_t)) ? (uint8_t *) (map + addr_alg) : (uint8_t *) addr_alg,
|
||||
FLASH_SECTOR_SIZE);
|
||||
memcpy(p->page, (addr >= start_data_pool && addr <= end_rom_pool + sizeof(uintptr_t)) ? (uint8_t *) (map + addr_alg) : (uint8_t *) addr_alg, FLASH_SECTOR_SIZE);
|
||||
#endif
|
||||
ready_pages++;
|
||||
p->address = addr_alg;
|
||||
|
||||
@@ -231,4 +231,11 @@ void init_otp_files() {
|
||||
}
|
||||
}
|
||||
#endif // PICO_RP2350 || ESP_PLATFORM
|
||||
#ifdef ENABLE_EMULATION
|
||||
static uint8_t _otp1[32] = {0}, _otp2[32] = {0};
|
||||
memset(_otp1, 0xAC, sizeof(_otp1));
|
||||
memset(_otp2, 0xBE, sizeof(_otp2));
|
||||
otp_key_1 = _otp1;
|
||||
otp_key_2 = _otp2;
|
||||
#endif
|
||||
}
|
||||
|
||||
130
src/fs/phy.c
130
src/fs/phy.c
@@ -29,6 +29,7 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
||||
uint8_t *p = data;
|
||||
if (phy->vidpid_present) {
|
||||
*p++ = PHY_VIDPID;
|
||||
*p++ = 4;
|
||||
*p++ = phy->vidpid[1];
|
||||
*p++ = phy->vidpid[0];
|
||||
*p++ = phy->vidpid[3];
|
||||
@@ -36,62 +37,143 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
||||
}
|
||||
if (phy->led_gpio_present) {
|
||||
*p++ = PHY_LED_GPIO;
|
||||
*p++ = 1;
|
||||
*p++ = phy->led_gpio;
|
||||
}
|
||||
if (phy->led_brightness_present) {
|
||||
*p++ = PHY_LED_BTNESS;
|
||||
*p++ = 1;
|
||||
*p++ = phy->led_brightness;
|
||||
}
|
||||
*p++ = PHY_OPTS;
|
||||
*p++ = phy->opts >> 8;
|
||||
*p++ = phy->opts & 0xff;
|
||||
*p++ = 2;
|
||||
p += put_uint16_t_be(phy->opts, p);
|
||||
if (phy->up_btn_present) {
|
||||
*p++ = PHY_UP_BTN;
|
||||
*p++ = 1;
|
||||
*p++ = phy->up_btn;
|
||||
}
|
||||
if (phy->usb_product_present) {
|
||||
*p++ = PHY_USB_PRODUCT;
|
||||
*p++ = strlen(phy->usb_product) + 1;
|
||||
strcpy((char *)p, phy->usb_product);
|
||||
p += strlen(phy->usb_product);
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (phy->enabled_curves_present) {
|
||||
*p++ = PHY_ENABLED_CURVES;
|
||||
*p++ = 4;
|
||||
p += put_uint32_t_be(phy->enabled_curves, p);
|
||||
}
|
||||
if (phy->enabled_usb_itf_present) {
|
||||
*p++ = PHY_ENABLED_USB_ITF;
|
||||
*p++ = 1;
|
||||
*p++ = phy->enabled_usb_itf;
|
||||
}
|
||||
|
||||
*len = p - data;
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
#include <stdio.h>
|
||||
|
||||
int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
||||
if (!phy || !data || !len) {
|
||||
return PICOKEY_ERR_NULL_PARAM;
|
||||
}
|
||||
memset(phy, 0, sizeof(phy_data_t));
|
||||
const uint8_t *p = data;
|
||||
uint8_t tag, tlen;
|
||||
while (p < data + len) {
|
||||
switch (*p++) {
|
||||
tag = *p++;
|
||||
tlen = *p++;
|
||||
switch (tag) {
|
||||
case PHY_VIDPID:
|
||||
memcpy(phy->vidpid, p, 4);
|
||||
phy->vidpid[1] = *p++;
|
||||
phy->vidpid[0] = *p++;
|
||||
phy->vidpid[3] = *p++;
|
||||
phy->vidpid[2] = *p++;
|
||||
phy->vidpid_present = true;
|
||||
if (tlen == 4) {
|
||||
memcpy(phy->vidpid, p, 4);
|
||||
phy->vidpid[1] = *p++;
|
||||
phy->vidpid[0] = *p++;
|
||||
phy->vidpid[3] = *p++;
|
||||
phy->vidpid[2] = *p++;
|
||||
phy->vidpid_present = true;
|
||||
}
|
||||
break;
|
||||
case PHY_LED_GPIO:
|
||||
phy->led_gpio = *p++;
|
||||
phy->led_gpio_present = true;
|
||||
if (tlen == 1) {
|
||||
phy->led_gpio = *p++;
|
||||
phy->led_gpio_present = true;
|
||||
}
|
||||
break;
|
||||
case PHY_LED_BTNESS:
|
||||
phy->led_brightness = *p++;
|
||||
phy->led_brightness_present = true;
|
||||
if (tlen == 1) {
|
||||
phy->led_brightness = *p++;
|
||||
phy->led_brightness_present = true;
|
||||
}
|
||||
break;
|
||||
case PHY_OPTS:
|
||||
phy->opts = (*p << 8) | *(p + 1);
|
||||
p += 2;
|
||||
if (tlen == 2) {
|
||||
phy->opts = get_uint16_t_be(p);
|
||||
p += 2;
|
||||
}
|
||||
break;
|
||||
case PHY_UP_BTN:
|
||||
if (tlen == 1) {
|
||||
phy->up_btn = *p++;
|
||||
phy->up_btn_present = true;
|
||||
}
|
||||
break;
|
||||
case PHY_USB_PRODUCT:
|
||||
if (tlen > 0 && tlen <= sizeof(phy->usb_product)) {
|
||||
memset(phy->usb_product, 0, sizeof(phy->usb_product));
|
||||
strlcpy(phy->usb_product, (const char *)p, sizeof(phy->usb_product));
|
||||
phy->usb_product_present = true;
|
||||
p += strlen(phy->usb_product) + 1;
|
||||
}
|
||||
break;
|
||||
case PHY_ENABLED_CURVES:
|
||||
if (tlen == 4) {
|
||||
phy->enabled_curves = get_uint32_t_be(p);
|
||||
p += 4;
|
||||
phy->enabled_curves_present = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case PHY_ENABLED_USB_ITF:
|
||||
if (tlen == 1) {
|
||||
phy->enabled_usb_itf = *p++;
|
||||
phy->enabled_usb_itf_present = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p += tlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!phy_data.enabled_usb_itf_present) {
|
||||
phy_data.enabled_usb_itf = PHY_USB_ITF_CCID | PHY_USB_ITF_WCID | PHY_USB_ITF_HID | PHY_USB_ITF_KB;
|
||||
phy_data.enabled_usb_itf_present = true;
|
||||
}
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
int phy_init() {
|
||||
memset(&phy_data, 0, sizeof(phy_data_t));
|
||||
if (file_has_data(ef_phy)) {
|
||||
const uint8_t *data = file_get_data(ef_phy);
|
||||
int ret = phy_unserialize_data(data, file_get_size(ef_phy), &phy_data);
|
||||
if (ret != PICOKEY_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return phy_load();
|
||||
}
|
||||
|
||||
int phy_save() {
|
||||
uint8_t tmp[PHY_MAX_SIZE] = {0};
|
||||
uint16_t tmp_len = 0;
|
||||
int ret = phy_serialize_data(&phy_data, tmp, &tmp_len);
|
||||
if (ret != PICOKEY_OK) {
|
||||
return ret;
|
||||
}
|
||||
file_put_data(ef_phy, tmp, tmp_len);
|
||||
low_flash_available();
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
int phy_load() {
|
||||
if (file_has_data(ef_phy)) {
|
||||
return phy_unserialize_data(file_get_data(ef_phy), file_get_size(ef_phy), &phy_data);
|
||||
}
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
45
src/fs/phy.h
45
src/fs/phy.h
@@ -24,9 +24,32 @@
|
||||
#define PHY_LED_GPIO 0x4
|
||||
#define PHY_LED_BTNESS 0x5
|
||||
#define PHY_OPTS 0x6
|
||||
#define PHY_UP_BTN 0x8
|
||||
#define PHY_USB_PRODUCT 0x9
|
||||
#define PHY_ENABLED_CURVES 0xA
|
||||
#define PHY_ENABLED_USB_ITF 0xB
|
||||
|
||||
#define PHY_OPT_WCID 0x1
|
||||
#define PHY_OPT_DIMM 0x2
|
||||
#define PHY_OPT_DISABLE_POWER_RESET 0x4
|
||||
#define PHY_OPT_LED_STEADY 0x8
|
||||
|
||||
#define PHY_CURVE_SECP256R1 0x1
|
||||
#define PHY_CURVE_SECP384R1 0x2
|
||||
#define PHY_CURVE_SECP521R1 0x4
|
||||
#define PHY_CURVE_SECP256K1 0x8
|
||||
#define PHY_CURVE_BP256R1 0x10
|
||||
#define PHY_CURVE_BP384R1 0x20
|
||||
#define PHY_CURVE_BP512R1 0x40
|
||||
#define PHY_CURVE_ED25519 0x80
|
||||
#define PHY_CURVE_ED448 0x100
|
||||
#define PHY_CURVE_CURVE25519 0x200
|
||||
#define PHY_CURVE_CURVE448 0x400
|
||||
|
||||
#define PHY_USB_ITF_CCID 0x1
|
||||
#define PHY_USB_ITF_WCID 0x2
|
||||
#define PHY_USB_ITF_HID 0x4
|
||||
#define PHY_USB_ITF_KB 0x8
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -39,22 +62,36 @@ typedef struct phy_data {
|
||||
};
|
||||
uint8_t vidpid[4];
|
||||
};
|
||||
|
||||
uint32_t enabled_curves;
|
||||
|
||||
char usb_product[32];
|
||||
|
||||
uint16_t opts;
|
||||
|
||||
uint8_t led_gpio;
|
||||
uint8_t led_brightness;
|
||||
uint16_t opts;
|
||||
uint8_t up_btn;
|
||||
uint8_t enabled_usb_itf;
|
||||
|
||||
bool vidpid_present;
|
||||
bool led_gpio_present;
|
||||
bool led_brightness_present;
|
||||
bool up_btn_present;
|
||||
bool usb_product_present;
|
||||
bool enabled_curves_present;
|
||||
bool enabled_usb_itf_present;
|
||||
|
||||
} phy_data_t;
|
||||
|
||||
#define PHY_OPT_MASK (PHY_OPT_SECURE_LOCK | PHY_OPT_SECURE_BOOT | PHY_OPT_DIMM | PHY_OPT_WCID)
|
||||
|
||||
#define PHY_MAX_SIZE 8
|
||||
#define PHY_MAX_SIZE ((2+4)+(2+4)+(2+32)+(2+2)+(2+1)+(2+1)+(2+1)+(2+1))
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
extern int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len);
|
||||
extern int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy);
|
||||
extern int phy_init();
|
||||
extern int phy_save();
|
||||
extern int phy_load();
|
||||
extern phy_data_t phy_data;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp_tinyusb: "^1.4.4"
|
||||
espressif/esp_tinyusb: "^1.7.2"
|
||||
#espressif/tinyusb: "^0.15.0"
|
||||
zorxx/neopixel: "^1.0.4"
|
||||
|
||||
@@ -35,10 +35,15 @@ void led_set_mode(uint32_t mode) {
|
||||
led_mode = mode;
|
||||
}
|
||||
|
||||
uint32_t led_get_mode() {
|
||||
return led_mode;
|
||||
}
|
||||
|
||||
void led_blinking_task() {
|
||||
#ifndef ENABLE_EMULATION
|
||||
static uint32_t start_ms = 0;
|
||||
static uint32_t stop_ms = 0;
|
||||
static uint32_t last_led_update_ms = 0;
|
||||
static uint8_t led_state = false;
|
||||
uint8_t state = led_state;
|
||||
#ifdef PICO_DEFAULT_LED_PIN_INVERTED
|
||||
@@ -49,7 +54,6 @@ void led_blinking_task() {
|
||||
uint32_t led_off = (led_mode & LED_OFF_MASK) >> LED_OFF_SHIFT;
|
||||
uint32_t led_on = (led_mode & LED_ON_MASK) >> LED_ON_SHIFT;
|
||||
|
||||
// how far in the current state from 0 - 1
|
||||
float progress = 0;
|
||||
|
||||
if (stop_ms > start_ms) {
|
||||
@@ -57,15 +61,17 @@ void led_blinking_task() {
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
// fading down so 1 -> 0
|
||||
progress = 1. - progress;
|
||||
}
|
||||
if (phy_data.opts & PHY_OPT_LED_STEADY) {
|
||||
progress = 1;
|
||||
}
|
||||
|
||||
// maybe quick return if progress didn't changed much ?
|
||||
|
||||
// current one from 0 - 1
|
||||
|
||||
led_driver_color(led_color, led_brightness, progress);
|
||||
// limit the frequency of LED status updates
|
||||
if (board_millis() - last_led_update_ms > 2) {
|
||||
led_driver_color(led_color, led_brightness, progress);
|
||||
last_led_update_ms = board_millis();
|
||||
}
|
||||
|
||||
if (board_millis() >= stop_ms){
|
||||
start_ms = stop_ms;
|
||||
|
||||
@@ -62,6 +62,7 @@ enum {
|
||||
};
|
||||
|
||||
extern void led_set_mode(uint32_t mode);
|
||||
extern uint32_t led_get_mode();
|
||||
extern void led_blinking_task();
|
||||
extern void led_off_all();
|
||||
extern void led_init();
|
||||
|
||||
@@ -27,7 +27,11 @@ void led_driver_init() {
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
(void)led_brightness;
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, progress >= 0.5);
|
||||
uint8_t gpio = CYW43_WL_GPIO_LED_PIN;
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
}
|
||||
cyw43_arch_gpio_put(gpio, progress >= 0.5);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,8 +35,18 @@ tNeopixel pixel[] = {
|
||||
{ 0, NP_RGB(255, 255, 255) }, /* white */
|
||||
};
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#define NEOPIXEL_PIN GPIO_NUM_48
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define NEOPIXEL_PIN GPIO_NUM_15
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
#define NEOPIXEL_PIN GPIO_NUM_8
|
||||
#else
|
||||
#define NEOPIXEL_PIN GPIO_NUM_27
|
||||
#endif
|
||||
|
||||
void led_driver_init() {
|
||||
uint8_t gpio = GPIO_NUM_48;
|
||||
uint8_t gpio = NEOPIXEL_PIN;
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
}
|
||||
|
||||
@@ -17,16 +17,21 @@
|
||||
|
||||
#include "pico_keys.h"
|
||||
|
||||
#if defined(PICO_DEFAULT_LED_PIN) && !defined(PICO_DEFAULT_WS2812_PIN)
|
||||
#if defined(PICO_DEFAULT_LED_PIN) && !defined(PICO_DEFAULT_WS2812_PIN) && !defined(PIMORONI_TINY2040) && !defined(PIMORONI_TINY2350)
|
||||
|
||||
uint8_t gpio = PICO_DEFAULT_LED_PIN;
|
||||
|
||||
void led_driver_init() {
|
||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
}
|
||||
gpio_init(gpio);
|
||||
gpio_set_dir(gpio, GPIO_OUT);
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
(void)led_brightness;
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, progress >= 0.5);
|
||||
gpio_put(gpio, progress >= 0.5);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,23 +21,32 @@
|
||||
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
#define ws2812_wrap_target 0
|
||||
#define ws2812_wrap 3
|
||||
#define ws2812_T1 2
|
||||
#define ws2812_T2 5
|
||||
#define ws2812_T3 3
|
||||
#define ws2812_pio_version 0
|
||||
|
||||
#define ws2812_T1 3
|
||||
#define ws2812_T2 3
|
||||
#define ws2812_T3 4
|
||||
|
||||
static const uint16_t ws2812_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x6221, // 0: out x, 1 side 0 [2]
|
||||
0x1123, // 1: jmp !x, 3 side 1 [1]
|
||||
0x1400, // 2: jmp 0 side 1 [4]
|
||||
0xa442, // 3: nop side 0 [4]
|
||||
// .wrap_target
|
||||
0x6321, // 0: out x, 1 side 0 [3]
|
||||
0x1223, // 1: jmp !x, 3 side 1 [2]
|
||||
0x1200, // 2: jmp 0 side 1 [2]
|
||||
0xa242, // 3: nop side 0 [2]
|
||||
// .wrap
|
||||
};
|
||||
|
||||
static const struct pio_program ws2812_program = {
|
||||
.instructions = ws2812_program_instructions,
|
||||
.length = 4,
|
||||
.origin = -1,
|
||||
.pio_version = ws2812_pio_version,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config ws2812_program_get_default_config(uint offset) {
|
||||
@@ -46,6 +55,7 @@ static inline pio_sm_config ws2812_program_get_default_config(uint offset) {
|
||||
sm_config_set_sideset(&c, 1, false, false);
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
|
||||
pio_gpio_init(pio, pin);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
|
||||
@@ -64,21 +74,45 @@ void led_driver_init() {
|
||||
PIO pio = pio0;
|
||||
int sm = 0;
|
||||
uint offset = pio_add_program(pio, &ws2812_program);
|
||||
|
||||
ws2812_program_init(pio, sm, offset, PICO_DEFAULT_WS2812_PIN, 800000, true);
|
||||
uint8_t gpio = PICO_DEFAULT_WS2812_PIN;
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
}
|
||||
ws2812_program_init(pio, sm, offset, gpio, 800000, false);
|
||||
}
|
||||
|
||||
uint32_t pixel[] = {
|
||||
0x00000000, // 0: off
|
||||
0x00ff0000, // 1: red
|
||||
0xff000000, // 2: green
|
||||
0x0000ff00, // 3: blue
|
||||
0xffff0000, // 4: yellow
|
||||
0x00ffff00, // 5: magenta
|
||||
0xff00ff00, // 6: cyan
|
||||
0xffffff00 // 7: white
|
||||
struct urgb_color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
static struct urgb_color urgb_color_table[] = {
|
||||
{0x00, 0x00, 0x00}, // 0: off LED_COLOR_OFF
|
||||
{0xff, 0x00, 0x00}, // 1: red LED_COLOR_RED
|
||||
{0x00, 0xff, 0x00}, // 2: green LED_COLOR_GREEN
|
||||
{0x00, 0x00, 0xff}, // 3: blue LED_COLOR_BLUE
|
||||
{0xff, 0xff, 0x00}, // 4: yellow LED_COLOR_YELLOW
|
||||
{0xff, 0x00, 0xff}, // 5: magenta LED_COLOR_MAGENTA
|
||||
{0x00, 0xff, 0xff}, // 6: cyan LED_COLOR_CYAN
|
||||
{0xff, 0xff, 0xff} // 7: white LED_COLOR_WHITE
|
||||
};
|
||||
|
||||
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((uint32_t) (r) << 8) | // For GRB data ordering WS2812
|
||||
((uint32_t) (g) << 16) |
|
||||
(uint32_t) (b);
|
||||
#if 0 // TODO: How to adapt WS2812 with different data ordering ?
|
||||
return ((uint32_t)(r) << 16) | // For RGB data ordering WS2812
|
||||
((uint32_t)(g) << 8) |
|
||||
(uint32_t)(b);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ws2812_put_pixel(uint32_t u32_pixel) {
|
||||
pio_sm_put_blocking(pio0, 0, u32_pixel << 8u);
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
if (!(phy_data.opts & PHY_OPT_DIMM)) {
|
||||
progress = progress >= 0.5 ? 1 : 0;
|
||||
@@ -86,16 +120,12 @@ void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
uint32_t led_phy_btness = phy_data.led_brightness_present ? phy_data.led_brightness : MAX_BTNESS;
|
||||
|
||||
float brightness = ((float)led_brightness / MAX_BTNESS) * ((float)led_phy_btness / MAX_BTNESS) * progress;
|
||||
uint32_t pixel_color = pixel[color];
|
||||
uint8_t r = (pixel_color >> 16) & 0xFF;
|
||||
uint8_t g = (pixel_color >> 24) & 0xFF;
|
||||
uint8_t b = (pixel_color >> 8) & 0xFF;
|
||||
struct urgb_color pixel_color = urgb_color_table[color];
|
||||
pixel_color.r = (uint8_t)(pixel_color.r * brightness);
|
||||
pixel_color.g = (uint8_t)(pixel_color.g * brightness);
|
||||
pixel_color.b = (uint8_t)(pixel_color.b * brightness);
|
||||
|
||||
r = (uint8_t)(r * brightness);
|
||||
g = (uint8_t)(g * brightness);
|
||||
b = (uint8_t)(b * brightness);
|
||||
|
||||
pio_sm_put_blocking(pio0, 0, (g << 24) | (r << 16) | (b << 8));
|
||||
ws2812_put_pixel(urgb_u32(pixel_color.r, pixel_color.g, pixel_color.b));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
41
src/main.c
41
src/main.c
@@ -54,7 +54,22 @@ app_t *current_app = NULL;
|
||||
|
||||
const uint8_t *ccid_atr = NULL;
|
||||
|
||||
bool app_exists(const uint8_t *aid, size_t aid_len) {
|
||||
if (current_app && current_app->aid && (current_app->aid + 1 == aid || !memcmp(current_app->aid + 1, aid, aid_len))) {
|
||||
return true;
|
||||
}
|
||||
for (int a = 0; a < num_apps; a++) {
|
||||
if (!memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int register_app(int (*select_aid)(app_t *, uint8_t), const uint8_t *aid) {
|
||||
if (app_exists(aid + 1, aid[0])) {
|
||||
return 1;
|
||||
}
|
||||
if (num_apps < sizeof(apps) / sizeof(app_t)) {
|
||||
apps[num_apps].select_aid = select_aid;
|
||||
apps[num_apps].aid = aid;
|
||||
@@ -99,7 +114,6 @@ bool is_req_button_pending() {
|
||||
return req_button_pending;
|
||||
}
|
||||
|
||||
uint32_t button_timeout = 15000;
|
||||
bool cancel_button = false;
|
||||
|
||||
#ifdef ENABLE_EMULATION
|
||||
@@ -182,9 +196,17 @@ bool button_pressed_state = false;
|
||||
uint32_t button_pressed_time = 0;
|
||||
uint8_t button_press = 0;
|
||||
bool wait_button() {
|
||||
uint32_t button_timeout = 15000;
|
||||
if (phy_data.up_btn_present) {
|
||||
button_timeout = phy_data.up_btn * 1000;
|
||||
if (button_timeout == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint32_t start_button = board_millis();
|
||||
bool timeout = false;
|
||||
cancel_button = false;
|
||||
uint32_t led_mode = led_get_mode();
|
||||
led_set_mode(MODE_BUTTON);
|
||||
req_button_pending = true;
|
||||
while (picok_board_button_read() == false && cancel_button == false) {
|
||||
@@ -205,7 +227,7 @@ bool wait_button() {
|
||||
}
|
||||
}
|
||||
}
|
||||
led_set_mode(MODE_PROCESSING);
|
||||
led_set_mode(led_mode);
|
||||
req_button_pending = false;
|
||||
return timeout || cancel_button;
|
||||
}
|
||||
@@ -288,7 +310,6 @@ int main(void) {
|
||||
board_init();
|
||||
stdio_init_all();
|
||||
#endif
|
||||
led_init();
|
||||
|
||||
#else
|
||||
emul_init("127.0.0.1", 35963);
|
||||
@@ -308,6 +329,8 @@ int main(void) {
|
||||
phy_init();
|
||||
#endif
|
||||
|
||||
led_init();
|
||||
|
||||
usb_init();
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
@@ -317,6 +340,16 @@ int main(void) {
|
||||
gpio_pulldown_dis(BOOT_PIN);
|
||||
|
||||
tusb_cfg.string_descriptor[3] = pico_serial_str;
|
||||
if (phy_data.usb_product_present) {
|
||||
tusb_cfg.string_descriptor[2] = phy_data.usb_product;
|
||||
}
|
||||
static char tmps[4][32];
|
||||
for (int i = 4; i < tusb_cfg.string_descriptor_count; i++) {
|
||||
strlcpy(tmps[i-4], tusb_cfg.string_descriptor[2], sizeof(tmps[0]));
|
||||
strlcat(tmps[i-4], " ", sizeof(tmps[0]));
|
||||
strlcat(tmps[i-4], tusb_cfg.string_descriptor[i], sizeof(tmps[0]));
|
||||
tusb_cfg.string_descriptor[i] = tmps[i-4];
|
||||
}
|
||||
tusb_cfg.configuration_descriptor = desc_config;
|
||||
|
||||
tinyusb_driver_install(&tusb_cfg);
|
||||
@@ -326,7 +359,7 @@ int main(void) {
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
xTaskCreatePinnedToCore(core0_loop, "core0", 4096*5, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, 0);
|
||||
xTaskCreatePinnedToCore(core0_loop, "core0", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, ESP32_CORE0);
|
||||
#else
|
||||
core0_loop();
|
||||
#endif
|
||||
|
||||
@@ -64,15 +64,89 @@ extern bool wait_button();
|
||||
|
||||
extern void low_flash_init_core1();
|
||||
|
||||
static inline uint16_t make_uint16_t(uint8_t b1, uint8_t b2) {
|
||||
static inline uint16_t make_uint16_t_be(uint8_t b1, uint8_t b2) {
|
||||
return (b1 << 8) | b2;
|
||||
}
|
||||
static inline uint16_t get_uint16_t(const uint8_t *b, uint16_t offset) {
|
||||
return make_uint16_t(b[offset], b[offset + 1]);
|
||||
static inline uint16_t make_uint16_t_le(uint8_t b1, uint8_t b2) {
|
||||
return (b2 << 8) | b1;
|
||||
}
|
||||
static inline void put_uint16_t(uint16_t n, uint8_t *b) {
|
||||
static inline uint16_t get_uint16_t_be(const uint8_t *b) {
|
||||
return make_uint16_t_be(b[0], b[1]);
|
||||
}
|
||||
static inline uint16_t get_uint16_t_le(const uint8_t *b) {
|
||||
return make_uint16_t_le(b[0], b[1]);
|
||||
}
|
||||
static inline uint32_t put_uint16_t_be(uint16_t n, uint8_t *b) {
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b = n & 0xff;
|
||||
return 2;
|
||||
}
|
||||
static inline uint32_t put_uint16_t_le(uint16_t n, uint8_t *b) {
|
||||
*b++ = n & 0xff;
|
||||
*b = (n >> 8) & 0xff;
|
||||
return 2;
|
||||
}
|
||||
|
||||
static inline uint32_t make_uint32_t_be(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) {
|
||||
return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
|
||||
}
|
||||
static inline uint32_t make_uint32_t_le(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) {
|
||||
return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
|
||||
}
|
||||
static inline uint32_t get_uint32_t_be(const uint8_t *b) {
|
||||
return make_uint32_t_be(b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
static inline uint32_t get_uint32_t_le(const uint8_t *b) {
|
||||
return make_uint32_t_le(b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
static inline uint32_t put_uint32_t_be(uint32_t n, uint8_t *b) {
|
||||
*b++ = (n >> 24) & 0xff;
|
||||
*b++ = (n >> 16) & 0xff;
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b = n & 0xff;
|
||||
return 4;
|
||||
}
|
||||
static inline uint32_t put_uint32_t_le(uint32_t n, uint8_t *b) {
|
||||
*b++ = n & 0xff;
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b++ = (n >> 16) & 0xff;
|
||||
*b = (n >> 24) & 0xff;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static inline uint64_t make_uint64_t_be(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7, uint8_t b8) {
|
||||
return ((uint64_t) b1 << 56) | ((uint64_t) b2 << 48) | ((uint64_t) b3 << 40) | ((uint64_t) b4 << 32) | ((uint64_t) b5 << 24) | ((uint64_t) b6 << 16) | ((uint64_t) b7 << 8) | b8;
|
||||
}
|
||||
static inline uint64_t make_uint64_t_le(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7, uint8_t b8) {
|
||||
return ((uint64_t) b8 << 56) | ((uint64_t) b7 << 48) | ((uint64_t) b6 << 40) | ((uint64_t) b5 << 32) | ((uint64_t) b4 << 24) | ((uint64_t) b3 << 16) | ((uint64_t) b2 << 8) | b1;
|
||||
}
|
||||
static inline uint64_t get_uint64_t_be(const uint8_t *b) {
|
||||
return make_uint64_t_be(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
|
||||
}
|
||||
static inline uint64_t get_uint64_t_le(const uint8_t *b) {
|
||||
return make_uint64_t_le(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
|
||||
}
|
||||
static inline uint32_t put_uint64_t_be(uint64_t n, uint8_t *b) {
|
||||
*b++ = (n >> 56) & 0xff;
|
||||
*b++ = (n >> 48) & 0xff;
|
||||
*b++ = (n >> 40) & 0xff;
|
||||
*b++ = (n >> 32) & 0xff;
|
||||
*b++ = (n >> 24) & 0xff;
|
||||
*b++ = (n >> 16) & 0xff;
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b = n & 0xff;
|
||||
return 8;
|
||||
}
|
||||
static inline uint32_t put_uint64_t_le(uint64_t n, uint8_t *b) {
|
||||
*b++ = n & 0xff;
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b++ = (n >> 16) & 0xff;
|
||||
*b++ = (n >> 24) & 0xff;
|
||||
*b++ = (n >> 32) & 0xff;
|
||||
*b++ = (n >> 40) & 0xff;
|
||||
*b++ = (n >> 48) & 0xff;
|
||||
*b = (n >> 56) & 0xff;
|
||||
return 8;
|
||||
}
|
||||
|
||||
extern void low_flash_available();
|
||||
|
||||
@@ -32,6 +32,8 @@ const uint8_t rescue_aid[] = {
|
||||
#define PICO_MCU 1
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#define PICO_MCU 2
|
||||
#elif defined(ENABLE_EMULATION)
|
||||
#define PICO_MCU 3
|
||||
#else
|
||||
#define PICO_MCU 0
|
||||
#endif
|
||||
@@ -70,11 +72,12 @@ int cmd_write() {
|
||||
#ifndef ENABLE_EMULATION
|
||||
int ret = phy_unserialize_data(apdu.data, apdu.nc, &phy_data);
|
||||
if (ret == PICOKEY_OK) {
|
||||
file_put_data(ef_phy, apdu.data, apdu.nc);
|
||||
if (phy_save() != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
#define CCID_DATA_BLOCK_RET 0x80
|
||||
#define CCID_SLOT_STATUS_RET 0x81 /* non-ICCD result */
|
||||
#define CCID_PARAMS_RET 0x82 /* non-ICCD result */
|
||||
#define CCID_SETDATARATEANDCLOCKFREQUENCY 0x73
|
||||
#define CCID_SETDATARATEANDCLOCKFREQUENCY_RET 0x84
|
||||
|
||||
#define CCID_MSG_SEQ_OFFSET 6
|
||||
#define CCID_MSG_STATUS_OFFSET 7
|
||||
@@ -92,7 +94,7 @@ uint8_t ccid_status = 1;
|
||||
static uint8_t itf_num;
|
||||
#endif
|
||||
|
||||
static usb_buffer_t ccid_rx[ITF_SC_TOTAL] = {0}, ccid_tx[ITF_SC_TOTAL] = {0};
|
||||
static usb_buffer_t *ccid_rx = NULL, *ccid_tx = NULL;
|
||||
|
||||
int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read);
|
||||
|
||||
@@ -105,9 +107,9 @@ void ccid_write(uint8_t itf, uint16_t size) {
|
||||
ccid_write_offset(itf, size, 0);
|
||||
}
|
||||
|
||||
ccid_header_t *ccid_response[ITF_SC_TOTAL];
|
||||
ccid_header_t *ccid_resp_fast[ITF_SC_TOTAL];
|
||||
ccid_header_t *ccid_header[ITF_SC_TOTAL];
|
||||
ccid_header_t **ccid_response = NULL;
|
||||
ccid_header_t **ccid_resp_fast = NULL;
|
||||
ccid_header_t **ccid_header = NULL;
|
||||
|
||||
uint8_t sc_itf_to_usb_itf(uint8_t itf) {
|
||||
if (itf == ITF_SC_CCID) {
|
||||
@@ -119,6 +121,27 @@ uint8_t sc_itf_to_usb_itf(uint8_t itf) {
|
||||
return itf;
|
||||
}
|
||||
|
||||
void ccid_init_buffers() {
|
||||
if (ITF_SC_TOTAL == 0) {
|
||||
return;
|
||||
}
|
||||
if (ccid_rx == NULL) {
|
||||
ccid_rx = (usb_buffer_t *)calloc(ITF_SC_TOTAL, sizeof(usb_buffer_t));
|
||||
}
|
||||
if (ccid_tx == NULL) {
|
||||
ccid_tx = (usb_buffer_t *)calloc(ITF_SC_TOTAL, sizeof(usb_buffer_t));
|
||||
}
|
||||
if (ccid_header == NULL) {
|
||||
ccid_header = (ccid_header_t **)calloc(ITF_SC_TOTAL, sizeof(ccid_header_t *));
|
||||
}
|
||||
if (ccid_response == NULL) {
|
||||
ccid_response = (ccid_header_t **)calloc(ITF_SC_TOTAL, sizeof(ccid_header_t *));
|
||||
}
|
||||
if (ccid_resp_fast == NULL) {
|
||||
ccid_resp_fast = (ccid_header_t **)calloc(ITF_SC_TOTAL, sizeof(ccid_header_t *));
|
||||
}
|
||||
}
|
||||
|
||||
int driver_init_ccid(uint8_t itf) {
|
||||
ccid_header[itf] = (ccid_header_t *) (ccid_rx[itf].buffer + ccid_rx[itf].r_ptr);
|
||||
ccid_resp_fast[itf] = (ccid_header_t *) (ccid_tx[itf].buffer + sizeof(ccid_tx[itf].buffer) - 64);
|
||||
@@ -133,7 +156,7 @@ int driver_init_ccid(uint8_t itf) {
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
void tud_vendor_rx_cb(uint8_t itf) {
|
||||
void tud_vendor_rx_cb(uint8_t itf, const uint8_t *buffer, uint16_t bufsize) {
|
||||
uint32_t len = tud_vendor_n_available(itf);
|
||||
do {
|
||||
uint16_t tlen = 0;
|
||||
@@ -150,11 +173,6 @@ void tud_vendor_rx_cb(uint8_t itf) {
|
||||
} while (len > 0);
|
||||
}
|
||||
|
||||
void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) {
|
||||
(void) sent_bytes;
|
||||
tud_vendor_n_write_flush(itf);
|
||||
}
|
||||
|
||||
int driver_write_ccid(uint8_t itf, const uint8_t *tx_buffer, uint16_t buffer_size) {
|
||||
if (*tx_buffer != 0x81) {
|
||||
DEBUG_PAYLOAD(tx_buffer, buffer_size);
|
||||
@@ -258,6 +276,16 @@ int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read) {
|
||||
memcpy(&ccid_resp_fast[itf]->apdu, params, sizeof(params));
|
||||
ccid_write_fast(itf, (const uint8_t *)ccid_resp_fast[itf], sizeof(params) + 10);
|
||||
}
|
||||
else if (ccid_header[itf]->bMessageType == CCID_SETDATARATEANDCLOCKFREQUENCY) {
|
||||
ccid_resp_fast[itf]->bMessageType = CCID_SETDATARATEANDCLOCKFREQUENCY_RET;
|
||||
ccid_resp_fast[itf]->dwLength = 8;
|
||||
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;
|
||||
memset(&ccid_resp_fast[itf]->apdu, 0, 8);
|
||||
ccid_write_fast(itf, (const uint8_t *)ccid_resp_fast[itf], 18);
|
||||
}
|
||||
else if (ccid_header[itf]->bMessageType == CCID_XFR_BLOCK) {
|
||||
apdu.rdata = &ccid_response[itf]->apdu;
|
||||
apdu_sent = apdu_process(itf, &ccid_header[itf]->apdu, (uint16_t)ccid_header[itf]->dwLength);
|
||||
@@ -316,11 +344,16 @@ void ccid_task() {
|
||||
}
|
||||
}
|
||||
|
||||
void ccid_init() {
|
||||
ccid_init_buffers();
|
||||
}
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
|
||||
#define USB_CONFIG_ATT_ONE TU_BIT(7)
|
||||
|
||||
#define MAX_USB_POWER 1
|
||||
void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) {
|
||||
(void) sent_bytes;
|
||||
tud_vendor_n_write_flush(itf);
|
||||
}
|
||||
|
||||
static void ccid_init_cb(void) {
|
||||
vendord_init();
|
||||
@@ -336,17 +369,20 @@ static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc,
|
||||
TU_VERIFY( itf_desc->bInterfaceClass == TUSB_CLASS_SMART_CARD && itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0, 0);
|
||||
|
||||
//vendord_open expects a CLASS_VENDOR interface class
|
||||
uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(struct ccid_class_descriptor) + 3 * sizeof(tusb_desc_endpoint_t);
|
||||
uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(struct ccid_class_descriptor) + TUSB_SMARTCARD_CCID_EPS * sizeof(tusb_desc_endpoint_t);
|
||||
memcpy(itf_vendor, itf_desc, sizeof(uint8_t) * max_len);
|
||||
((tusb_desc_interface_t *) itf_vendor)->bInterfaceClass = TUSB_CLASS_VENDOR_SPECIFIC;
|
||||
#if TUSB_SMARTCARD_CCID_EPS == 3
|
||||
((tusb_desc_interface_t *) itf_vendor)->bNumEndpoints -= 1;
|
||||
vendord_open(rhport, (tusb_desc_interface_t *) itf_vendor, max_len - sizeof(tusb_desc_endpoint_t));
|
||||
vendord_open(rhport, (tusb_desc_interface_t *)itf_vendor, max_len - sizeof(tusb_desc_endpoint_t));
|
||||
tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *)((uint8_t *)itf_desc + drv_len - sizeof(tusb_desc_endpoint_t));
|
||||
TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0);
|
||||
free(itf_vendor);
|
||||
|
||||
uint8_t msg[] = { 0x50, 0x03 };
|
||||
usbd_edpt_xfer(rhport, desc_ep->bEndpointAddress, msg, sizeof(msg));
|
||||
#else
|
||||
vendord_open(rhport, (tusb_desc_interface_t *)itf_vendor, max_len);
|
||||
#endif
|
||||
free(itf_vendor);
|
||||
|
||||
TU_VERIFY(max_len >= drv_len, 0);
|
||||
|
||||
|
||||
@@ -303,28 +303,24 @@ uint16_t emul_read(uint8_t itf) {
|
||||
driver_write_emul(itf, ccid_atr ? ccid_atr + 1 : NULL, ccid_atr ? ccid_atr[0] : 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(itf) {
|
||||
#ifdef USB_ITF_CCID
|
||||
case ITF_CCID: {
|
||||
uint16_t sent = 0;
|
||||
DEBUG_PAYLOAD(emul_rx, len);
|
||||
apdu.rdata = emul_tx;
|
||||
if ((sent = apdu_process(itf, emul_rx, len)) > 0) {
|
||||
process_apdu();
|
||||
apdu_finish();
|
||||
}
|
||||
if (sent > 0) {
|
||||
uint16_t ret = apdu_next();
|
||||
DEBUG_PAYLOAD(apdu.rdata, ret);
|
||||
driver_write_emul(itf, apdu.rdata, ret);
|
||||
}
|
||||
break;
|
||||
else if (itf == ITF_CCID) {
|
||||
uint16_t sent = 0;
|
||||
DEBUG_PAYLOAD(emul_rx, len);
|
||||
apdu.rdata = emul_tx;
|
||||
if ((sent = apdu_process(itf, emul_rx, len)) > 0) {
|
||||
process_apdu();
|
||||
apdu_finish();
|
||||
}
|
||||
if (sent > 0) {
|
||||
uint16_t ret = apdu_next();
|
||||
DEBUG_PAYLOAD(apdu.rdata, ret);
|
||||
driver_write_emul(itf, apdu.rdata, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
emul_rx_size += valread;
|
||||
}
|
||||
else {
|
||||
emul_rx_size += valread;
|
||||
}
|
||||
return (uint16_t)emul_rx_size;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ bool is_nitrokey = false;
|
||||
uint8_t (*get_version_major)() = NULL;
|
||||
uint8_t (*get_version_minor)() = NULL;
|
||||
|
||||
static usb_buffer_t hid_rx[ITF_HID_TOTAL] = {0}, hid_tx[ITF_HID_TOTAL] = {0};
|
||||
static usb_buffer_t *hid_rx = NULL, *hid_tx = NULL;
|
||||
|
||||
PACK(
|
||||
typedef struct msg_packet {
|
||||
@@ -56,8 +56,8 @@ bool driver_mounted_hid() {
|
||||
return mounted;
|
||||
}
|
||||
|
||||
static uint16_t send_buffer_size[ITF_HID_TOTAL] = {0};
|
||||
static write_status_t last_write_result[ITF_HID_TOTAL] = {0};
|
||||
static uint16_t *send_buffer_size = NULL;
|
||||
static write_status_t *last_write_result = NULL;
|
||||
|
||||
CTAPHID_FRAME *ctap_req = NULL, *ctap_resp = NULL;
|
||||
void send_keepalive();
|
||||
@@ -65,6 +65,24 @@ int driver_process_usb_packet_hid(uint16_t read);
|
||||
int driver_write_hid(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size);
|
||||
int driver_process_usb_nopacket_hid();
|
||||
|
||||
void hid_init() {
|
||||
if (ITF_HID_TOTAL == 0) {
|
||||
return;
|
||||
}
|
||||
if (send_buffer_size == NULL) {
|
||||
send_buffer_size = (uint16_t *)calloc(ITF_HID_TOTAL, sizeof(uint16_t));
|
||||
}
|
||||
if (last_write_result == NULL) {
|
||||
last_write_result = (write_status_t *)calloc(ITF_HID_TOTAL, sizeof(write_status_t));
|
||||
}
|
||||
if (hid_rx == NULL) {
|
||||
hid_rx = (usb_buffer_t *)calloc(ITF_HID_TOTAL, sizeof(usb_buffer_t));
|
||||
}
|
||||
if (hid_tx == NULL) {
|
||||
hid_tx = (usb_buffer_t *)calloc(ITF_HID_TOTAL, sizeof(usb_buffer_t));
|
||||
}
|
||||
}
|
||||
|
||||
int driver_init_hid() {
|
||||
#ifndef ENABLE_EMULATION
|
||||
static bool _init = false;
|
||||
@@ -78,7 +96,7 @@ int driver_init_hid() {
|
||||
|
||||
ctap_resp = (CTAPHID_FRAME *) (hid_tx[ITF_HID_CTAP].buffer);
|
||||
apdu.rdata = ctap_resp->init.data;
|
||||
//memset(ctap_resp, 0, sizeof(CTAPHID_FRAME));
|
||||
memset(ctap_resp, 0, sizeof(CTAPHID_FRAME));
|
||||
|
||||
usb_set_timeout_counter(ITF_HID, 200);
|
||||
|
||||
@@ -513,6 +531,7 @@ int driver_process_usb_packet_hid(uint16_t read) {
|
||||
msg_packet.len = msg_packet.current_len = 0;
|
||||
last_packet_time = 0;
|
||||
cancel_button = true;
|
||||
hid_tx[ITF_HID_CTAP].r_ptr = hid_tx[ITF_HID_CTAP].w_ptr = 0;
|
||||
}
|
||||
else {
|
||||
if (msg_packet.len == 0) {
|
||||
@@ -536,6 +555,9 @@ int driver_process_usb_packet_hid(uint16_t read) {
|
||||
}
|
||||
|
||||
void send_keepalive() {
|
||||
if (thread_type == 1) {
|
||||
return;
|
||||
}
|
||||
CTAPHID_FRAME *resp = (CTAPHID_FRAME *) (hid_tx[ITF_HID_CTAP].buffer + sizeof(hid_tx[ITF_HID_CTAP].buffer) - 64);
|
||||
//memset(ctap_resp, 0, sizeof(CTAPHID_FRAME));
|
||||
resp->cid = ctap_req->cid;
|
||||
@@ -554,8 +576,7 @@ void driver_exec_finished_hid(uint16_t size_next) {
|
||||
else {
|
||||
if (is_nitrokey) {
|
||||
memmove(apdu.rdata + 2, apdu.rdata, size_next - 2);
|
||||
apdu.rdata[0] = apdu.sw >> 8;
|
||||
apdu.rdata[1] = apdu.sw & 0xff;
|
||||
put_uint16_t_be(apdu.sw, apdu.rdata);
|
||||
}
|
||||
driver_exec_finished_cont_hid(ITF_HID_CTAP, size_next, 7);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
#define CFG_TUD_VENDOR_TX_BUFSIZE 4096
|
||||
#define CFG_TUD_VENDOR_TX_BUFSIZE 2048
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_CDC 0
|
||||
|
||||
@@ -37,13 +37,29 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
// Device specific functions
|
||||
static uint32_t timeout_counter[ITF_TOTAL] = { 0 };
|
||||
static uint8_t card_locked_itf = ITF_TOTAL; // no locked
|
||||
static uint32_t *timeout_counter = NULL;
|
||||
static uint8_t card_locked_itf = 0; // no locked
|
||||
static void (*card_locked_func)(void) = NULL;
|
||||
#ifndef ENABLE_EMULATION
|
||||
static mutex_t mutex;
|
||||
extern void usb_desc_setup();
|
||||
#endif
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
uint8_t ITF_HID_CTAP = ITF_INVALID, ITF_HID_KB = ITF_INVALID;
|
||||
uint8_t ITF_HID = ITF_INVALID, ITF_KEYBOARD = ITF_INVALID;
|
||||
uint8_t ITF_HID_TOTAL = 0;
|
||||
extern void hid_init();
|
||||
#endif
|
||||
|
||||
#ifdef USB_ITF_CCID
|
||||
uint8_t ITF_SC_CCID = ITF_INVALID, ITF_SC_WCID = ITF_INVALID;
|
||||
uint8_t ITF_CCID = ITF_INVALID, ITF_WCID = ITF_INVALID;
|
||||
uint8_t ITF_SC_TOTAL = 0;
|
||||
extern void ccid_init();
|
||||
#endif
|
||||
uint8_t ITF_TOTAL = 0;
|
||||
|
||||
void usb_set_timeout_counter(uint8_t itf, uint32_t v) {
|
||||
timeout_counter[itf] = v;
|
||||
}
|
||||
@@ -64,6 +80,58 @@ void usb_init() {
|
||||
#endif
|
||||
queue_init(&card_to_usb_q, sizeof(uint32_t), 64);
|
||||
queue_init(&usb_to_card_q, sizeof(uint32_t), 64);
|
||||
|
||||
uint8_t enabled_usb_itf = PHY_USB_ITF_CCID | PHY_USB_ITF_WCID | PHY_USB_ITF_HID | PHY_USB_ITF_KB;
|
||||
#ifndef ENABLE_EMULATION
|
||||
if (phy_data.enabled_usb_itf_present) {
|
||||
enabled_usb_itf = phy_data.enabled_usb_itf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
ITF_HID_TOTAL = 0;
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
ITF_SC_TOTAL = 0;
|
||||
#endif
|
||||
ITF_TOTAL = 0;
|
||||
#ifdef USB_ITF_HID
|
||||
if (enabled_usb_itf & PHY_USB_ITF_HID) {
|
||||
ITF_HID_CTAP = ITF_HID_TOTAL++;
|
||||
ITF_HID = ITF_TOTAL++;
|
||||
}
|
||||
if (enabled_usb_itf & PHY_USB_ITF_KB) {
|
||||
ITF_HID_KB = ITF_HID_TOTAL++;
|
||||
ITF_KEYBOARD = ITF_TOTAL++;
|
||||
}
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
if (enabled_usb_itf & PHY_USB_ITF_CCID) {
|
||||
ITF_SC_CCID = ITF_SC_TOTAL++;
|
||||
ITF_CCID = ITF_TOTAL++;
|
||||
}
|
||||
if (enabled_usb_itf & PHY_USB_ITF_WCID) {
|
||||
ITF_SC_WCID = ITF_SC_TOTAL++;
|
||||
ITF_WCID = ITF_TOTAL++;
|
||||
}
|
||||
#endif
|
||||
card_locked_itf = ITF_TOTAL;
|
||||
if (timeout_counter == NULL) {
|
||||
timeout_counter = (uint32_t *)calloc(ITF_TOTAL, sizeof(uint32_t));
|
||||
}
|
||||
#ifdef USB_ITF_HID
|
||||
if (ITF_HID_TOTAL > 0) {
|
||||
hid_init();
|
||||
}
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
if (ITF_SC_TOTAL > 0) {
|
||||
ccid_init();
|
||||
}
|
||||
#endif
|
||||
#ifdef ESP_PLATFORM
|
||||
usb_desc_setup();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t timeout = 0;
|
||||
|
||||
@@ -44,38 +44,32 @@
|
||||
#define EV_BUTTON_TIMEOUT 16
|
||||
#define EV_BUTTON_PRESSED 32
|
||||
|
||||
enum {
|
||||
static const uint8_t ITF_INVALID = 0xFF;
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
ITF_HID_CTAP = 0,
|
||||
ITF_HID_KB,
|
||||
extern uint8_t ITF_HID_CTAP, ITF_HID_KB;
|
||||
extern uint8_t ITF_HID, ITF_KEYBOARD;
|
||||
extern uint8_t ITF_HID_TOTAL;
|
||||
#endif
|
||||
ITF_HID_TOTAL
|
||||
};
|
||||
enum {
|
||||
|
||||
#ifdef USB_ITF_CCID
|
||||
ITF_SC_CCID = 0,
|
||||
ITF_SC_WCID,
|
||||
extern uint8_t ITF_SC_CCID, ITF_SC_WCID;
|
||||
extern uint8_t ITF_CCID, ITF_WCID;
|
||||
extern uint8_t ITF_SC_TOTAL;
|
||||
#endif
|
||||
ITF_SC_TOTAL
|
||||
};
|
||||
extern uint8_t ITF_TOTAL;
|
||||
|
||||
enum {
|
||||
#ifdef USB_ITF_HID
|
||||
ITF_HID = ITF_HID_CTAP,
|
||||
ITF_KEYBOARD = ITF_HID_KB,
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
ITF_CCID = ITF_SC_CCID + ITF_HID_TOTAL,
|
||||
ITF_WCID = ITF_SC_WCID + ITF_HID_TOTAL,
|
||||
#endif
|
||||
ITF_TOTAL = ITF_HID_TOTAL + ITF_SC_TOTAL
|
||||
};
|
||||
|
||||
enum {
|
||||
REPORT_ID_KEYBOARD = 1,
|
||||
REPORT_ID_KEYBOARD = 0,
|
||||
REPORT_ID_COUNT
|
||||
};
|
||||
|
||||
#if defined(ESP_PLATFORM) && defined(USB_ITF_HID) && defined(USB_ITF_CCID)
|
||||
#define TUSB_SMARTCARD_CCID_EPS 2
|
||||
#else
|
||||
#define TUSB_SMARTCARD_CCID_EPS 3
|
||||
#endif
|
||||
|
||||
extern void usb_task();
|
||||
extern queue_t usb_to_card_q;
|
||||
extern queue_t card_to_usb_q;
|
||||
@@ -109,7 +103,7 @@ extern void driver_exec_finished_emul(uint8_t itf, uint16_t size_next);
|
||||
extern void driver_exec_finished_cont_emul(uint8_t itf, uint16_t size_next, uint16_t offset);
|
||||
#endif
|
||||
|
||||
#define USB_BUFFER_SIZE 2048 // Size of USB buffer"
|
||||
#define USB_BUFFER_SIZE 2048
|
||||
|
||||
PACK(
|
||||
typedef struct {
|
||||
|
||||
@@ -76,19 +76,21 @@ uint8_t const *tud_descriptor_device_cb(void) {
|
||||
#define TUD_INTERFACE_DESC_LEN 9
|
||||
#define TUD_ENDPOINT_DESC_LEN 7
|
||||
#define TUSB_SMARTCARD_LEN 54
|
||||
#define TUSB_SMARTCARD_CCID_DESC_LEN (TUD_INTERFACE_DESC_LEN + TUSB_SMARTCARD_LEN + 3 * TUD_ENDPOINT_DESC_LEN)
|
||||
#define TUSB_SMARTCARD_WCID_DESC_LEN (TUD_INTERFACE_DESC_LEN + TUSB_SMARTCARD_LEN + 2 * TUD_ENDPOINT_DESC_LEN)
|
||||
#define TUSB_WSMARTCARD_LEN 53
|
||||
|
||||
#define TUSB_SMARTCARD_CCID_DESC_LEN (TUD_INTERFACE_DESC_LEN + TUSB_SMARTCARD_LEN + TUSB_SMARTCARD_CCID_EPS * TUD_ENDPOINT_DESC_LEN)
|
||||
#define TUSB_SMARTCARD_WCID_DESC_LEN (TUD_INTERFACE_DESC_LEN + TUSB_WSMARTCARD_LEN + 2 * TUD_ENDPOINT_DESC_LEN)
|
||||
|
||||
uint16_t TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN;
|
||||
enum {
|
||||
TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN
|
||||
MAX_TUSB_DESC_TOTAL_LEN = (TUD_CONFIG_DESC_LEN
|
||||
#ifdef USB_ITF_HID
|
||||
+ TUD_HID_INOUT_DESC_LEN
|
||||
+ TUD_HID_DESC_LEN
|
||||
+ TUD_HID_INOUT_DESC_LEN + TUD_HID_DESC_LEN
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
+ TUSB_SMARTCARD_CCID_DESC_LEN
|
||||
+ TUSB_SMARTCARD_WCID_DESC_LEN
|
||||
+ TUSB_SMARTCARD_CCID_DESC_LEN + TUSB_SMARTCARD_WCID_DESC_LEN
|
||||
#endif
|
||||
)
|
||||
};
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
@@ -96,35 +98,48 @@ uint8_t const desc_hid_report[] = {
|
||||
TUD_HID_REPORT_DESC_FIDO_U2F(CFG_TUD_HID_EP_BUFSIZE)
|
||||
};
|
||||
uint8_t const desc_hid_report_kb[] = {
|
||||
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD))
|
||||
TUD_HID_REPORT_DESC_KEYBOARD(HID_USAGE_PAGE(HID_USAGE_DESKTOP_KEYBOARD), HID_USAGE_MIN(0), HID_USAGE_MAX_N(255,2), HID_LOGICAL_MIN(0), HID_LOGICAL_MAX_N(255, 2), HID_REPORT_COUNT(8), HID_REPORT_SIZE(8), HID_FEATURE( HID_DATA | HID_VARIABLE | HID_ABSOLUTE),)
|
||||
};
|
||||
#define EPNUM_HID 0x04
|
||||
#endif
|
||||
|
||||
enum {
|
||||
#ifdef USB_ITF_CCID
|
||||
EPNUM_CCID = 1,
|
||||
#if TUSB_SMARTCARD_CCID_EPS == 3
|
||||
EPNUM_CCID_INT,
|
||||
#endif
|
||||
EPNUM_WCID,
|
||||
#endif
|
||||
#ifdef USB_ITF_HID
|
||||
EPNUM_HID,
|
||||
EPNUM_HID_KB,
|
||||
#endif
|
||||
EPNUM_TOTAL
|
||||
};
|
||||
|
||||
#ifdef USB_ITF_CCID
|
||||
#define TUD_SMARTCARD_DESCRIPTOR_WEB(_itf, _strix, _epout, _epin, _epsize) \
|
||||
9, TUSB_DESC_INTERFACE, _itf, 0, 2, 0xFF, 0, 0, _strix, \
|
||||
54, 0x21, U16_TO_U8S_LE(0x0110), 0, 0x1, U32_TO_U8S_LE(0x01|0x2), U32_TO_U8S_LE(0xDFC), U32_TO_U8S_LE(0xDFC), 0, U32_TO_U8S_LE(0x2580), U32_TO_U8S_LE(0x2580), 0, U32_TO_U8S_LE(0xFE), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0x40840), U32_TO_U8S_LE(65544+10), 0xFF, 0xFF, U16_TO_U8S_LE(0x0), 0, 0x1, \
|
||||
TUSB_WSMARTCARD_LEN, 0x21, U16_TO_U8S_LE(0x0110), 0, 0x1, U32_TO_U8S_LE(0x01|0x2), U32_TO_U8S_LE(0xDFC), U32_TO_U8S_LE(0xDFC), 0, U32_TO_U8S_LE(0x2580), U32_TO_U8S_LE(0x2580), 0, U32_TO_U8S_LE(0xFE), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0x40840), U32_TO_U8S_LE(USB_BUFFER_SIZE), 0xFF, 0xFF, U16_TO_U8S_LE(0x0), 0, \
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, \
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
#define TUD_SMARTCARD_DESCRIPTOR(_itf, _strix, _epout, _epin, _epint, _epsize) \
|
||||
9, TUSB_DESC_INTERFACE, _itf, 0, 3, TUSB_CLASS_SMART_CARD, 0, 0, _strix, \
|
||||
54, 0x21, U16_TO_U8S_LE(0x0110), 0, 0x1, U32_TO_U8S_LE(0x01|0x2), U32_TO_U8S_LE(0xDFC), U32_TO_U8S_LE(0xDFC), 0, U32_TO_U8S_LE(0x2580), U32_TO_U8S_LE(0x2580), 0, U32_TO_U8S_LE(0xFE), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0x40840), U32_TO_U8S_LE(65544+10), 0xFF, 0xFF, U16_TO_U8S_LE(0x0), 0, 0x1, \
|
||||
#define TUD_SMARTCARD_DESCRIPTOR_2EP(_itf, _strix, _epout, _epin, _epsize) \
|
||||
9, TUSB_DESC_INTERFACE, _itf, 0, TUSB_SMARTCARD_CCID_EPS, TUSB_CLASS_SMART_CARD, 0, 0, _strix, \
|
||||
TUSB_SMARTCARD_LEN, 0x21, U16_TO_U8S_LE(0x0110), 0, 0x1, U32_TO_U8S_LE(0x01|0x2), U32_TO_U8S_LE(0xDFC), U32_TO_U8S_LE(0xDFC), 0, U32_TO_U8S_LE(0x2580), U32_TO_U8S_LE(0x2580), 0, U32_TO_U8S_LE(0xFE), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0x40840), U32_TO_U8S_LE(USB_BUFFER_SIZE), 0xFF, 0xFF, U16_TO_U8S_LE(0x0), 0, 0x1, \
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, \
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, \
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
#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
|
||||
#else
|
||||
#define TUD_SMARTCARD_DESCRIPTOR(_itf, _strix, _epout, _epin, _epint, _epsize) \
|
||||
TUD_SMARTCARD_DESCRIPTOR_2EP(_itf, _strix, _epout, _epin, _epsize)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const uint8_t desc_config[] = {
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_TOTAL, 4, TUSB_DESC_TOTAL_LEN, USB_CONFIG_ATT_ONE | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, MAX_USB_POWER),
|
||||
#ifdef USB_ITF_HID
|
||||
TUD_HID_INOUT_DESCRIPTOR(ITF_HID, ITF_HID + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, TUSB_DIR_IN_MASK | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10),
|
||||
TUD_HID_DESCRIPTOR(ITF_KEYBOARD, ITF_KEYBOARD + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report_kb), TUSB_DIR_IN_MASK | (EPNUM_HID + 1), 16, 5),
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
TUD_SMARTCARD_DESCRIPTOR(ITF_CCID, ITF_CCID+5, 1, TUSB_DIR_IN_MASK | 1, TUSB_DIR_IN_MASK | 2, 64),
|
||||
TUD_SMARTCARD_DESCRIPTOR_WEB(ITF_WCID, ITF_WCID+5, 3, TUSB_DIR_IN_MASK | 3, 64),
|
||||
#endif
|
||||
uint8_t desc_config[MAX_TUSB_DESC_TOTAL_LEN] = {
|
||||
TUD_CONFIG_DESCRIPTOR(1, 0, 4, 0, USB_CONFIG_ATT_ONE | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, MAX_USB_POWER)
|
||||
};
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
@@ -139,9 +154,47 @@ uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void usb_desc_setup() {
|
||||
desc_config[4] = ITF_TOTAL;
|
||||
TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN;
|
||||
uint8_t *p = desc_config + TUD_CONFIG_DESC_LEN;
|
||||
#ifdef USB_ITF_HID
|
||||
if (ITF_HID != ITF_INVALID) {
|
||||
TUSB_DESC_TOTAL_LEN += TUD_HID_INOUT_DESC_LEN;
|
||||
const uint8_t desc[] = { TUD_HID_INOUT_DESCRIPTOR(ITF_HID, ITF_HID + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, TUSB_DIR_IN_MASK | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10) };
|
||||
memcpy(p, desc, sizeof(desc));
|
||||
p += sizeof(desc);
|
||||
}
|
||||
if (ITF_KEYBOARD != ITF_INVALID) {
|
||||
TUSB_DESC_TOTAL_LEN += TUD_HID_DESC_LEN;
|
||||
const uint8_t desc_kb[] = { TUD_HID_DESCRIPTOR(ITF_KEYBOARD, ITF_KEYBOARD + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report_kb), TUSB_DIR_IN_MASK | EPNUM_HID_KB, 16, 5) };
|
||||
memcpy(p, desc_kb, sizeof(desc_kb));
|
||||
p += sizeof(desc_kb);
|
||||
}
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
if (ITF_CCID != ITF_INVALID) {
|
||||
TUSB_DESC_TOTAL_LEN += TUSB_SMARTCARD_CCID_DESC_LEN;
|
||||
const uint8_t desc_ccid[] = { TUD_SMARTCARD_DESCRIPTOR(ITF_CCID, ITF_CCID + 5, EPNUM_CCID, TUSB_DIR_IN_MASK | EPNUM_CCID, TUSB_DIR_IN_MASK | EPNUM_CCID_INT, 64) };
|
||||
memcpy(p, desc_ccid, sizeof(desc_ccid));
|
||||
p += sizeof(desc_ccid);
|
||||
}
|
||||
if (ITF_WCID != ITF_INVALID) {
|
||||
TUSB_DESC_TOTAL_LEN += TUSB_SMARTCARD_WCID_DESC_LEN;
|
||||
const uint8_t desc_wcid[] = { TUD_SMARTCARD_DESCRIPTOR_WEB(ITF_WCID, ITF_WCID + 5, EPNUM_WCID, TUSB_DIR_IN_MASK | EPNUM_WCID, 64) };
|
||||
memcpy(p, desc_wcid, sizeof(desc_wcid));
|
||||
p += sizeof(desc_wcid);
|
||||
}
|
||||
#endif
|
||||
desc_config[2] = TUSB_DESC_TOTAL_LEN & 0xFF;
|
||||
desc_config[3] = TUSB_DESC_TOTAL_LEN >> 8;
|
||||
}
|
||||
|
||||
#ifndef ESP_PLATFORM
|
||||
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
(void) index; // for multiple configurations
|
||||
usb_desc_setup();
|
||||
return desc_config;
|
||||
}
|
||||
#endif
|
||||
@@ -167,7 +220,7 @@ const tusb_desc_webusb_url_t desc_url =
|
||||
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
|
||||
|
||||
#define MS_OS_20_DESC_LEN 0xB2
|
||||
uint8_t const desc_ms_os_20[] = {
|
||||
uint8_t desc_ms_os_20[] = {
|
||||
// Set header: length, type, windows version, total length
|
||||
U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN),
|
||||
|
||||
@@ -175,7 +228,7 @@ uint8_t const desc_ms_os_20[] = {
|
||||
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A),
|
||||
|
||||
// Function Subset header: length, type, first interface, reserved, subset length
|
||||
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_WCID, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
|
||||
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), 0/*ITF_WCID*/, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
|
||||
|
||||
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
|
||||
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
|
||||
@@ -208,6 +261,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
|
||||
if (request->wIndex == 7) {
|
||||
// Get Microsoft OS 2.0 compatible descriptor
|
||||
uint16_t total_len;
|
||||
desc_ms_os_20[22] = ITF_WCID;
|
||||
memcpy(&total_len, desc_ms_os_20+8, 2);
|
||||
return tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_ms_os_20, total_len);
|
||||
}
|
||||
@@ -258,14 +312,14 @@ char const *string_desc_arr [] = {
|
||||
"Pol Henarejos", // 1: Manufacturer
|
||||
"Pico Key", // 2: Product
|
||||
"11223344", // 3: Serials, should use chip ID
|
||||
"Pico Key Config" // 4: Vendor Interface
|
||||
"Config" // 4: Vendor Interface
|
||||
#ifdef USB_ITF_HID
|
||||
, "Pico Key HID Interface"
|
||||
, "Pico Key HID Keyboard Interface"
|
||||
, "HID Interface"
|
||||
, "HID Keyboard Interface"
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
, "Pico Key CCID Interface"
|
||||
, "Pico Key WebCCID Interface"
|
||||
, "CCID OTP FIDO Interface"
|
||||
, "WebCCID Interface"
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -273,7 +327,7 @@ char const *string_desc_arr [] = {
|
||||
tinyusb_config_t tusb_cfg = {
|
||||
.device_descriptor = &desc_device,
|
||||
.string_descriptor = string_desc_arr,
|
||||
.string_descriptor_count = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]),
|
||||
.string_descriptor_count = (sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) > 8 ? 8 : (sizeof(string_desc_arr) / sizeof(string_desc_arr[0])),
|
||||
.external_phy = false,
|
||||
.configuration_descriptor = desc_config,
|
||||
};
|
||||
@@ -283,7 +337,7 @@ static uint16_t _desc_str[32];
|
||||
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
(void) langid;
|
||||
|
||||
uint8_t chr_count;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
if (index == 0) {
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
@@ -301,15 +355,27 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
if (index == 3) {
|
||||
str = pico_serial_str;
|
||||
}
|
||||
|
||||
chr_count = strlen(str);
|
||||
if (chr_count > 31) {
|
||||
chr_count = 31;
|
||||
else if (index == 2) {
|
||||
if (phy_data.usb_product_present) {
|
||||
str = phy_data.usb_product;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert ASCII string into UTF-16
|
||||
for (uint8_t i = 0; i < chr_count; i++) {
|
||||
_desc_str[1 + i] = str[i];
|
||||
uint8_t buff_avail = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1;
|
||||
if (index >= 4) {
|
||||
const char *product = phy_data.usb_product_present ? phy_data.usb_product : string_desc_arr[2];
|
||||
uint8_t len = MIN(strlen(product), buff_avail);
|
||||
for (int ix = 0; ix < len; chr_count++, ix++) {
|
||||
_desc_str[1 + chr_count] = product[ix];
|
||||
}
|
||||
buff_avail -= len;
|
||||
if (buff_avail > 0) {
|
||||
_desc_str[1 + chr_count++] = ' ';
|
||||
buff_avail--;
|
||||
}
|
||||
}
|
||||
for (int ix = 0; ix < MIN(strlen(str), buff_avail); chr_count++, ix++) {
|
||||
_desc_str[1 + chr_count] = str[ix];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user