78 Commits

Author SHA1 Message Date
Pol Henarejos
113e720fca Merge remote-tracking branch 'origin/main' 2025-06-22 19:58:17 +02:00
Pol Henarejos
c45c97ee1f Fix Pico Keys SDK build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-06-22 19:57:15 +02:00
Pol Henarejos
d66d1c85b9 Add missing header.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-06-22 19:52:36 +02:00
Pol Henarejos
f01aca5518 Flash size is obtained dynamically rather than in build time. It will allow to reduce dramatically the number of builds.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-30 12:06:26 +02:00
Pol Henarejos
da3a7f25d0 Fix bool build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-25 19:20:04 +02:00
Pol Henarejos
eb75ad4efa Add app_exists() to check if an AID is loaded. 2025-05-25 19:07:20 +02:00
Pol Henarejos
11d8a5343c Remove the tweak for packets multiple of 64 bytes. It was fixed in the USB stack handling (don't remember where).
Fixes #95.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-23 20:17:57 +02:00
Pol Henarejos
a324477a8a Fix interface descriptor when HID is disabled.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-02 18:28:38 +02:00
Pol Henarejos
580b0acffa Define MCU for emulation.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-07 01:24:03 +02:00
Pol Henarejos
3990e7643a Fix EPNUM counting for ESP32. It fixes the problem of not sending KB.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-06 18:31:01 +02:00
Pol Henarejos
5718c83083 Upgrade TinyUSB for ESP32
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-06 18:26:34 +02:00
Pol Henarejos
a75fd6b815 CTAP_RESP should be 0ed before sending.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-30 18:12:06 +02:00
Pol Henarejos
499e8fafaa Upgrade to mbedtls v3.6.3 and fix git subscripts.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-24 23:58:53 +01:00
Pol Henarejos
5f79a8c8ed Fix ESP32 dynamic USB interfaces.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-24 09:22:25 +01:00
Pol Henarejos
a08abaed0f Enable each USB interface independently depending on PHY parameters.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-22 23:25:31 +01:00
Pol Henarejos
4ef641b8d3 Always build ccid if defined.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-22 23:25:04 +01:00
Pol Henarejos
c185b35ca3 Add enabled USB interfaces in PHY.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-22 23:24:36 +01:00
Pol Henarejos
f1b1382300 USB descriptors are now created dynamically.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-21 15:30:50 +01:00
Pol Henarejos
f18f761234 Restore led mode when finishing button press.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-19 01:19:17 +01:00
Pol Henarejos
1a4ca13cc7 Add get led mode.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-19 01:18:57 +01:00
Pol Henarejos
ef9b66f990 Use TLV for PHY serialization/unserialization.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-17 11:36:14 +01:00
Pol Henarejos
7191cda6d3 Add PHY option to enable specific curves. It's in the app side the management.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-11 18:43:08 +01:00
Pol Henarejos
2c3fe5bebf Only pin to core in ESP32-S3 since it is multicore.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-03-07 19:35:13 +01:00
Pol Henarejos
9e9632f297 Fix commissioned values for LED.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-23 00:49:45 +01:00
Pol Henarejos
259c4854df Fix LED for ESP32S3
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-23 00:49:12 +01:00
Pol Henarejos
0a4c7b0981 Fix autobuild.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 19:56:19 +01:00
Pol Henarejos
db338842b9 Add git pull when switch
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 19:12:19 +01:00
Pol Henarejos
71af710568 Add EDDSA support as a conditional build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 19:00:21 +01:00
Pol Henarejos
e18f192edf Fix ESP32 build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 18:59:11 +01:00
Pol Henarejos
07415e6e8b Fix emulation build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 17:08:29 +01:00
Pol Henarejos
a9eff9fb17 Build cyw43 driver with RP2350.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 17:02:20 +01:00
Pol Henarejos
6e6b524878 Fix led driver build for Pimoroni.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-19 15:14:23 +01:00
Pol Henarejos
bfa085cae9 Take led_driver on build depending on defines.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-19 14:32:58 +01:00
Pol Henarejos
94a842fa04 Add file & line to debug info.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-19 11:43:47 +01:00
Pol Henarejos
90fb86be64 Add support for ESP32-S2 build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-19 11:18:11 +01:00
Pol Henarejos
f06cb3a96d Fix multiple interfaces in older PCSC versions.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-12 13:25:23 +01:00
Pol Henarejos
5985548c97 Merge pull request #7 from imkuang/limit-led-update-frequency
Limit the frequency of LED status updates
2025-02-09 19:16:29 +01:00
Pol Henarejos
3f5cbf6542 Merge pull request #8 from imkuang/update-led-ws2812-driver
Update ws2812 pio program and optimized the process of RGB color values
2025-02-09 19:12:39 +01:00
Ming Kuang
29c0d078c3 Update ws2812 pio program and optimized the process of RGB color values
1. Update ws2812 pio program to the latest version in pico-examples.
   References: https://github.com/raspberrypi/pico-examples/pull/486
2. Modify the rgbw type to false since we don't use the white channel.
3. Optimize the process of RGB color values to avoid a lot of shift
   operations and improve readability.
2025-02-09 16:51:22 +08:00
Ming Kuang
1723613b4e Limit the frequency of LED status updates
Unrestricted refreshing of the LED status may cause the WS2812
controller to not work properly.
Observed on my waveshare_rp2040_one board where the LED remains
either constantly on or off, even though the workflow should
dim or turn off/on the LED.
2025-02-09 15:35:42 +08:00
Pol Henarejos
44ca760e1c Added phy_save() and phy_load() to save and load PHY.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-29 17:09:20 +01:00
Pol Henarejos
4992d8e273 Added phy_save() and phy_load() to save and load PHY.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-29 17:06:55 +01:00
Pol Henarejos
80fa13a19c Do not init PHY on unserialize.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-29 16:57:53 +01:00
Pol Henarejos
b4c67d2fa5 Add PHY option to keep LED steady.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-29 16:27:26 +01:00
Pol Henarejos
18eb3e6ef2 Fixed stack overflow on serializing PHY.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-29 15:16:13 +01:00
Pol Henarejos
350f0da763 Fix USB keyboard descriptor.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-29 13:21:17 +01:00
Pol Henarejos
a081a2bde6 LibCCID allows propietary class for CCID (ALLOW_PROPIETARY_CLASS in LibCCID). Then both interfaces are loaded but since both belong to same device, only the last is opened.
We change maxSlot value even it breaks the ICCD spec to cause a timeout in LibCCID and deactivate WebCCID interface.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-17 20:56:03 +01:00
Pol Henarejos
3d912878f1 Add OTP (dummy value) for emulation.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-08 13:25:43 +01:00
Pol Henarejos
68a816895e Fix build for RP2040.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-30 21:37:38 +01:00
Pol Henarejos
1d89c14268 Compute flash memory bounds depending on the partition if available.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-30 21:27:46 +01:00
Pol Henarejos
5508c082e5 Add padding to align the struct in host build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-30 21:27:27 +01:00
Pol Henarejos
0bed03e522 Reduce data partition to 2K. It start always at half of flash.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-30 21:27:00 +01:00
Pol Henarejos
9e2b6ac4b6 Remove comment
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-24 02:05:50 +01:00
Pol Henarejos
046bac42e3 Update CCID descriptor to reflect max USB transport size.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-24 02:05:07 +01:00
Pol Henarejos
c59fb91540 Set stack size depending on the number of enabled interfaces.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-24 01:42:33 +01:00
Pol Henarejos
f8cb36c2cf Use uint16 funcs.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 21:23:13 +01:00
Pol Henarejos
d78e977926 Use BE/LE functions for packing uint16.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 21:00:43 +01:00
Pol Henarejos
8e68e6cae9 Use BE/LE functions for packing uint16.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 21:00:38 +01:00
Pol Henarejos
d530ea6979 Add BE/LE functions.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 20:39:47 +01:00
Pol Henarejos
f509833a3c Pack file struct for.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 20:39:31 +01:00
Pol Henarejos
4f5f2a8854 Add functions to pack/unpack uint32_t and uint64_t.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 20:26:52 +01:00
Pol Henarejos
ffaf20da5d Add memory statistics.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-23 19:35:56 +01:00
Pol Henarejos
e627b3fc86 Fix with string termination.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-17 17:06:08 +01:00
Pol Henarejos
585a6d77e3 Use USB product field in the descriptor.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-17 16:27:11 +01:00
Pol Henarejos
7805131d92 Introduce USB product name as a dynamic field.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-17 16:25:47 +01:00
Pol Henarejos
86999d8cdd Do not debug after write the buffer.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-16 18:42:42 +01:00
Pol Henarejos
6859cedcbf Use PHY value for LED GPIO number.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-16 13:10:51 +01:00
Pol Henarejos
1431f91281 In pure U2F mode, no keepalive is sent by authenticator. Instead, client sends commands to know the status.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-11 22:36:24 +01:00
Pol Henarejos
f58bcaecf1 In pure U2F mode, no keepalive is sent by authenticator. Instead, client sends commands to know the status.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-11 22:36:09 +01:00
Pol Henarejos
cb4e2ba0eb Fixes for ESP32-S3:
- It only supports 4 IN endpoints, so 1 EP must be removed (INT of CCID).
- It only supports 8 strings max.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-11 12:14:31 +01:00
Pol Henarejos
e9875b358c Fix cancel command.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-03 08:35:20 +01:00
Pol Henarejos
fcae98eecc Add support for tinyusb 0.17 in ESP32.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-01 01:23:56 +01:00
Pol Henarejos
a61f7683b6 Add option to disable power cycle on reset via Commissioner.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-12-01 01:07:25 +01:00
Pol Henarejos
a271785814 Fix build for RP2350.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-11-25 23:45:54 +01:00
Pol Henarejos
49758c6ac7 Fix ESP32 build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-11-25 22:59:01 +01:00
Pol Henarejos
9f79693025 Fix for Pico SDK 2.1.0
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-11-25 22:44:00 +01:00
Pol Henarejos
812f075ee4 Add UP button timeout to PHY.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-11-25 12:57:17 +01:00
Pol Henarejos
6a18e3aa83 Add CCID SET_DATA_RATE_AND_CLOCK command.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-11-25 12:54:57 +01:00
34 changed files with 973 additions and 391 deletions

View File

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

View File

@@ -24,7 +24,8 @@
{
"name": "Pico Keys Data",
"id": 1,
"size": "3072K",
"start": "2048K",
"size": "2048K",
"families": ["data"],
"permissions": {
"secure": "rw",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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