mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-28 17:11:23 +02:00
@@ -45,16 +45,16 @@ set(USB_ITF_CCID 1)
|
|||||||
set(USB_ITF_WCID 1)
|
set(USB_ITF_WCID 1)
|
||||||
include(cmake/version.cmake)
|
include(cmake/version.cmake)
|
||||||
include(cmake/options.cmake OPTIONAL)
|
include(cmake/options.cmake OPTIONAL)
|
||||||
include(pico_keys_sdk_import.cmake)
|
include(picokeys_sdk_import.cmake)
|
||||||
if(NOT ESP_PLATFORM)
|
if(NOT ESP_PLATFORM)
|
||||||
set(SOURCES ${PICO_KEYS_SOURCES})
|
set(SOURCES ${PICOKEYS_SOURCES})
|
||||||
endif()
|
endif()
|
||||||
list(APPEND SOURCES
|
list(APPEND SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/files.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/files.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/version.c
|
${CMAKE_CURRENT_LIST_DIR}/src/version.c
|
||||||
)
|
)
|
||||||
|
|
||||||
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/pico_keys_version.h")
|
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/picokeys_version.h")
|
||||||
|
|
||||||
if(ESP_PLATFORM)
|
if(ESP_PLATFORM)
|
||||||
project(pico_rescue)
|
project(pico_rescue)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# OpenSSL wrapper configuration for Pico Keys SDK.
|
# OpenSSL wrapper configuration for Pico Keys SDK.
|
||||||
# Keeps OpenSSL-specific build logic out of pico_keys_sdk_import.cmake.
|
# Keeps OpenSSL-specific build logic out of picokeys_sdk_import.cmake.
|
||||||
#
|
#
|
||||||
|
|
||||||
if(NOT DEFINED USE_OPENSSL)
|
if(NOT DEFINED USE_OPENSSL)
|
||||||
|
|||||||
8
config/esp32/components/cjson/CMakeLists.txt
Executable file
8
config/esp32/components/cjson/CMakeLists.txt
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
set(PICOKEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
|
||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
SRCS ${CJSON_SOURCES}
|
||||||
|
INCLUDE_DIRS ${PICOKEYS_SDK_DIR}/third-party/cjson
|
||||||
|
)
|
||||||
|
|
||||||
|
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
||||||
@@ -1,29 +1,30 @@
|
|||||||
set(PICO_KEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
|
set(PICOKEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
|
||||||
|
|
||||||
set(PICO_KEYS_INCLUDE_DIRS
|
set(PICOKEYS_INCLUDE_DIRS
|
||||||
${PICO_KEYS_SDK_DIR}/src
|
${PICOKEYS_SDK_DIR}/src
|
||||||
${PICO_KEYS_SDK_DIR}/src/fs
|
${PICOKEYS_SDK_DIR}/src/fs
|
||||||
${PICO_KEYS_SDK_DIR}/src/rng
|
${PICOKEYS_SDK_DIR}/src/rng
|
||||||
${PICO_KEYS_SDK_DIR}/src/usb
|
${PICOKEYS_SDK_DIR}/src/usb
|
||||||
${PICO_KEYS_SDK_DIR}/src/led
|
${PICOKEYS_SDK_DIR}/src/led
|
||||||
${PICO_KEYS_SDK_DIR}/third-party/tinycbor/src
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PICO_KEYS_REQUIRES
|
set(PICOKEYS_REQUIRES
|
||||||
bootloader_support
|
bootloader_support
|
||||||
esp_partition
|
esp_partition
|
||||||
esp_tinyusb
|
esp_tinyusb
|
||||||
efuse
|
efuse
|
||||||
mbedtls
|
mbedtls
|
||||||
tinycbor
|
tinycbor
|
||||||
|
lwip
|
||||||
|
cjson
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_PQC)
|
if(ENABLE_PQC)
|
||||||
list(APPEND PICO_KEYS_INCLUDE_DIRS
|
list(APPEND PICOKEYS_INCLUDE_DIRS
|
||||||
${PICO_KEYS_SDK_DIR}/third-party/mlkem/mlkem
|
${PICOKEYS_SDK_DIR}/third-party/mlkem/mlkem
|
||||||
${PICO_KEYS_SDK_DIR}/config/mlkem
|
${PICOKEYS_SDK_DIR}/config/mlkem
|
||||||
)
|
)
|
||||||
list(APPEND PICO_KEYS_REQUIRES
|
list(APPEND PICOKEYS_REQUIRES
|
||||||
mlkem512
|
mlkem512
|
||||||
mlkem768
|
mlkem768
|
||||||
mlkem1024
|
mlkem1024
|
||||||
@@ -31,9 +32,9 @@ if(ENABLE_PQC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${PICO_KEYS_SOURCES}
|
SRCS ${PICOKEYS_SOURCES}
|
||||||
INCLUDE_DIRS ${PICO_KEYS_INCLUDE_DIRS}
|
INCLUDE_DIRS ${PICOKEYS_INCLUDE_DIRS}
|
||||||
REQUIRES ${PICO_KEYS_REQUIRES}
|
REQUIRES ${PICOKEYS_REQUIRES}
|
||||||
)
|
)
|
||||||
|
|
||||||
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
set(PICO_KEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
|
set(PICOKEYS_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${CBOR_SOURCES}
|
SRCS ${CBOR_SOURCES}
|
||||||
INCLUDE_DIRS ${PICO_KEYS_SDK_DIR}/third-party/tinycbor/src
|
INCLUDE_DIRS ${PICOKEYS_SDK_DIR}/third-party/tinycbor/src
|
||||||
)
|
)
|
||||||
|
|
||||||
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ if(ENABLE_PQC)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/main.c
|
${CMAKE_CURRENT_LIST_DIR}/src/main.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
||||||
@@ -358,17 +358,20 @@ list(APPEND PICO_KEYS_SOURCES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/src/asn1.c
|
${CMAKE_CURRENT_LIST_DIR}/src/asn1.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/apdu.c
|
${CMAKE_CURRENT_LIST_DIR}/src/apdu.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/rescue.c
|
${CMAKE_CURRENT_LIST_DIR}/src/rescue.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/serial.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/pico_time.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/button.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led.c
|
${CMAKE_CURRENT_LIST_DIR}/src/led/led.c
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ESP_PLATFORM)
|
if(ESP_PLATFORM)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_neopixel.c
|
${CMAKE_CURRENT_LIST_DIR}/src/led/led_neopixel.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pico.c
|
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pico.c
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
if(NOT ENABLE_EMULATION)
|
if(NOT ENABLE_EMULATION)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_cyw43.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_pico.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pimoroni.c
|
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pimoroni.c
|
||||||
@@ -401,12 +404,14 @@ set(SYSTEM_INCLUDES
|
|||||||
)
|
)
|
||||||
|
|
||||||
if(USB_ITF_LWIP)
|
if(USB_ITF_LWIP)
|
||||||
|
if (NOT ESP_PLATFORM)
|
||||||
add_compile_definitions(
|
add_compile_definitions(
|
||||||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||||
MBEDTLS_SSL_PROTO_TLS1_2
|
MBEDTLS_SSL_PROTO_TLS1_2
|
||||||
MBEDTLS_SSL_SRV_C
|
MBEDTLS_SSL_SRV_C
|
||||||
MBEDTLS_SSL_TLS_C
|
MBEDTLS_SSL_TLS_C
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
list(APPEND MBEDTLS_SOURCES
|
list(APPEND MBEDTLS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/third-party/mbedtls/library/pkparse.c
|
${CMAKE_CURRENT_LIST_DIR}/third-party/mbedtls/library/pkparse.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/third-party/mbedtls/library/pk_ecc.c
|
${CMAKE_CURRENT_LIST_DIR}/third-party/mbedtls/library/pk_ecc.c
|
||||||
@@ -512,8 +517,8 @@ endfunction()
|
|||||||
|
|
||||||
# Apply strict warning flags to a caller-provided source list.
|
# Apply strict warning flags to a caller-provided source list.
|
||||||
# Usage:
|
# Usage:
|
||||||
# pico_keys_apply_strict_flags(SOURCES ${SOURCES} FILTER_REGEX "/src/fido/")
|
# picokeys_apply_strict_flags(SOURCES ${SOURCES} FILTER_REGEX "/src/fido/")
|
||||||
function(pico_keys_apply_strict_flags)
|
function(picokeys_apply_strict_flags)
|
||||||
set(options)
|
set(options)
|
||||||
set(oneValueArgs FILTER_REGEX)
|
set(oneValueArgs FILTER_REGEX)
|
||||||
set(multiValueArgs SOURCES)
|
set(multiValueArgs SOURCES)
|
||||||
@@ -523,7 +528,7 @@ function(pico_keys_apply_strict_flags)
|
|||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(PICO_KEYS_STRICT_FLAGS
|
set(PICOKEYS_STRICT_FLAGS
|
||||||
-Wextra
|
-Wextra
|
||||||
-pipe
|
-pipe
|
||||||
-funsigned-char
|
-funsigned-char
|
||||||
@@ -560,12 +565,12 @@ function(pico_keys_apply_strict_flags)
|
|||||||
continue()
|
continue()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
set_property(SOURCE "${src}" APPEND PROPERTY COMPILE_OPTIONS ${PICO_KEYS_STRICT_FLAGS})
|
set_property(SOURCE "${src}" APPEND PROPERTY COMPILE_OPTIONS ${PICOKEYS_STRICT_FLAGS})
|
||||||
endforeach()
|
endforeach()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
if(USB_ITF_HID)
|
if(USB_ITF_HID)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c
|
||||||
)
|
)
|
||||||
list(APPEND INCLUDES
|
list(APPEND INCLUDES
|
||||||
@@ -574,7 +579,7 @@ if(USB_ITF_HID)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USB_ITF_CCID)
|
if(USB_ITF_CCID)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c
|
||||||
)
|
)
|
||||||
list(APPEND INCLUDES
|
list(APPEND INCLUDES
|
||||||
@@ -587,7 +592,7 @@ if(NOT MSVC)
|
|||||||
add_compile_options("-fmacro-prefix-map=${CMAKE_CURRENT_LIST_DIR}/=")
|
add_compile_options("-fmacro-prefix-map=${CMAKE_CURRENT_LIST_DIR}/=")
|
||||||
endif()
|
endif()
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/mman.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/mman.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -596,11 +601,11 @@ if(ENABLE_EMULATION)
|
|||||||
add_definitions("-Wno-deprecated-declarations")
|
add_definitions("-Wno-deprecated-declarations")
|
||||||
endif()
|
endif()
|
||||||
add_compile_definitions(ENABLE_EMULATION)
|
add_compile_definitions(ENABLE_EMULATION)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/emulation.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/emulation.c
|
||||||
)
|
)
|
||||||
if(USE_OPENSSL_EMULATION_WRAPPER)
|
if(USE_OPENSSL_EMULATION_WRAPPER)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/openssl.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/openssl.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -611,7 +616,7 @@ if(ENABLE_EMULATION)
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -641,7 +646,7 @@ if(PICO_PLATFORM)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USB_ITF_LWIP)
|
if(USB_ITF_LWIP)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/rest.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/rest.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/rest_server.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/rest_server.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/rest_server_tls.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/rest_server_tls.c
|
||||||
@@ -650,8 +655,11 @@ if(USB_ITF_LWIP)
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip
|
||||||
)
|
)
|
||||||
if(NOT ENABLE_EMULATION)
|
if(NOT ENABLE_EMULATION)
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/lwip.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/lwip/lwip.c
|
||||||
|
)
|
||||||
|
if ((NOT ESP_PLATFORM) AND (NOT IDF_TARGET))
|
||||||
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${PICO_TINYUSB_PATH}/lib/networking/dhserver.c
|
${PICO_TINYUSB_PATH}/lib/networking/dhserver.c
|
||||||
${PICO_TINYUSB_PATH}/lib/networking/dnserver.c
|
${PICO_TINYUSB_PATH}/lib/networking/dnserver.c
|
||||||
)
|
)
|
||||||
@@ -662,6 +670,7 @@ if(USB_ITF_LWIP)
|
|||||||
message(STATUS "TINYUSB_PATH:\t\t ${PICO_TINYUSB_PATH}")
|
message(STATUS "TINYUSB_PATH:\t\t ${PICO_TINYUSB_PATH}")
|
||||||
message(STATUS "LWIP_PATH:\t\t ${PICO_LWIP_PATH}")
|
message(STATUS "LWIP_PATH:\t\t ${PICO_LWIP_PATH}")
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(PICO_RP2350)
|
if(PICO_RP2350)
|
||||||
@@ -686,24 +695,24 @@ if(PICO_RP2350)
|
|||||||
)
|
)
|
||||||
target_link_libraries(mbedtls PRIVATE pico_sha256)
|
target_link_libraries(mbedtls PRIVATE pico_sha256)
|
||||||
endif()
|
endif()
|
||||||
list(APPEND PICO_KEYS_SOURCES
|
list(APPEND PICOKEYS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt/sha256_alt.c
|
${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt/sha256_alt.c
|
||||||
)
|
)
|
||||||
add_compile_definitions(MBEDTLS_SHA256_ALT=1)
|
add_compile_definitions(MBEDTLS_SHA256_ALT=1)
|
||||||
list(APPEND LIBRARIES pico_sha256)
|
list(APPEND LIBRARIES pico_sha256)
|
||||||
endif()
|
endif()
|
||||||
set(INTERNAL_SOURCES ${PICO_KEYS_SOURCES})
|
set(INTERNAL_SOURCES ${PICOKEYS_SOURCES})
|
||||||
|
|
||||||
if(NOT TARGET pico_keys_sdk)
|
if(NOT TARGET picokeys_sdk)
|
||||||
if(PICO_PLATFORM)
|
if(PICO_PLATFORM)
|
||||||
pico_add_library(pico_keys_sdk)
|
pico_add_library(picokeys_sdk)
|
||||||
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${LIBRARIES})
|
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${LIBRARIES})
|
||||||
else()
|
else()
|
||||||
add_impl_library(pico_keys_sdk)
|
add_impl_library(picokeys_sdk)
|
||||||
endif()
|
endif()
|
||||||
target_sources(pico_keys_sdk INTERFACE ${PICO_KEYS_SOURCES})
|
target_sources(picokeys_sdk INTERFACE ${PICOKEYS_SOURCES})
|
||||||
target_include_directories(pico_keys_sdk INTERFACE ${INCLUDES})
|
target_include_directories(picokeys_sdk INTERFACE ${INCLUDES})
|
||||||
target_include_directories(pico_keys_sdk SYSTEM INTERFACE ${SYSTEM_INCLUDES})
|
target_include_directories(picokeys_sdk SYSTEM INTERFACE ${SYSTEM_INCLUDES})
|
||||||
target_link_libraries(pico_keys_sdk INTERFACE ${LIBRARIES})
|
target_link_libraries(picokeys_sdk INTERFACE ${LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
@@ -12,3 +12,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
|||||||
CONFIG_WL_SECTOR_SIZE_512=y
|
CONFIG_WL_SECTOR_SIZE_512=y
|
||||||
CONFIG_WL_SECTOR_MODE_PERF=y
|
CONFIG_WL_SECTOR_MODE_PERF=y
|
||||||
COMPILER_OPTIMIZATION="Performance"
|
COMPILER_OPTIMIZATION="Performance"
|
||||||
|
CONFIG_MBEDTLS_HKDF_C=y
|
||||||
|
|||||||
25
src/apdu.c
25
src/apdu.c
@@ -15,12 +15,13 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "pico_keys.h"
|
#include "led/led.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include "esp_compat.h"
|
#include "compat/esp_compat.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_EMULATION
|
#ifdef ENABLE_EMULATION
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
@@ -33,6 +34,8 @@ bool is_chaining = false;
|
|||||||
uint8_t chain_buf[2038];
|
uint8_t chain_buf[2038];
|
||||||
uint8_t *chain_ptr = NULL;
|
uint8_t *chain_ptr = NULL;
|
||||||
|
|
||||||
|
struct apdu apdu;
|
||||||
|
|
||||||
int process_apdu(void) {
|
int process_apdu(void) {
|
||||||
led_set_mode(MODE_PROCESSING);
|
led_set_mode(MODE_PROCESSING);
|
||||||
if (CLA(apdu) & 0x10) {
|
if (CLA(apdu) & 0x10) {
|
||||||
@@ -58,7 +61,7 @@ int process_apdu(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (INS(apdu) == 0xA4 && P1(apdu) == 0x04 && (P2(apdu) == 0x00 || P2(apdu) == 0x4)) { //select by AID
|
if (INS(apdu) == 0xA4 && P1(apdu) == 0x04 && (P2(apdu) == 0x00 || P2(apdu) == 0x4)) { //select by AID
|
||||||
if (select_app(apdu.data, apdu.nc) == PICOKEY_OK) {
|
if (select_app(apdu.data, apdu.nc) == PICOKEYS_OK) {
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
return SW_FILE_NOT_FOUND();
|
return SW_FILE_NOT_FOUND();
|
||||||
@@ -87,17 +90,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) {
|
else if (apdu.header[4] == 0x0 && buffer_size >= 7) {
|
||||||
if (buffer_size == 7) {
|
if (buffer_size == 7) {
|
||||||
apdu.ne = get_uint16_t_be(apdu.header + 5);
|
apdu.ne = get_uint16_be(apdu.header + 5);
|
||||||
if (apdu.ne == 0) {
|
if (apdu.ne == 0) {
|
||||||
apdu.ne = 65536;
|
apdu.ne = 65536;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
apdu.ne = 0;
|
apdu.ne = 0;
|
||||||
apdu.nc = get_uint16_t_be(apdu.header + 5);
|
apdu.nc = get_uint16_be(apdu.header + 5);
|
||||||
apdu.data = apdu.header + 7;
|
apdu.data = apdu.header + 7;
|
||||||
if (apdu.nc + 7 + 2 == buffer_size) {
|
if (apdu.nc + 7 + 2 == buffer_size) {
|
||||||
apdu.ne = get_uint16_t_be(apdu.header + buffer_size - 2);
|
apdu.ne = get_uint16_be(apdu.header + buffer_size - 2);
|
||||||
if (apdu.ne == 0) {
|
if (apdu.ne == 0) {
|
||||||
apdu.ne = 65536;
|
apdu.ne = 65536;
|
||||||
}
|
}
|
||||||
@@ -178,11 +181,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) {
|
uint16_t set_res_sw(uint8_t sw1, uint8_t sw2) {
|
||||||
apdu.sw = make_uint16_t_be(sw1, sw2);
|
apdu.sw = make_uint16_be(sw1, sw2);
|
||||||
if (sw1 != 0x90) {
|
if (sw1 != 0x90) {
|
||||||
res_APDU_size = 0;
|
res_APDU_size = 0;
|
||||||
}
|
}
|
||||||
return make_uint16_t_be(sw1, sw2);
|
return make_uint16_be(sw1, sw2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *apdu_thread(void *arg) {
|
void *apdu_thread(void *arg) {
|
||||||
@@ -225,7 +228,7 @@ done: ;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void apdu_finish(void) {
|
void apdu_finish(void) {
|
||||||
put_uint16_t_be(apdu.sw, apdu.rdata + apdu.rlen);
|
put_uint16_be(apdu.sw, apdu.rdata + apdu.rlen);
|
||||||
// timeout_stop();
|
// timeout_stop();
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
/* It was fixed in the USB handling. Keep it just in case */
|
/* It was fixed in the USB handling. Keep it just in case */
|
||||||
@@ -273,8 +276,8 @@ int bulk_cmd(int (*cmd)(void)) {
|
|||||||
*apdu.rdata++ = 0;
|
*apdu.rdata++ = 0;
|
||||||
apdu.rlen = 0;
|
apdu.rlen = 0;
|
||||||
cmd();
|
cmd();
|
||||||
put_uint16_t_be(apdu.rlen, apdu.rdata - 2);
|
put_uint16_be(apdu.rlen, apdu.rdata - 2);
|
||||||
put_uint16_t_be(apdu.sw, apdu.rdata + apdu.rlen);
|
put_uint16_be(apdu.sw, apdu.rdata + apdu.rlen);
|
||||||
rapdu_size += 4 + apdu.rlen + 2;
|
rapdu_size += 4 + apdu.rlen + 2;
|
||||||
apdu.rdata += apdu.rlen + 2;
|
apdu.rdata += apdu.rlen + 2;
|
||||||
p += 3 + apdu.nc;
|
p += 3 + apdu.nc;
|
||||||
|
|||||||
68
src/apdu.h
68
src/apdu.h
@@ -18,14 +18,10 @@
|
|||||||
#ifndef _APDU_H_
|
#ifndef _APDU_H_
|
||||||
#define _APDU_H_
|
#define _APDU_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stddef.h>
|
||||||
#if defined(PICO_PLATFORM)
|
#include <stdint.h>
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#endif
|
|
||||||
#include "compat.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "compat/compat.h"
|
||||||
|
|
||||||
typedef struct app {
|
typedef struct app {
|
||||||
const uint8_t *aid;
|
const uint8_t *aid;
|
||||||
@@ -76,4 +72,62 @@ extern uint16_t apdu_next(void);
|
|||||||
extern void *apdu_thread(void *);
|
extern void *apdu_thread(void *);
|
||||||
extern int bulk_cmd(int (*cmd)(void));
|
extern int bulk_cmd(int (*cmd)(void));
|
||||||
|
|
||||||
|
|
||||||
|
#define SW_BYTES_REMAINING_00() set_res_sw(0x61, 0x00)
|
||||||
|
#define SW_WARNING_STATE_UNCHANGED() set_res_sw(0x62, 0x00)
|
||||||
|
#define SW_WARNING_CORRUPTED() set_res_sw(0x62, 0x81)
|
||||||
|
#define SW_WARNING_EOF() set_res_sw(0x62, 0x82)
|
||||||
|
#define SW_WARNING_EF_DEACTIVATED() set_res_sw(0x62, 0x83)
|
||||||
|
#define SW_WARNING_WRONG_FCI() set_res_sw(0x62, 0x84)
|
||||||
|
#define SW_WARNING_EF_TERMINATED() set_res_sw(0x62, 0x85)
|
||||||
|
|
||||||
|
#define SW_WARNING_NOINFO() set_res_sw(0x63, 0x00)
|
||||||
|
#define SW_WARNING_FILLUP() set_res_sw(0x63, 0x81)
|
||||||
|
|
||||||
|
#define SW_EXEC_ERROR() set_res_sw(0x64, 0x00)
|
||||||
|
|
||||||
|
#define SW_MEMORY_FAILURE() set_res_sw(0x65, 0x81)
|
||||||
|
|
||||||
|
#define SW_SECURE_MESSAGE_EXEC_ERROR() set_res_sw(0x66, 0x00)
|
||||||
|
|
||||||
|
#define SW_WRONG_LENGTH() set_res_sw(0x67, 0x00)
|
||||||
|
#define SW_WRONG_DATA() set_res_sw(0x67, 0x00)
|
||||||
|
|
||||||
|
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED() set_res_sw(0x68, 0x81)
|
||||||
|
#define SW_SECURE_MESSAGING_NOT_SUPPORTED() set_res_sw(0x68, 0x82)
|
||||||
|
|
||||||
|
#define SW_COMMAND_INCOMPATIBLE() set_res_sw(0x69, 0x81)
|
||||||
|
#define SW_SECURITY_STATUS_NOT_SATISFIED() set_res_sw(0x69, 0x82)
|
||||||
|
#define SW_PIN_BLOCKED() set_res_sw(0x69, 0x83)
|
||||||
|
#define SW_DATA_INVALID() set_res_sw(0x69, 0x84)
|
||||||
|
#define SW_CONDITIONS_NOT_SATISFIED() set_res_sw(0x69, 0x85)
|
||||||
|
#define SW_COMMAND_NOT_ALLOWED() set_res_sw(0x69, 0x86)
|
||||||
|
#define SW_SECURE_MESSAGING_MISSING_DO() set_res_sw(0x69, 0x87)
|
||||||
|
#define SW_SECURE_MESSAGING_INCORRECT_DO() set_res_sw(0x69, 0x88)
|
||||||
|
#define SW_APPLET_SELECT_FAILED() set_res_sw(0x69, 0x99)
|
||||||
|
|
||||||
|
#define SW_INCORRECT_PARAMS() set_res_sw(0x6A, 0x80)
|
||||||
|
#define SW_FUNC_NOT_SUPPORTED() set_res_sw(0x6A, 0x81)
|
||||||
|
#define SW_FILE_NOT_FOUND() set_res_sw(0x6A, 0x82)
|
||||||
|
#define SW_RECORD_NOT_FOUND() set_res_sw(0x6A, 0x83)
|
||||||
|
#define SW_FILE_FULL() set_res_sw(0x6A, 0x84)
|
||||||
|
#define SW_WRONG_NE() set_res_sw(0x6A, 0x85)
|
||||||
|
#define SW_INCORRECT_P1P2() set_res_sw(0x6A, 0x86)
|
||||||
|
#define SW_WRONG_NC() set_res_sw(0x6A, 0x87)
|
||||||
|
#define SW_REFERENCE_NOT_FOUND() set_res_sw(0x6A, 0x88)
|
||||||
|
#define SW_FILE_EXISTS() set_res_sw(0x6A, 0x89)
|
||||||
|
|
||||||
|
#define SW_WRONG_P1P2() set_res_sw(0x6B, 0x00)
|
||||||
|
|
||||||
|
#define SW_CORRECT_LENGTH_00() set_res_sw(0x6C, 0x00)
|
||||||
|
|
||||||
|
#define SW_INS_NOT_SUPPORTED() set_res_sw(0x6D, 0x00)
|
||||||
|
|
||||||
|
#define SW_CLA_NOT_SUPPORTED() set_res_sw(0x6E, 0x00)
|
||||||
|
|
||||||
|
#define SW_UNKNOWN() set_res_sw(0x6F, 0x00)
|
||||||
|
|
||||||
|
#define SW_OK() set_res_sw(0x90, 0x00)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
10
src/asn1.c
10
src/asn1.c
@@ -15,22 +15,22 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
|
||||||
int asn1_ctx_init(uint8_t *data, uint16_t len, asn1_ctx_t *ctx) {
|
int asn1_ctx_init(uint8_t *data, uint16_t len, asn1_ctx_t *ctx) {
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
return PICOKEY_ERR_NULL_PARAM;
|
return PICOKEYS_ERR_NULL_PARAM;
|
||||||
}
|
}
|
||||||
ctx->data = data;
|
ctx->data = data;
|
||||||
ctx->len = len;
|
ctx->len = len;
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int asn1_ctx_clear(asn1_ctx_t *ctx) {
|
int asn1_ctx_clear(asn1_ctx_t *ctx) {
|
||||||
ctx->data = NULL;
|
ctx->data = NULL;
|
||||||
ctx->len = 0;
|
ctx->len = 0;
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t asn1_len(asn1_ctx_t *ctx) {
|
uint16_t asn1_len(asn1_ctx_t *ctx) {
|
||||||
@@ -73,7 +73,7 @@ uint8_t format_tlv_len(uint16_t len, uint8_t *out) {
|
|||||||
}
|
}
|
||||||
if (out) {
|
if (out) {
|
||||||
*out++ = 0x82;
|
*out++ = 0x82;
|
||||||
put_uint16_t_be(len, out);
|
put_uint16_be(len, out);
|
||||||
}
|
}
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,8 @@
|
|||||||
#ifndef _ASN1_H_
|
#ifndef _ASN1_H_
|
||||||
#define _ASN1_H_
|
#define _ASN1_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#if defined(PICO_PLATFORM)
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct asn1_ctx {
|
typedef struct asn1_ctx {
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
|||||||
159
src/button.c
Normal file
159
src/button.c
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
|
#include "button.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
#if defined(PICO_PLATFORM)
|
||||||
|
#include "bsp/board.h"
|
||||||
|
#include "hardware/sync.h"
|
||||||
|
#include "hardware/structs/ioqspi.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#elif defined(ESP_PLATFORM)
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#endif
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
extern void execute_tasks(void);
|
||||||
|
|
||||||
|
int (*button_pressed_cb)(uint8_t) = NULL;
|
||||||
|
|
||||||
|
static bool req_button_pending = false;
|
||||||
|
|
||||||
|
bool is_req_button_pending(void) {
|
||||||
|
return req_button_pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cancel_button = false;
|
||||||
|
|
||||||
|
#if !defined(ENABLE_EMULATION)
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
static bool picok_board_button_read(void) {
|
||||||
|
int boot_state = gpio_get_level(BOOT_PIN);
|
||||||
|
return boot_state == 0;
|
||||||
|
}
|
||||||
|
#elif defined(PICO_PLATFORM)
|
||||||
|
static bool __no_inline_not_in_flash_func(picok_get_bootsel_button)(void) {
|
||||||
|
const uint CS_PIN_INDEX = 1;
|
||||||
|
|
||||||
|
// Must disable interrupts, as interrupt handlers may be in flash, and we
|
||||||
|
// are about to temporarily disable flash access!
|
||||||
|
uint32_t flags = save_and_disable_interrupts();
|
||||||
|
|
||||||
|
// Set chip select to Hi-Z
|
||||||
|
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||||
|
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||||
|
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||||
|
|
||||||
|
// Note we can't call into any sleep functions in flash right now
|
||||||
|
for (volatile int i = 0; i < 1000; ++i);
|
||||||
|
|
||||||
|
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
|
||||||
|
// Note the button pulls the pin *low* when pressed.
|
||||||
|
#ifdef PICO_RP2040
|
||||||
|
#define CS_BIT (1u << 1)
|
||||||
|
#else
|
||||||
|
#define CS_BIT SIO_GPIO_HI_IN_QSPI_CSN_BITS
|
||||||
|
#endif
|
||||||
|
bool button_state = !(sio_hw->gpio_hi_in & CS_BIT);
|
||||||
|
|
||||||
|
// Need to restore the state of chip select, else we are going to have a
|
||||||
|
// bad time when we return to code in flash!
|
||||||
|
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||||
|
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||||
|
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||||
|
|
||||||
|
restore_interrupts(flags);
|
||||||
|
|
||||||
|
return button_state;
|
||||||
|
}
|
||||||
|
static bool picok_board_button_read(void) {
|
||||||
|
return picok_get_bootsel_button();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static bool picok_board_button_read(void) {
|
||||||
|
return true; // always unpressed
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
static bool button_pressed_state = false;
|
||||||
|
static uint32_t button_pressed_time = 0;
|
||||||
|
static uint8_t button_press = 0;
|
||||||
|
|
||||||
|
bool button_wait(void) {
|
||||||
|
/* Disabled by default. As LED may not be properly configured,
|
||||||
|
it will not be possible to indicate button press unless it
|
||||||
|
is commissioned. */
|
||||||
|
uint32_t button_timeout = 0;
|
||||||
|
if (phy_data.up_btn_present) {
|
||||||
|
button_timeout = phy_data.up_btn * 1000;
|
||||||
|
}
|
||||||
|
if (button_timeout == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
execute_tasks();
|
||||||
|
//sleep_ms(10);
|
||||||
|
if (start_button + button_timeout < board_millis()) { /* timeout */
|
||||||
|
timeout = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!timeout) {
|
||||||
|
while (picok_board_button_read() == true && cancel_button == false) {
|
||||||
|
execute_tasks();
|
||||||
|
//sleep_ms(10);
|
||||||
|
if (start_button + 15000 < board_millis()) { /* timeout */
|
||||||
|
timeout = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
led_set_mode(led_mode);
|
||||||
|
req_button_pending = false;
|
||||||
|
return timeout || cancel_button;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void button_task(void) {
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
if (button_pressed_cb && board_millis() > 1000 && !is_busy()) { // wait 1 second to boot up
|
||||||
|
bool current_button_state = picok_board_button_read();
|
||||||
|
if (current_button_state != button_pressed_state) {
|
||||||
|
if (current_button_state == false) { // unpressed
|
||||||
|
if (button_pressed_time == 0 || button_pressed_time + 1000 > board_millis()) {
|
||||||
|
button_press++;
|
||||||
|
}
|
||||||
|
button_pressed_time = board_millis();
|
||||||
|
}
|
||||||
|
button_pressed_state = current_button_state;
|
||||||
|
}
|
||||||
|
if (button_pressed_time > 0 && button_press > 0 && button_pressed_time + 1000 < board_millis() && button_pressed_state == false) {
|
||||||
|
if (button_pressed_cb != NULL) {
|
||||||
|
(*button_pressed_cb)(button_press);
|
||||||
|
}
|
||||||
|
button_pressed_time = button_press = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
31
src/button.h
Normal file
31
src/button.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BUTTON_H
|
||||||
|
#define BUTTON_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#if defined(ESP_PLATFORM)
|
||||||
|
#define BOOT_PIN GPIO_NUM_0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern bool button_wait(void);
|
||||||
|
extern void button_task(void);
|
||||||
|
|
||||||
|
#endif // BUTTON_H
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
#define QUEUE_H
|
#define QUEUE_H
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include "pthread_win32.h"
|
#include "compat/pthread_win32.h"
|
||||||
#include "semaphore_win32.h"
|
#include "compat/semaphore_win32.h"
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
@@ -15,21 +15,16 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(ESP_PLATFORM)
|
#include "picokeys.h"
|
||||||
#include "esp_compat.h"
|
#include "serial.h"
|
||||||
#elif defined(PICO_PLATFORM)
|
|
||||||
#include <pico/unique_id.h>
|
|
||||||
#endif
|
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
#include "mbedtls/hkdf.h"
|
#include "mbedtls/hkdf.h"
|
||||||
#include "mbedtls/gcm.h"
|
#include "mbedtls/gcm.h"
|
||||||
#include "crypto_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
#include "otp.h"
|
#include "otp.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int ct_memcmp(const void *a, const void *b, size_t n) {
|
int ct_memcmp(const void *a, const void *b, size_t n) {
|
||||||
const volatile uint8_t *x = (const volatile uint8_t *)a;
|
const volatile uint8_t *x = (const volatile uint8_t *)a;
|
||||||
@@ -109,7 +104,7 @@ int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len
|
|||||||
pin_derive_kenc(key, kenc);
|
pin_derive_kenc(key, kenc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return PICOKEY_WRONG_DATA;
|
return PICOKEYS_WRONG_DATA;
|
||||||
}
|
}
|
||||||
int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256);
|
int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256);
|
||||||
mbedtls_platform_zeroize(kenc, sizeof(kenc));
|
mbedtls_platform_zeroize(kenc, sizeof(kenc));
|
||||||
@@ -141,7 +136,7 @@ int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len
|
|||||||
pin_derive_kenc(key, kenc);
|
pin_derive_kenc(key, kenc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return PICOKEY_WRONG_DATA;
|
return PICOKEYS_WRONG_DATA;
|
||||||
}
|
}
|
||||||
int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256);
|
int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256);
|
||||||
mbedtls_platform_zeroize(kenc, sizeof(kenc));
|
mbedtls_platform_zeroize(kenc, sizeof(kenc));
|
||||||
@@ -210,9 +205,9 @@ int aes_encrypt(const uint8_t *key, const uint8_t *iv, uint16_t key_size, int mo
|
|||||||
}
|
}
|
||||||
int r = mbedtls_aes_setkey_enc(&aes, key, key_size);
|
int r = mbedtls_aes_setkey_enc(&aes, key, key_size);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
if (mode == PICO_KEYS_AES_MODE_CBC) {
|
if (mode == PICOKEYS_AES_MODE_CBC) {
|
||||||
return mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, len, tmp_iv, data, data);
|
return mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, len, tmp_iv, data, data);
|
||||||
}
|
}
|
||||||
return mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_ENCRYPT, len, &iv_offset, tmp_iv, data, data);
|
return mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_ENCRYPT, len, &iv_offset, tmp_iv, data, data);
|
||||||
@@ -229,9 +224,9 @@ int aes_decrypt(const uint8_t *key, const uint8_t *iv, uint16_t key_size, int mo
|
|||||||
}
|
}
|
||||||
int r = mbedtls_aes_setkey_dec(&aes, key, key_size);
|
int r = mbedtls_aes_setkey_dec(&aes, key, key_size);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
if (mode == PICO_KEYS_AES_MODE_CBC) {
|
if (mode == PICOKEYS_AES_MODE_CBC) {
|
||||||
return mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, len, tmp_iv, data, data);
|
return mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, len, tmp_iv, data, data);
|
||||||
}
|
}
|
||||||
r = mbedtls_aes_setkey_enc(&aes, key, key_size); //CFB requires set_enc instead set_dec
|
r = mbedtls_aes_setkey_enc(&aes, key, key_size); //CFB requires set_enc instead set_dec
|
||||||
@@ -239,10 +234,10 @@ int aes_decrypt(const uint8_t *key, const uint8_t *iv, uint16_t key_size, int mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len) {
|
int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len) {
|
||||||
return aes_encrypt(key, iv, 256, PICO_KEYS_AES_MODE_CFB, data, len);
|
return aes_encrypt(key, iv, 256, PICOKEYS_AES_MODE_CFB, data, len);
|
||||||
}
|
}
|
||||||
int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len) {
|
int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len) {
|
||||||
return aes_decrypt(key, iv, 256, PICO_KEYS_AES_MODE_CFB, data, len);
|
return aes_decrypt(key, iv, 256, PICOKEYS_AES_MODE_CFB, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lv_data {
|
struct lv_data {
|
||||||
|
|||||||
@@ -21,20 +21,20 @@
|
|||||||
#include "mbedtls/ecp.h"
|
#include "mbedtls/ecp.h"
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
#define PICO_KEYS_KEY_RSA 0x000f // It is a mask
|
#define PICOKEYS_KEY_RSA 0x000f // It is a mask
|
||||||
#define PICO_KEYS_KEY_RSA_1K 0x0001
|
#define PICOKEYS_KEY_RSA_1K 0x0001
|
||||||
#define PICO_KEYS_KEY_RSA_2K 0x0002
|
#define PICOKEYS_KEY_RSA_2K 0x0002
|
||||||
#define PICO_KEYS_KEY_RSA_3K 0x0004
|
#define PICOKEYS_KEY_RSA_3K 0x0004
|
||||||
#define PICO_KEYS_KEY_RSA_4k 0x0008
|
#define PICOKEYS_KEY_RSA_4k 0x0008
|
||||||
#define PICO_KEYS_KEY_EC 0x0010
|
#define PICOKEYS_KEY_EC 0x0010
|
||||||
#define PICO_KEYS_KEY_AES 0x0f00 // It is a mask
|
#define PICOKEYS_KEY_AES 0x0f00 // It is a mask
|
||||||
#define PICO_KEYS_KEY_AES_128 0x0100
|
#define PICOKEYS_KEY_AES_128 0x0100
|
||||||
#define PICO_KEYS_KEY_AES_192 0x0200
|
#define PICOKEYS_KEY_AES_192 0x0200
|
||||||
#define PICO_KEYS_KEY_AES_256 0x0400
|
#define PICOKEYS_KEY_AES_256 0x0400
|
||||||
#define PICO_KEYS_KEY_AES_512 0x0800 /* For AES XTS */
|
#define PICOKEYS_KEY_AES_512 0x0800 /* For AES XTS */
|
||||||
|
|
||||||
#define PICO_KEYS_AES_MODE_CBC 1
|
#define PICOKEYS_AES_MODE_CBC 1
|
||||||
#define PICO_KEYS_AES_MODE_CFB 2
|
#define PICOKEYS_AES_MODE_CFB 2
|
||||||
|
|
||||||
#define IV_SIZE 16
|
#define IV_SIZE 16
|
||||||
|
|
||||||
|
|||||||
43
src/eac.c
43
src/eac.c
@@ -15,6 +15,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
#include "eac.h"
|
#include "eac.h"
|
||||||
#include "crypto_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
@@ -100,13 +101,13 @@ int sm_sign(uint8_t *in, size_t in_len, uint8_t out[16]) {
|
|||||||
int sm_unwrap(void) {
|
int sm_unwrap(void) {
|
||||||
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
|
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
|
||||||
if (sm_indicator == 0) {
|
if (sm_indicator == 0) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
if (!sm_active || sm_blocksize == 0) {
|
if (!sm_active || sm_blocksize == 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
int r = sm_verify();
|
int r = sm_verify();
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEYS_OK) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
apdu.ne = sm_get_le();
|
apdu.ne = sm_get_le();
|
||||||
@@ -131,26 +132,26 @@ int sm_unwrap(void) {
|
|||||||
}
|
}
|
||||||
if (!body) {
|
if (!body) {
|
||||||
apdu.nc = 0;
|
apdu.nc = 0;
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
if (is87 && *body++ != 0x1) {
|
if (is87 && *body++ != 0x1) {
|
||||||
return PICOKEY_WRONG_PADDING;
|
return PICOKEYS_WRONG_PADDING;
|
||||||
}
|
}
|
||||||
sm_update_iv();
|
sm_update_iv();
|
||||||
aes_decrypt(sm_kenc, sm_iv, 128, PICO_KEYS_AES_MODE_CBC, body, body_size);
|
aes_decrypt(sm_kenc, sm_iv, 128, PICOKEYS_AES_MODE_CBC, body, body_size);
|
||||||
memmove(apdu.data, body, body_size);
|
memmove(apdu.data, body, body_size);
|
||||||
apdu.nc = sm_remove_padding(apdu.data, body_size);
|
apdu.nc = sm_remove_padding(apdu.data, body_size);
|
||||||
DEBUG_PAYLOAD(apdu.data, (int) apdu.nc);
|
DEBUG_PAYLOAD(apdu.data, (int) apdu.nc);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm_wrap(void) {
|
int sm_wrap(void) {
|
||||||
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
|
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
|
||||||
if (sm_indicator == 0) {
|
if (sm_indicator == 0) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
if (!sm_active || sm_blocksize == 0) {
|
if (!sm_active || sm_blocksize == 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
uint8_t input[USB_BUFFER_SIZE];
|
uint8_t input[USB_BUFFER_SIZE];
|
||||||
size_t input_len = 0;
|
size_t input_len = 0;
|
||||||
@@ -161,7 +162,7 @@ int sm_wrap(void) {
|
|||||||
mbedtls_mpi_copy(&sm_mSSC, &ssc);
|
mbedtls_mpi_copy(&sm_mSSC, &ssc);
|
||||||
int r = mbedtls_mpi_write_binary(&ssc, input, sm_blocksize);
|
int r = mbedtls_mpi_write_binary(&ssc, input, sm_blocksize);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
input_len += sm_blocksize;
|
input_len += sm_blocksize;
|
||||||
mbedtls_mpi_free(&ssc);
|
mbedtls_mpi_free(&ssc);
|
||||||
@@ -171,7 +172,7 @@ int sm_wrap(void) {
|
|||||||
res_APDU_size += (sm_blocksize - (res_APDU_size % sm_blocksize));
|
res_APDU_size += (sm_blocksize - (res_APDU_size % sm_blocksize));
|
||||||
DEBUG_PAYLOAD(res_APDU, res_APDU_size);
|
DEBUG_PAYLOAD(res_APDU, res_APDU_size);
|
||||||
sm_update_iv();
|
sm_update_iv();
|
||||||
aes_encrypt(sm_kenc, sm_iv, 128, PICO_KEYS_AES_MODE_CBC, res_APDU, res_APDU_size);
|
aes_encrypt(sm_kenc, sm_iv, 128, PICOKEYS_AES_MODE_CBC, res_APDU, res_APDU_size);
|
||||||
memmove(res_APDU + 1, res_APDU, res_APDU_size);
|
memmove(res_APDU + 1, res_APDU, res_APDU_size);
|
||||||
res_APDU[0] = 0x1;
|
res_APDU[0] = 0x1;
|
||||||
res_APDU_size++;
|
res_APDU_size++;
|
||||||
@@ -189,14 +190,14 @@ int sm_wrap(void) {
|
|||||||
else {
|
else {
|
||||||
memmove(res_APDU + 4, res_APDU, res_APDU_size);
|
memmove(res_APDU + 4, res_APDU, res_APDU_size);
|
||||||
res_APDU[1] = 0x82;
|
res_APDU[1] = 0x82;
|
||||||
put_uint16_t_be(res_APDU_size, res_APDU + 2);
|
put_uint16_be(res_APDU_size, res_APDU + 2);
|
||||||
res_APDU_size += 4;
|
res_APDU_size += 4;
|
||||||
}
|
}
|
||||||
res_APDU[0] = 0x87;
|
res_APDU[0] = 0x87;
|
||||||
}
|
}
|
||||||
res_APDU[res_APDU_size++] = 0x99;
|
res_APDU[res_APDU_size++] = 0x99;
|
||||||
res_APDU[res_APDU_size++] = 2;
|
res_APDU[res_APDU_size++] = 2;
|
||||||
put_uint16_t_be(apdu.sw, res_APDU + res_APDU_size);
|
put_uint16_be(apdu.sw, res_APDU + res_APDU_size);
|
||||||
res_APDU_size += 2;
|
res_APDU_size += 2;
|
||||||
memcpy(input + input_len, res_APDU, res_APDU_size);
|
memcpy(input + input_len, res_APDU, res_APDU_size);
|
||||||
input_len += res_APDU_size;
|
input_len += res_APDU_size;
|
||||||
@@ -210,7 +211,7 @@ int sm_wrap(void) {
|
|||||||
apdu.ne = res_APDU_size;
|
apdu.ne = res_APDU_size;
|
||||||
}
|
}
|
||||||
set_res_sw(0x90, 0x00);
|
set_res_sw(0x90, 0x00);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sm_get_le(void) {
|
uint16_t sm_get_le(void) {
|
||||||
@@ -235,7 +236,7 @@ void sm_update_iv(void) {
|
|||||||
uint8_t tmp_iv[16], sc_counter[16];
|
uint8_t tmp_iv[16], sc_counter[16];
|
||||||
memset(tmp_iv, 0, sizeof(tmp_iv)); //IV is always 0 for encryption of IV based on counter
|
memset(tmp_iv, 0, sizeof(tmp_iv)); //IV is always 0 for encryption of IV based on counter
|
||||||
mbedtls_mpi_write_binary(&sm_mSSC, sc_counter, sizeof(sc_counter));
|
mbedtls_mpi_write_binary(&sm_mSSC, sc_counter, sizeof(sc_counter));
|
||||||
aes_encrypt(sm_kenc, tmp_iv, 128, PICO_KEYS_AES_MODE_CBC, sc_counter, sizeof(sc_counter));
|
aes_encrypt(sm_kenc, tmp_iv, 128, PICOKEYS_AES_MODE_CBC, sc_counter, sizeof(sc_counter));
|
||||||
memcpy(sm_iv, sc_counter, sizeof(sc_counter));
|
memcpy(sm_iv, sc_counter, sizeof(sc_counter));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +251,7 @@ int sm_verify(void) {
|
|||||||
data_len += sm_blocksize;
|
data_len += sm_blocksize;
|
||||||
}
|
}
|
||||||
if (data_len + (add_header ? sm_blocksize : 0) > sizeof(input)) {
|
if (data_len + (add_header ? sm_blocksize : 0) > sizeof(input)) {
|
||||||
return PICOKEY_WRONG_LENGTH;
|
return PICOKEYS_WRONG_LENGTH;
|
||||||
}
|
}
|
||||||
mbedtls_mpi ssc;
|
mbedtls_mpi ssc;
|
||||||
mbedtls_mpi_init(&ssc);
|
mbedtls_mpi_init(&ssc);
|
||||||
@@ -260,7 +261,7 @@ int sm_verify(void) {
|
|||||||
input_len += sm_blocksize;
|
input_len += sm_blocksize;
|
||||||
mbedtls_mpi_free(&ssc);
|
mbedtls_mpi_free(&ssc);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
if (add_header) {
|
if (add_header) {
|
||||||
input[input_len++] = CLA(apdu);
|
input[input_len++] = CLA(apdu);
|
||||||
@@ -293,7 +294,7 @@ int sm_verify(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mac || mac_len != 8) {
|
if (!mac || mac_len != 8) {
|
||||||
return PICOKEY_WRONG_DATA;
|
return PICOKEYS_WRONG_DATA;
|
||||||
}
|
}
|
||||||
if (some_added) {
|
if (some_added) {
|
||||||
input[input_len++] = 0x80;
|
input[input_len++] = 0x80;
|
||||||
@@ -302,12 +303,12 @@ int sm_verify(void) {
|
|||||||
uint8_t signature[16];
|
uint8_t signature[16];
|
||||||
r = sm_sign(input, input_len, signature);
|
r = sm_sign(input, input_len, signature);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
if (memcmp(signature, mac, mac_len) == 0) {
|
if (memcmp(signature, mac, mac_len) == 0) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
return PICOKEY_VERIFICATION_FAILED;
|
return PICOKEYS_VERIFICATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sm_remove_padding(const uint8_t *data, uint16_t data_len) {
|
uint16_t sm_remove_padding(const uint8_t *data, uint16_t data_len) {
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
#ifndef _EAC_H_
|
#ifndef _EAC_H_
|
||||||
#define _EAC_H_
|
#define _EAC_H_
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef enum MSE_protocol {
|
typedef enum MSE_protocol {
|
||||||
MSE_AES = 0,
|
MSE_AES = 0,
|
||||||
|
|||||||
@@ -15,12 +15,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
extern const uintptr_t end_data_pool;
|
extern const uintptr_t end_data_pool;
|
||||||
extern const uintptr_t start_data_pool;
|
extern const uintptr_t start_data_pool;
|
||||||
@@ -48,11 +47,11 @@ void process_fci(const file_t *pe, int fmd) {
|
|||||||
if ((pe->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) {
|
if ((pe->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) {
|
||||||
int (*data_fn)(const file_t *, int) = (int (*)(const file_t *, int))(uintptr_t)pe->data;
|
int (*data_fn)(const file_t *, int) = (int (*)(const file_t *, int))(uintptr_t)pe->data;
|
||||||
uint16_t len = (uint16_t)data_fn(pe, 0);
|
uint16_t len = (uint16_t)data_fn(pe, 0);
|
||||||
res_APDU_size += put_uint16_t_be(len, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint16_be(len, res_APDU + res_APDU_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint16_t v = file_get_size(pe);
|
uint16_t v = file_get_size(pe);
|
||||||
res_APDU_size += put_uint16_t_be(v, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint16_be(v, res_APDU + res_APDU_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -78,7 +77,7 @@ void process_fci(const file_t *pe, int fmd) {
|
|||||||
|
|
||||||
res_APDU[res_APDU_size++] = 0x83;
|
res_APDU[res_APDU_size++] = 0x83;
|
||||||
res_APDU[res_APDU_size++] = 2;
|
res_APDU[res_APDU_size++] = 2;
|
||||||
res_APDU_size += put_uint16_t_be(pe->fid, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint16_be(pe->fid, res_APDU + res_APDU_size);
|
||||||
if (pe->name) {
|
if (pe->name) {
|
||||||
res_APDU[res_APDU_size++] = 0x84;
|
res_APDU[res_APDU_size++] = 0x84;
|
||||||
res_APDU[res_APDU_size++] = MIN(pe->name[0], 16);
|
res_APDU[res_APDU_size++] = MIN(pe->name[0], 16);
|
||||||
@@ -165,13 +164,13 @@ static uint8_t make_path_buf(const file_t *pe, uint8_t *buf, uint8_t buflen, con
|
|||||||
if (pe == top) { //MF or relative DF
|
if (pe == top) { //MF or relative DF
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
put_uint16_t_be(pe->fid, buf);
|
put_uint16_be(pe->fid, buf);
|
||||||
return make_path_buf(&file_entries[pe->parent], buf + 2, buflen - 2, top) + 2;
|
return make_path_buf(&file_entries[pe->parent], buf + 2, buflen - 2, top) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t make_path(const file_t *pe, const file_t *top, uint8_t *path) {
|
static uint8_t make_path(const file_t *pe, const file_t *top, uint8_t *path) {
|
||||||
uint8_t buf[MAX_DEPTH * 2], *p = path;
|
uint8_t buf[MAX_DEPTH * 2], *p = path;
|
||||||
put_uint16_t_be(pe->fid, buf);
|
put_uint16_be(pe->fid, buf);
|
||||||
uint8_t depth = make_path_buf(&file_entries[pe->parent], buf + 2, sizeof(buf) - 2, top) + 2;
|
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) {
|
for (int d = depth - 2; d >= 0; d -= 2) {
|
||||||
memcpy(p, buf + d, 2);
|
memcpy(p, buf + d, 2);
|
||||||
@@ -330,7 +329,7 @@ file_t *search_dynamic_file(uint16_t fid) {
|
|||||||
|
|
||||||
int delete_dynamic_file(file_t *f) {
|
int delete_dynamic_file(file_t *f) {
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < dynamic_files; i++) {
|
for (int i = 0; i < dynamic_files; i++) {
|
||||||
if (dynamic_file[i].fid == f->fid) {
|
if (dynamic_file[i].fid == f->fid) {
|
||||||
@@ -338,10 +337,10 @@ int delete_dynamic_file(file_t *f) {
|
|||||||
memcpy(&dynamic_file[j - 1], &dynamic_file[j], sizeof(file_t));
|
memcpy(&dynamic_file[j - 1], &dynamic_file[j], sizeof(file_t));
|
||||||
}
|
}
|
||||||
dynamic_files--;
|
dynamic_files--;
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_t *file_new(uint16_t fid) {
|
file_t *file_new(uint16_t fid) {
|
||||||
@@ -381,7 +380,7 @@ uint16_t meta_find(uint16_t fid, uint8_t **out) {
|
|||||||
if (tag_len < 2) {
|
if (tag_len < 2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint16_t cfid = get_uint16_t_be(tag_data);
|
uint16_t cfid = get_uint16_be(tag_data);
|
||||||
if (cfid == fid) {
|
if (cfid == fid) {
|
||||||
if (out) {
|
if (out) {
|
||||||
*out = tag_data + 2;
|
*out = tag_data + 2;
|
||||||
@@ -394,7 +393,7 @@ uint16_t meta_find(uint16_t fid, uint8_t **out) {
|
|||||||
int meta_delete(uint16_t fid) {
|
int meta_delete(uint16_t fid) {
|
||||||
file_t *ef = search_file(EF_META);
|
file_t *ef = search_file(EF_META);
|
||||||
if (!ef) {
|
if (!ef) {
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
uint16_t tag = 0x0;
|
uint16_t tag = 0x0;
|
||||||
uint8_t *tag_data = NULL, *p = NULL;
|
uint8_t *tag_data = NULL, *p = NULL;
|
||||||
@@ -407,7 +406,7 @@ int meta_delete(uint16_t fid) {
|
|||||||
if (tag_len < 2) {
|
if (tag_len < 2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint16_t cfid = get_uint16_t_be(tag_data);
|
uint16_t cfid = get_uint16_be(tag_data);
|
||||||
if (cfid == fid) {
|
if (cfid == fid) {
|
||||||
uint16_t new_len = ctxi.len - 1 - tag_len - format_tlv_len(tag_len, NULL);
|
uint16_t new_len = ctxi.len - 1 - tag_len - format_tlv_len(tag_len, NULL);
|
||||||
if (new_len == 0) {
|
if (new_len == 0) {
|
||||||
@@ -423,21 +422,21 @@ int meta_delete(uint16_t fid) {
|
|||||||
}
|
}
|
||||||
int r = file_put_data(ef, fdata, new_len);
|
int r = file_put_data(ef, fdata, new_len);
|
||||||
free(fdata);
|
free(fdata);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEYS_OK) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||||
int r;
|
int r;
|
||||||
file_t *ef = search_file(EF_META);
|
file_t *ef = search_file(EF_META);
|
||||||
if (!ef) {
|
if (!ef) {
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
uint16_t ef_size = file_get_size(ef);
|
uint16_t ef_size = file_get_size(ef);
|
||||||
uint8_t *fdata = (uint8_t *) calloc(1, ef_size);
|
uint8_t *fdata = (uint8_t *) calloc(1, ef_size);
|
||||||
@@ -451,16 +450,16 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
|||||||
if (tag_len < 2) {
|
if (tag_len < 2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint16_t cfid = get_uint16_t_be(tag_data);
|
uint16_t cfid = get_uint16_be(tag_data);
|
||||||
if (cfid == fid) {
|
if (cfid == fid) {
|
||||||
if (tag_len - 2 == len) { //an update
|
if (tag_len - 2 == len) { //an update
|
||||||
memcpy(p - tag_len + 2, data, len);
|
memcpy(p - tag_len + 2, data, len);
|
||||||
r = file_put_data(ef, fdata, ef_size);
|
r = file_put_data(ef, fdata, ef_size);
|
||||||
free(fdata);
|
free(fdata);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEYS_OK) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
else { //needs reallocation
|
else { //needs reallocation
|
||||||
uint8_t *tpos = p - asn1_len_tag(tag, tag_len);
|
uint8_t *tpos = p - asn1_len_tag(tag, tag_len);
|
||||||
@@ -475,20 +474,20 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free(fdata);
|
free(fdata);
|
||||||
return PICOKEY_ERR_MEMORY_FATAL;
|
return PICOKEYS_ERR_MEMORY_FATAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t *f = fdata + meta_offset;
|
uint8_t *f = fdata + meta_offset;
|
||||||
*f++ = fid & 0xff;
|
*f++ = fid & 0xff;
|
||||||
f += format_tlv_len(len + 2, f);
|
f += format_tlv_len(len + 2, f);
|
||||||
f += put_uint16_t_be(fid, f);
|
f += put_uint16_be(fid, f);
|
||||||
memcpy(f, data, len);
|
memcpy(f, data, len);
|
||||||
r = file_put_data(ef, fdata, ef_size);
|
r = file_put_data(ef, fdata, ef_size);
|
||||||
free(fdata);
|
free(fdata);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEYS_OK) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -496,14 +495,14 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
|||||||
uint8_t *f = fdata + ef_size;
|
uint8_t *f = fdata + ef_size;
|
||||||
*f++ = fid & 0x1f;
|
*f++ = fid & 0x1f;
|
||||||
f += format_tlv_len(len + 2, f);
|
f += format_tlv_len(len + 2, f);
|
||||||
f += put_uint16_t_be(fid, f);
|
f += put_uint16_be(fid, f);
|
||||||
memcpy(f, data, len);
|
memcpy(f, data, len);
|
||||||
r = file_put_data(ef, fdata, ef_size + (uint16_t)asn1_len_tag(fid & 0x1f, len + 2));
|
r = file_put_data(ef, fdata, ef_size + (uint16_t)asn1_len_tag(fid & 0x1f, len + 2));
|
||||||
free(fdata);
|
free(fdata);
|
||||||
if (r != PICOKEY_OK) {
|
if (r != PICOKEYS_OK) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file_has_data(const file_t *f) {
|
bool file_has_data(const file_t *f) {
|
||||||
@@ -512,15 +511,15 @@ bool file_has_data(const file_t *f) {
|
|||||||
|
|
||||||
int delete_file(file_t *ef) {
|
int delete_file(file_t *ef) {
|
||||||
if (ef == NULL) {
|
if (ef == NULL) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
meta_delete(ef->fid);
|
meta_delete(ef->fid);
|
||||||
if (flash_clear_file(ef) != PICOKEY_OK) {
|
if (flash_clear_file(ef) != PICOKEYS_OK) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
if (delete_dynamic_file(ef) != PICOKEY_OK) {
|
if (delete_dynamic_file(ef) != PICOKEYS_OK) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEYS_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,10 @@
|
|||||||
#ifndef _FILE_H_
|
#ifndef _FILE_H_
|
||||||
#define _FILE_H_
|
#define _FILE_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stddef.h>
|
||||||
#if defined(PICO_PLATFORM)
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#else
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#include <stdbool.h>
|
||||||
#include "compat.h"
|
#include "compat/compat.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
|
||||||
#define FILE_TYPE_NOT_KNOWN 0x00
|
#define FILE_TYPE_NOT_KNOWN 0x00
|
||||||
@@ -167,7 +163,7 @@ extern uint8_t flash_read_uint8(uintptr_t addr);
|
|||||||
extern uint8_t *flash_read(uintptr_t addr);
|
extern uint8_t *flash_read(uintptr_t addr);
|
||||||
extern int flash_erase_page(uintptr_t addr, size_t page_size);
|
extern int flash_erase_page(uintptr_t addr, size_t page_size);
|
||||||
extern bool flash_check_blank(const uint8_t *p_start, size_t size);
|
extern bool flash_check_blank(const uint8_t *p_start, size_t size);
|
||||||
extern void do_flash(void);
|
extern void flash_task(void);
|
||||||
extern void low_flash_init(void);
|
extern void low_flash_init(void);
|
||||||
|
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
|
|||||||
@@ -15,10 +15,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "pico_keys.h"
|
|
||||||
|
|
||||||
#if !defined(PICO_PLATFORM)
|
#if !defined(PICO_PLATFORM)
|
||||||
#define XIP_BASE 0
|
#define XIP_BASE 0
|
||||||
@@ -34,11 +31,11 @@ uint32_t FLASH_SIZE_BYTES = (1 * 1024 * 1024);
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
uint32_t FLASH_SIZE_BYTES = (2 * 1024 * 1024);
|
uint32_t FLASH_SIZE_BYTES = (2 * 1024 * 1024);
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "hardware/flash.h"
|
#include "hardware/flash.h"
|
||||||
#endif
|
#endif
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
extern void low_flash_task(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ------------------------------------------------------
|
* ------------------------------------------------------
|
||||||
@@ -116,7 +113,7 @@ static uintptr_t allocate_free_addr(uint16_t size, bool persistent) {
|
|||||||
|
|
||||||
int flash_clear_file(file_t *file) {
|
int flash_clear_file(file_t *file) {
|
||||||
if (file == NULL || file->data == NULL) {
|
if (file == NULL || file->data == NULL) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_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 prev_addr = flash_read_uintptr(base_addr + sizeof(uintptr_t));
|
||||||
@@ -132,17 +129,17 @@ int flash_clear_file(file_t *file) {
|
|||||||
file->data = NULL;
|
file->data = NULL;
|
||||||
num_files--;
|
num_files--;
|
||||||
//printf("na %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr));
|
//printf("na %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr));
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len, uint16_t offset) {
|
static int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len, uint16_t offset) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return PICOKEY_ERR_NULL_PARAM;
|
return PICOKEYS_ERR_NULL_PARAM;
|
||||||
}
|
}
|
||||||
uint16_t size_file_flash = file->data ? flash_read_uint16((uintptr_t) file->data) : 0;
|
uint16_t size_file_flash = file->data ? flash_read_uint16((uintptr_t) file->data) : 0;
|
||||||
uint8_t *old_data = NULL;
|
uint8_t *old_data = NULL;
|
||||||
if (offset + len > FLASH_SECTOR_SIZE || offset > size_file_flash) {
|
if (offset + len > FLASH_SECTOR_SIZE || offset > size_file_flash) {
|
||||||
return PICOKEY_ERR_NO_MEMORY;
|
return PICOKEYS_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
if (file->data) { //already in flash
|
if (file->data) { //already in flash
|
||||||
if (offset + len <= size_file_flash) { //it fits, no need to move it
|
if (offset + len <= size_file_flash) { //it fits, no need to move it
|
||||||
@@ -150,7 +147,7 @@ static int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, ui
|
|||||||
if (data) {
|
if (data) {
|
||||||
flash_program_block((uintptr_t) file->data + sizeof(uint16_t) + offset, data, len);
|
flash_program_block((uintptr_t) file->data + sizeof(uint16_t) + offset, data, len);
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
else { //we clear the old file
|
else { //we clear the old file
|
||||||
flash_clear_file(file);
|
flash_clear_file(file);
|
||||||
@@ -167,7 +164,7 @@ static int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, ui
|
|||||||
uintptr_t new_addr = allocate_free_addr(len, (file->type & FILE_PERSISTENT) == FILE_PERSISTENT);
|
uintptr_t new_addr = allocate_free_addr(len, (file->type & FILE_PERSISTENT) == FILE_PERSISTENT);
|
||||||
//printf("na %x\n",new_addr);
|
//printf("na %x\n",new_addr);
|
||||||
if (new_addr == 0x0) {
|
if (new_addr == 0x0) {
|
||||||
return PICOKEY_ERR_NO_MEMORY;
|
return PICOKEYS_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
if (new_addr < last_base) {
|
if (new_addr < last_base) {
|
||||||
last_base = new_addr;
|
last_base = new_addr;
|
||||||
@@ -182,7 +179,7 @@ static int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, ui
|
|||||||
free(old_data);
|
free(old_data);
|
||||||
}
|
}
|
||||||
num_files++;
|
num_files++;
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
|
int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
|
||||||
@@ -208,3 +205,7 @@ uint32_t flash_num_files(void) {
|
|||||||
uint32_t flash_size(void) {
|
uint32_t flash_size(void) {
|
||||||
return FLASH_SIZE_BYTES;
|
return FLASH_SIZE_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flash_task(void) {
|
||||||
|
low_flash_task();
|
||||||
|
}
|
||||||
|
|||||||
23
src/fs/flash.h
Normal file
23
src/fs/flash.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FLASH_H
|
||||||
|
#define _FLASH_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _FLASH_H
|
||||||
@@ -15,16 +15,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
#include <stdint.h>
|
#include "serial.h"
|
||||||
#include <stdlib.h>
|
#include "crypto_utils.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "pico_keys.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include "crypto_utils.h"
|
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "hardware/flash.h"
|
#include "hardware/flash.h"
|
||||||
#include "hardware/sync.h"
|
#include "hardware/sync.h"
|
||||||
#include "pico/mutex.h"
|
#include "pico/mutex.h"
|
||||||
@@ -34,7 +28,7 @@
|
|||||||
#include "boot/picobin.h"
|
#include "boot/picobin.h"
|
||||||
#else
|
#else
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include "esp_compat.h"
|
#include "compat/esp_compat.h"
|
||||||
#include "esp_partition.h"
|
#include "esp_partition.h"
|
||||||
const esp_partition_t *part0;
|
const esp_partition_t *part0;
|
||||||
#define save_and_disable_interrupts() 1
|
#define save_and_disable_interrupts() 1
|
||||||
@@ -56,7 +50,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
#include "queue.h"
|
#include "compat/queue.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_EMULATION
|
#ifdef ENABLE_EMULATION
|
||||||
#define FLASH_SECTOR_SIZE 0x4000
|
#define FLASH_SECTOR_SIZE 0x4000
|
||||||
@@ -103,7 +97,7 @@ bool flash_available = false;
|
|||||||
|
|
||||||
|
|
||||||
//this function has to be called from the core 0
|
//this function has to be called from the core 0
|
||||||
void do_flash(void) {
|
void low_flash_task(void) {
|
||||||
if (mutex_try_enter(&mtx_flash, NULL) == true) {
|
if (mutex_try_enter(&mtx_flash, NULL) == true) {
|
||||||
if (locked_out == true && flash_available == true && ready_pages > 0) {
|
if (locked_out == true && flash_available == true && ready_pages > 0) {
|
||||||
//printf(" DO_FLASH AVAILABLE\n");
|
//printf(" DO_FLASH AVAILABLE\n");
|
||||||
@@ -284,24 +278,24 @@ int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len) {
|
|||||||
page_flash_t *p = NULL;
|
page_flash_t *p = NULL;
|
||||||
|
|
||||||
if (!data || len == 0) {
|
if (!data || len == 0) {
|
||||||
return PICOKEY_ERR_NULL_PARAM;
|
return PICOKEYS_ERR_NULL_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_enter_blocking(&mtx_flash);
|
mutex_enter_blocking(&mtx_flash);
|
||||||
if (ready_pages == TOTAL_FLASH_PAGES) {
|
if (ready_pages == TOTAL_FLASH_PAGES) {
|
||||||
mutex_exit(&mtx_flash);
|
mutex_exit(&mtx_flash);
|
||||||
printf("ERROR: ALL FLASH PAGES CACHED\n");
|
printf("ERROR: ALL FLASH PAGES CACHED\n");
|
||||||
return PICOKEY_ERR_NO_MEMORY;
|
return PICOKEYS_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
if (!(p = find_free_page(addr))) {
|
if (!(p = find_free_page(addr))) {
|
||||||
mutex_exit(&mtx_flash);
|
mutex_exit(&mtx_flash);
|
||||||
printf("ERROR: FLASH CANNOT FIND A PAGE (rare error)\n");
|
printf("ERROR: FLASH CANNOT FIND A PAGE (rare error)\n");
|
||||||
return PICOKEY_ERR_MEMORY_FATAL;
|
return PICOKEYS_ERR_MEMORY_FATAL;
|
||||||
}
|
}
|
||||||
memcpy(&p->page[addr & (FLASH_SECTOR_SIZE - 1)], data, len);
|
memcpy(&p->page[addr & (FLASH_SECTOR_SIZE - 1)], data, len);
|
||||||
//printf("Flash: modified page %X with data %x at [%x]\n",(uintptr_t)addr,(uintptr_t)data,addr&(FLASH_SECTOR_SIZE-1));
|
//printf("Flash: modified page %X with data %x at [%x]\n",(uintptr_t)addr,(uintptr_t)data,addr&(FLASH_SECTOR_SIZE-1));
|
||||||
mutex_exit(&mtx_flash);
|
mutex_exit(&mtx_flash);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flash_program_halfword(uintptr_t addr, uint16_t data) {
|
int flash_program_halfword(uintptr_t addr, uint16_t data) {
|
||||||
@@ -365,19 +359,19 @@ int flash_erase_page(uintptr_t addr, size_t page_size) {
|
|||||||
if (ready_pages == TOTAL_FLASH_PAGES) {
|
if (ready_pages == TOTAL_FLASH_PAGES) {
|
||||||
mutex_exit(&mtx_flash);
|
mutex_exit(&mtx_flash);
|
||||||
printf("ERROR: ALL FLASH PAGES CACHED\n");
|
printf("ERROR: ALL FLASH PAGES CACHED\n");
|
||||||
return PICOKEY_ERR_NO_MEMORY;
|
return PICOKEYS_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
if (!(p = find_free_page(addr))) {
|
if (!(p = find_free_page(addr))) {
|
||||||
printf("ERROR: FLASH CANNOT FIND A PAGE (rare error)\n");
|
printf("ERROR: FLASH CANNOT FIND A PAGE (rare error)\n");
|
||||||
mutex_exit(&mtx_flash);
|
mutex_exit(&mtx_flash);
|
||||||
return PICOKEY_ERR_MEMORY_FATAL;
|
return PICOKEYS_ERR_MEMORY_FATAL;
|
||||||
}
|
}
|
||||||
p->erase = true;
|
p->erase = true;
|
||||||
p->ready = false;
|
p->ready = false;
|
||||||
p->page_size = page_size;
|
p->page_size = page_size;
|
||||||
mutex_exit(&mtx_flash);
|
mutex_exit(&mtx_flash);
|
||||||
|
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flash_check_blank(const uint8_t *p_start, size_t size) {
|
bool flash_check_blank(const uint8_t *p_start, size_t size) {
|
||||||
|
|||||||
42
src/fs/otp.c
42
src/fs/otp.c
@@ -15,9 +15,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "file.h"
|
#include "picokeys.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "otp.h"
|
#include "otp.h"
|
||||||
|
|
||||||
#ifdef PICO_RP2350
|
#ifdef PICO_RP2350
|
||||||
@@ -255,8 +253,8 @@ typedef esp_err_t otp_ret_t;
|
|||||||
#ifndef SECURE_BOOT_BOOTKEY_INDEX
|
#ifndef SECURE_BOOT_BOOTKEY_INDEX
|
||||||
#define SECURE_BOOT_BOOTKEY_INDEX 0
|
#define SECURE_BOOT_BOOTKEY_INDEX 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef PICO_KEYS_REQUIRE_SECURE_BOOT_BEFORE_LOCK
|
#ifndef PICOKEYS_REQUIRE_SECURE_BOOT_BEFORE_LOCK
|
||||||
#define PICO_KEYS_REQUIRE_SECURE_BOOT_BEFORE_LOCK 1
|
#define PICOKEYS_REQUIRE_SECURE_BOOT_BEFORE_LOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool otp_is_secure_boot_enabled(uint8_t *bootkey) {
|
bool otp_is_secure_boot_enabled(uint8_t *bootkey) {
|
||||||
@@ -352,7 +350,7 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
|||||||
#ifdef PICO_RP2350
|
#ifdef PICO_RP2350
|
||||||
alignas(2) uint8_t BOOTKEY[] = "\xe1\xd1\x6b\xa7\x64\xab\xd7\x12\xd4\xef\x6e\x3e\xdd\x74\x4e\xd5\x63\x8c\x26\xb\x77\x1c\xf9\x81\x51\x11\xb\xaf\xac\x9b\xc8\x71";
|
alignas(2) uint8_t BOOTKEY[] = "\xe1\xd1\x6b\xa7\x64\xab\xd7\x12\xd4\xef\x6e\x3e\xdd\x74\x4e\xd5\x63\x8c\x26\xb\x77\x1c\xf9\x81\x51\x11\xb\xaf\xac\x9b\xc8\x71";
|
||||||
if (is_empty_otp_buffer(OTP_DATA_BOOTKEY0_0_ROW + 0x10*bootkey, 32)) {
|
if (is_empty_otp_buffer(OTP_DATA_BOOTKEY0_0_ROW + 0x10*bootkey, 32)) {
|
||||||
PICOKEY_CHECK(otp_write_data(OTP_DATA_BOOTKEY0_0_ROW + 0x10*bootkey, BOOTKEY, sizeof(BOOTKEY)));
|
PICOKEYS_CHECK(otp_write_data(OTP_DATA_BOOTKEY0_0_ROW + 0x10*bootkey, BOOTKEY, sizeof(BOOTKEY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *boot_flags1 = otp_buffer_raw(OTP_DATA_BOOT_FLAGS1_ROW);
|
const uint8_t *boot_flags1 = otp_buffer_raw(OTP_DATA_BOOT_FLAGS1_ROW);
|
||||||
@@ -361,9 +359,9 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
|||||||
flagsb1[1] |= ((OTP_DATA_BOOT_FLAGS1_KEY_INVALID_BITS >> OTP_DATA_BOOT_FLAGS1_KEY_INVALID_LSB) & (~(1 << bootkey)));
|
flagsb1[1] |= ((OTP_DATA_BOOT_FLAGS1_KEY_INVALID_BITS >> OTP_DATA_BOOT_FLAGS1_KEY_INVALID_LSB) & (~(1 << bootkey)));
|
||||||
}
|
}
|
||||||
|
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_ROW, flagsb1, sizeof(flagsb1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_ROW, flagsb1, sizeof(flagsb1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_R1_ROW, flagsb1, sizeof(flagsb1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_R1_ROW, flagsb1, sizeof(flagsb1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_R2_ROW, flagsb1, sizeof(flagsb1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_R2_ROW, flagsb1, sizeof(flagsb1)));
|
||||||
|
|
||||||
const uint8_t *crit1 = otp_buffer_raw(OTP_DATA_CRIT1_ROW);
|
const uint8_t *crit1 = otp_buffer_raw(OTP_DATA_CRIT1_ROW);
|
||||||
alignas(4) uint8_t flagsc1[] = { crit1[0] | (1 << OTP_DATA_CRIT1_SECURE_BOOT_ENABLE_LSB), crit1[1], crit1[2], 0x00 };
|
alignas(4) uint8_t flagsc1[] = { crit1[0] | (1 << OTP_DATA_CRIT1_SECURE_BOOT_ENABLE_LSB), crit1[1], crit1[2], 0x00 };
|
||||||
@@ -372,31 +370,31 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
|||||||
flagsc1[0] |= (1 << OTP_DATA_CRIT1_GLITCH_DETECTOR_ENABLE_LSB);
|
flagsc1[0] |= (1 << OTP_DATA_CRIT1_GLITCH_DETECTOR_ENABLE_LSB);
|
||||||
flagsc1[0] |= (3 << OTP_DATA_CRIT1_GLITCH_DETECTOR_SENS_LSB);
|
flagsc1[0] |= (3 << OTP_DATA_CRIT1_GLITCH_DETECTOR_SENS_LSB);
|
||||||
}
|
}
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R1_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R1_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R2_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R2_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R3_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R3_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R4_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R4_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R5_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R5_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R6_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R6_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R7_ROW, flagsc1, sizeof(flagsc1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R7_ROW, flagsc1, sizeof(flagsc1)));
|
||||||
|
|
||||||
if (secure_lock) {
|
if (secure_lock) {
|
||||||
const uint8_t *page1 = otp_buffer_raw(OTP_DATA_PAGE1_LOCK1_ROW);
|
const uint8_t *page1 = otp_buffer_raw(OTP_DATA_PAGE1_LOCK1_ROW);
|
||||||
uint8_t page1v = page1[0] | (OTP_DATA_PAGE1_LOCK1_LOCK_BL_VALUE_READ_ONLY << OTP_DATA_PAGE1_LOCK1_LOCK_BL_LSB);
|
uint8_t page1v = page1[0] | (OTP_DATA_PAGE1_LOCK1_LOCK_BL_VALUE_READ_ONLY << OTP_DATA_PAGE1_LOCK1_LOCK_BL_LSB);
|
||||||
alignas(4) uint8_t flagsp1[] = { page1v, page1v, page1v, 0x00 };
|
alignas(4) uint8_t flagsp1[] = { page1v, page1v, page1v, 0x00 };
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_PAGE1_LOCK1_ROW, flagsp1, sizeof(flagsp1)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_PAGE1_LOCK1_ROW, flagsp1, sizeof(flagsp1)));
|
||||||
const uint8_t *page2 = otp_buffer_raw(OTP_DATA_PAGE2_LOCK1_ROW);
|
const uint8_t *page2 = otp_buffer_raw(OTP_DATA_PAGE2_LOCK1_ROW);
|
||||||
uint8_t page2v = page2[0] | (OTP_DATA_PAGE2_LOCK1_LOCK_BL_VALUE_READ_ONLY << OTP_DATA_PAGE2_LOCK1_LOCK_BL_LSB);
|
uint8_t page2v = page2[0] | (OTP_DATA_PAGE2_LOCK1_LOCK_BL_VALUE_READ_ONLY << OTP_DATA_PAGE2_LOCK1_LOCK_BL_LSB);
|
||||||
alignas(4) uint8_t flagsp2[] = { page2v, page2v, page2v, 0x00 };
|
alignas(4) uint8_t flagsp2[] = { page2v, page2v, page2v, 0x00 };
|
||||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_PAGE2_LOCK1_ROW, flagsp2, sizeof(flagsp2)));
|
PICOKEYS_CHECK(otp_write_data_raw(OTP_DATA_PAGE2_LOCK1_ROW, flagsp2, sizeof(flagsp2)));
|
||||||
}
|
}
|
||||||
#elif defined(ESP_PLATFORM)
|
#elif defined(ESP_PLATFORM)
|
||||||
if (bootkey > 2) {
|
if (bootkey > 2) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secure_lock && PICO_KEYS_REQUIRE_SECURE_BOOT_BEFORE_LOCK) {
|
if (secure_lock && PICOKEYS_REQUIRE_SECURE_BOOT_BEFORE_LOCK) {
|
||||||
if (!esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_EN)) {
|
if (!esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_EN)) {
|
||||||
printf("Secure lock requires SECURE_BOOT_EN already set. Enable secure boot first.\n");
|
printf("Secure lock requires SECURE_BOOT_EN already set. Enable secure boot first.\n");
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
@@ -461,10 +459,10 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
|||||||
#endif // PICO_RP2350
|
#endif // PICO_RP2350
|
||||||
goto err;
|
goto err;
|
||||||
err:
|
err:
|
||||||
if (ret != PICOKEY_OK) {
|
if (ret != PICOKEYS_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PICO_RP2350
|
#ifdef PICO_RP2350
|
||||||
|
|||||||
25
src/fs/phy.c
25
src/fs/phy.c
@@ -15,8 +15,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
#include "file.h"
|
|
||||||
#include "otp.h"
|
#include "otp.h"
|
||||||
|
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
@@ -25,7 +24,7 @@ phy_data_t phy_data;
|
|||||||
|
|
||||||
int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
||||||
if (!phy || !data || !len) {
|
if (!phy || !data || !len) {
|
||||||
return PICOKEY_ERR_NULL_PARAM;
|
return PICOKEYS_ERR_NULL_PARAM;
|
||||||
}
|
}
|
||||||
uint8_t *p = data;
|
uint8_t *p = data;
|
||||||
if (phy->vidpid_present) {
|
if (phy->vidpid_present) {
|
||||||
@@ -48,7 +47,7 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
|||||||
}
|
}
|
||||||
*p++ = PHY_OPTS;
|
*p++ = PHY_OPTS;
|
||||||
*p++ = 2;
|
*p++ = 2;
|
||||||
p += put_uint16_t_be(phy->opts, p);
|
p += put_uint16_be(phy->opts, p);
|
||||||
if (phy->up_btn_present) {
|
if (phy->up_btn_present) {
|
||||||
*p++ = PHY_UP_BTN;
|
*p++ = PHY_UP_BTN;
|
||||||
*p++ = 1;
|
*p++ = 1;
|
||||||
@@ -64,7 +63,7 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
|||||||
if (phy->enabled_curves_present) {
|
if (phy->enabled_curves_present) {
|
||||||
*p++ = PHY_ENABLED_CURVES;
|
*p++ = PHY_ENABLED_CURVES;
|
||||||
*p++ = 4;
|
*p++ = 4;
|
||||||
p += put_uint32_t_be(phy->enabled_curves, p);
|
p += put_uint32_be(phy->enabled_curves, p);
|
||||||
}
|
}
|
||||||
if (phy->enabled_usb_itf_present) {
|
if (phy->enabled_usb_itf_present) {
|
||||||
*p++ = PHY_ENABLED_USB_ITF;
|
*p++ = PHY_ENABLED_USB_ITF;
|
||||||
@@ -78,12 +77,12 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*len = (uint8_t)(p - data);
|
*len = (uint8_t)(p - data);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
||||||
if (!phy || !data || !len) {
|
if (!phy || !data || !len) {
|
||||||
return PICOKEY_ERR_NULL_PARAM;
|
return PICOKEYS_ERR_NULL_PARAM;
|
||||||
}
|
}
|
||||||
const uint8_t *p = data;
|
const uint8_t *p = data;
|
||||||
uint8_t tag, tlen;
|
uint8_t tag, tlen;
|
||||||
@@ -115,7 +114,7 @@ int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
|||||||
break;
|
break;
|
||||||
case PHY_OPTS:
|
case PHY_OPTS:
|
||||||
if (tlen == 2) {
|
if (tlen == 2) {
|
||||||
phy->opts = get_uint16_t_be(p);
|
phy->opts = get_uint16_be(p);
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -135,7 +134,7 @@ int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
|||||||
break;
|
break;
|
||||||
case PHY_ENABLED_CURVES:
|
case PHY_ENABLED_CURVES:
|
||||||
if (tlen == 4) {
|
if (tlen == 4) {
|
||||||
phy->enabled_curves = get_uint32_t_be(p);
|
phy->enabled_curves = get_uint32_be(p);
|
||||||
p += 4;
|
p += 4;
|
||||||
phy->enabled_curves_present = true;
|
phy->enabled_curves_present = true;
|
||||||
}
|
}
|
||||||
@@ -162,7 +161,7 @@ int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
|||||||
phy_data.enabled_usb_itf = PHY_USB_ITF_ALL;
|
phy_data.enabled_usb_itf = PHY_USB_ITF_ALL;
|
||||||
phy_data.enabled_usb_itf_present = true;
|
phy_data.enabled_usb_itf_present = true;
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int phy_init(void) {
|
int phy_init(void) {
|
||||||
@@ -174,18 +173,18 @@ int phy_save(void) {
|
|||||||
uint8_t tmp[PHY_MAX_SIZE] = {0};
|
uint8_t tmp[PHY_MAX_SIZE] = {0};
|
||||||
uint16_t tmp_len = 0;
|
uint16_t tmp_len = 0;
|
||||||
int ret = phy_serialize_data(&phy_data, tmp, &tmp_len);
|
int ret = phy_serialize_data(&phy_data, tmp, &tmp_len);
|
||||||
if (ret != PICOKEY_OK) {
|
if (ret != PICOKEYS_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
file_put_data(ef_phy, tmp, tmp_len);
|
file_put_data(ef_phy, tmp, tmp_len);
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int phy_load(void) {
|
int phy_load(void) {
|
||||||
if (file_has_data(ef_phy)) {
|
if (file_has_data(ef_phy)) {
|
||||||
return phy_unserialize_data(file_get_data(ef_phy), file_get_size(ef_phy), &phy_data);
|
return phy_unserialize_data(file_get_data(ef_phy), file_get_size(ef_phy), &phy_data);
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,14 +15,13 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "picokeys.h"
|
||||||
#include <stdlib.h>
|
#include "led/led.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
#include "bsp/board.h"
|
#include "bsp/board.h"
|
||||||
#elif defined(ESP_PLATFORM)
|
#elif defined(ESP_PLATFORM)
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_compat.h"
|
#include "compat/esp_compat.h"
|
||||||
#elif defined(ENABLE_EMULATION)
|
#elif defined(ENABLE_EMULATION)
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,7 +15,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CYW43_WL_GPIO_LED_PIN
|
#ifdef CYW43_WL_GPIO_LED_PIN
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,12 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#endif
|
||||||
#ifdef PICO_DEFAULT_LED_PIN
|
#ifdef PICO_DEFAULT_LED_PIN
|
||||||
static uint8_t gpio = PICO_DEFAULT_LED_PIN;
|
static uint8_t gpio = PICO_DEFAULT_LED_PIN;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -15,9 +15,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
|
#include "hardware/gpio.h"
|
||||||
#ifdef PICO_DEFAULT_LED_PIN
|
#ifdef PICO_DEFAULT_LED_PIN
|
||||||
static uint8_t gpio = PICO_DEFAULT_LED_PIN;
|
static uint8_t gpio = PICO_DEFAULT_LED_PIN;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
|
|||||||
241
src/main.c
241
src/main.c
@@ -15,10 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "picokeys.h"
|
||||||
#include <stdlib.h>
|
#include "button.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
|
|
||||||
#if !defined(ENABLE_EMULATION)
|
#if !defined(ENABLE_EMULATION)
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -28,22 +26,20 @@
|
|||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "rom/gpio.h"
|
#include "rom/gpio.h"
|
||||||
#include "tinyusb.h"
|
#include "tinyusb.h"
|
||||||
#include "esp_efuse.h"
|
|
||||||
#define BOOT_PIN GPIO_NUM_0
|
|
||||||
#elif defined(PICO_PLATFORM)
|
#elif defined(PICO_PLATFORM)
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "bsp/board.h"
|
#include "bsp/board.h"
|
||||||
#include "pico/aon_timer.h"
|
|
||||||
#include "hardware/gpio.h"
|
|
||||||
#include "hardware/sync.h"
|
|
||||||
#include "hardware/structs/ioqspi.h"
|
#include "hardware/structs/ioqspi.h"
|
||||||
#include "hardware/structs/sio.h"
|
#include "pico/stdio.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "hwrng.h"
|
#include "hwrng.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "flash.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
#include "pico_time.h"
|
||||||
|
#include "serial.h"
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
|
|
||||||
extern void init_otp_files(void);
|
extern void init_otp_files(void);
|
||||||
@@ -80,208 +76,34 @@ int register_app(int (*select_aid)(app_t *, uint8_t), const uint8_t *aid) {
|
|||||||
int select_app(const uint8_t *aid, size_t aid_len) {
|
int select_app(const uint8_t *aid, size_t aid_len) {
|
||||||
if (current_app && current_app->aid && (current_app->aid + 1 == aid || (aid_len >= current_app->aid[0] && !memcmp(current_app->aid + 1, aid, current_app->aid[0])))) {
|
if (current_app && current_app->aid && (current_app->aid + 1 == aid || (aid_len >= current_app->aid[0] && !memcmp(current_app->aid + 1, aid, current_app->aid[0])))) {
|
||||||
current_app->select_aid(current_app, 0);
|
current_app->select_aid(current_app, 0);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
for (int a = 0; a < num_apps; a++) {
|
for (int a = 0; a < num_apps; a++) {
|
||||||
if (aid_len >= apps[a].aid[0] && !memcmp(apps[a].aid + 1, aid, apps[a].aid[0])) {
|
if (aid_len >= apps[a].aid[0] && !memcmp(apps[a].aid + 1, aid, apps[a].aid[0])) {
|
||||||
if (current_app) {
|
if (current_app) {
|
||||||
if (current_app->aid && aid_len >= current_app->aid[0] && !memcmp(current_app->aid + 1, aid, current_app->aid[0])) {
|
if (current_app->aid && aid_len >= current_app->aid[0] && !memcmp(current_app->aid + 1, aid, current_app->aid[0])) {
|
||||||
current_app->select_aid(current_app, 1);
|
current_app->select_aid(current_app, 1);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
if (current_app->unload) {
|
if (current_app->unload) {
|
||||||
current_app->unload();
|
current_app->unload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_app = &apps[a];
|
current_app = &apps[a];
|
||||||
if (current_app->select_aid(current_app, 1) == PICOKEY_OK) {
|
if (current_app->select_aid(current_app, 1) == PICOKEYS_OK) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
int (*button_pressed_cb)(uint8_t) = NULL;
|
|
||||||
|
|
||||||
static void execute_tasks(void);
|
|
||||||
|
|
||||||
static bool req_button_pending = false;
|
|
||||||
|
|
||||||
bool is_req_button_pending(void) {
|
|
||||||
return req_button_pending;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cancel_button = false;
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <windows.h>
|
|
||||||
struct timezone
|
|
||||||
{
|
|
||||||
__int32 tz_minuteswest; /* minutes W of Greenwich */
|
|
||||||
bool tz_dsttime; /* type of dst correction */
|
|
||||||
};
|
|
||||||
int gettimeofday(struct timeval* tp, struct timezone* tzp)
|
|
||||||
{
|
|
||||||
(void)tzp;
|
|
||||||
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
|
|
||||||
// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
|
|
||||||
// until 00:00:00 January 1, 1970
|
|
||||||
static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
|
|
||||||
|
|
||||||
SYSTEMTIME system_time;
|
|
||||||
FILETIME file_time;
|
|
||||||
uint64_t time;
|
|
||||||
|
|
||||||
GetSystemTime(&system_time);
|
|
||||||
SystemTimeToFileTime(&system_time, &file_time);
|
|
||||||
time = ((uint64_t)file_time.dwLowDateTime);
|
|
||||||
time += ((uint64_t)file_time.dwHighDateTime) << 32;
|
|
||||||
|
|
||||||
tp->tv_sec = (long)((time - EPOCH) / 10000000L);
|
|
||||||
tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !defined(ENABLE_EMULATION)
|
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
static bool picok_board_button_read(void) {
|
|
||||||
int boot_state = gpio_get_level(BOOT_PIN);
|
|
||||||
return boot_state == 0;
|
|
||||||
}
|
|
||||||
#elif defined(PICO_PLATFORM)
|
|
||||||
static bool __no_inline_not_in_flash_func(picok_get_bootsel_button)(void) {
|
|
||||||
const uint CS_PIN_INDEX = 1;
|
|
||||||
|
|
||||||
// Must disable interrupts, as interrupt handlers may be in flash, and we
|
|
||||||
// are about to temporarily disable flash access!
|
|
||||||
uint32_t flags = save_and_disable_interrupts();
|
|
||||||
|
|
||||||
// Set chip select to Hi-Z
|
|
||||||
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
|
||||||
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
|
||||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
|
||||||
|
|
||||||
// Note we can't call into any sleep functions in flash right now
|
|
||||||
for (volatile int i = 0; i < 1000; ++i);
|
|
||||||
|
|
||||||
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
|
|
||||||
// Note the button pulls the pin *low* when pressed.
|
|
||||||
#ifdef PICO_RP2040
|
|
||||||
#define CS_BIT (1u << 1)
|
|
||||||
#else
|
|
||||||
#define CS_BIT SIO_GPIO_HI_IN_QSPI_CSN_BITS
|
|
||||||
#endif
|
|
||||||
bool button_state = !(sio_hw->gpio_hi_in & CS_BIT);
|
|
||||||
|
|
||||||
// Need to restore the state of chip select, else we are going to have a
|
|
||||||
// bad time when we return to code in flash!
|
|
||||||
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
|
||||||
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
|
||||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
|
||||||
|
|
||||||
restore_interrupts(flags);
|
|
||||||
|
|
||||||
return button_state;
|
|
||||||
}
|
|
||||||
static bool picok_board_button_read(void) {
|
|
||||||
return picok_get_bootsel_button();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static bool picok_board_button_read(void) {
|
|
||||||
return true; // always unpressed
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bool button_pressed_state = false;
|
|
||||||
uint32_t button_pressed_time = 0;
|
|
||||||
uint8_t button_press = 0;
|
|
||||||
bool wait_button(void) {
|
|
||||||
/* Disabled by default. As LED may not be properly configured,
|
|
||||||
it will not be possible to indicate button press unless it
|
|
||||||
is commissioned. */
|
|
||||||
uint32_t button_timeout = 0;
|
|
||||||
if (phy_data.up_btn_present) {
|
|
||||||
button_timeout = phy_data.up_btn * 1000;
|
|
||||||
}
|
|
||||||
if (button_timeout == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
execute_tasks();
|
|
||||||
//sleep_ms(10);
|
|
||||||
if (start_button + button_timeout < board_millis()) { /* timeout */
|
|
||||||
timeout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!timeout) {
|
|
||||||
while (picok_board_button_read() == true && cancel_button == false) {
|
|
||||||
execute_tasks();
|
|
||||||
//sleep_ms(10);
|
|
||||||
if (start_button + 15000 < board_millis()) { /* timeout */
|
|
||||||
timeout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
led_set_mode(led_mode);
|
|
||||||
req_button_pending = false;
|
|
||||||
return timeout || cancel_button;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int picokey_init(void) {
|
__attribute__((weak)) int picokey_init(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
void execute_tasks(void) {
|
||||||
|
|
||||||
bool set_rtc = false;
|
|
||||||
|
|
||||||
bool has_set_rtc(void) {
|
|
||||||
return set_rtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_rtc_time(time_t t) {
|
|
||||||
#ifdef PICO_PLATFORM
|
|
||||||
struct timespec tv = {.tv_sec = t, .tv_nsec = 0};
|
|
||||||
aon_timer_set_time(&tv);
|
|
||||||
#else
|
|
||||||
struct timeval tv = {.tv_sec = t, .tv_usec = 0};
|
|
||||||
settimeofday(&tv, NULL);
|
|
||||||
#endif
|
|
||||||
set_rtc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t get_rtc_time(void) {
|
|
||||||
#ifdef PICO_PLATFORM
|
|
||||||
struct timespec tv;
|
|
||||||
aon_timer_get_time(&tv);
|
|
||||||
return tv.tv_sec;
|
|
||||||
#else
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
return tv.tv_sec;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
struct apdu apdu;
|
|
||||||
|
|
||||||
static void init_rtc(void) {
|
|
||||||
#ifdef PICO_PLATFORM
|
|
||||||
struct timespec tv = {0};
|
|
||||||
tv.tv_sec = 1577836800; // 2020-01-01
|
|
||||||
aon_timer_start(&tv);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void execute_tasks(void)
|
|
||||||
{
|
|
||||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||||
tud_task(); // tinyusb device task
|
tud_task(); // tinyusb device task
|
||||||
#endif
|
#endif
|
||||||
@@ -300,54 +122,23 @@ static void core0_loop(void *arg) {
|
|||||||
while (1) {
|
while (1) {
|
||||||
execute_tasks();
|
execute_tasks();
|
||||||
hwrng_task();
|
hwrng_task();
|
||||||
do_flash();
|
flash_task();
|
||||||
#ifndef ENABLE_EMULATION
|
button_task();
|
||||||
if (button_pressed_cb && board_millis() > 1000 && !is_busy()) { // wait 1 second to boot up
|
|
||||||
bool current_button_state = picok_board_button_read();
|
|
||||||
if (current_button_state != button_pressed_state) {
|
|
||||||
if (current_button_state == false) { // unpressed
|
|
||||||
if (button_pressed_time == 0 || button_pressed_time + 1000 > board_millis()) {
|
|
||||||
button_press++;
|
|
||||||
}
|
|
||||||
button_pressed_time = board_millis();
|
|
||||||
}
|
|
||||||
button_pressed_state = current_button_state;
|
|
||||||
}
|
|
||||||
if (button_pressed_time > 0 && button_press > 0 && button_pressed_time + 1000 < board_millis() && button_pressed_state == false) {
|
|
||||||
if (button_pressed_cb != NULL) {
|
|
||||||
(*button_pressed_cb)(button_press);
|
|
||||||
}
|
|
||||||
button_pressed_time = button_press = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char pico_serial_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1];
|
|
||||||
uint8_t pico_serial_hash[32];
|
|
||||||
pico_unique_board_id_t pico_serial;
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#define pico_get_unique_board_id(a) do { uint32_t value; esp_efuse_read_block(EFUSE_BLK1, &value, 0, 32); memcpy((uint8_t *)(a), &value, sizeof(uint32_t)); esp_efuse_read_block(EFUSE_BLK1, &value, 32, 32); memcpy((uint8_t *)(a)+4, &value, sizeof(uint32_t)); } while(0)
|
|
||||||
extern tinyusb_config_t tusb_cfg;
|
extern tinyusb_config_t tusb_cfg;
|
||||||
extern const uint8_t desc_config[];
|
extern const uint8_t desc_config[];
|
||||||
TaskHandle_t hcore0 = NULL, hcore1 = NULL;
|
TaskHandle_t hcore0 = NULL, hcore1 = NULL;
|
||||||
int app_main(void) {
|
int app_main(void) {
|
||||||
#else
|
#else
|
||||||
#ifndef PICO_PLATFORM
|
|
||||||
#define pico_get_unique_board_id(a) memset(a, 0, sizeof(*(a)))
|
|
||||||
#endif
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
#endif
|
#endif
|
||||||
pico_get_unique_board_id(&pico_serial);
|
serial_init();
|
||||||
memset(pico_serial_str, 0, sizeof(pico_serial_str));
|
|
||||||
for (size_t i = 0; i < sizeof(pico_serial); i++) {
|
|
||||||
snprintf(&pico_serial_str[2 * i], 3, "%02X", pico_serial.id[i]);
|
|
||||||
}
|
|
||||||
mbedtls_sha256(pico_serial.id, sizeof(pico_serial.id), pico_serial_hash, false);
|
|
||||||
|
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
|
|||||||
261
src/pico_keys.h
261
src/pico_keys.h
@@ -1,261 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
|
||||||
* Copyright (c) 2022 Pol Henarejos.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_KEYS_H_
|
|
||||||
#define _PICO_KEYS_H_
|
|
||||||
|
|
||||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
|
||||||
|
|
||||||
#if defined(PICO_RP2040) || defined(PICO_RP2350)
|
|
||||||
#define PICO_PLATFORM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "file.h"
|
|
||||||
#include "led/led.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#if !defined(MIN)
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
|
||||||
#else
|
|
||||||
#define MIN(a, b) \
|
|
||||||
({ __typeof__ (a) _a = (a); \
|
|
||||||
__typeof__ (b) _b = (b); \
|
|
||||||
_a < _b ? _a : _b; })
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if !defined(MAX)
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
|
||||||
#else
|
|
||||||
#define MAX(a, b) \
|
|
||||||
({ __typeof__ (a) _a = (a); \
|
|
||||||
__typeof__ (b) _b = (b); \
|
|
||||||
_a > _b ? _a : _b; })
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if defined(PICO_PLATFORM)
|
|
||||||
#include "pico/unique_id.h"
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
#if defined(ENABLE_EMULATION)
|
|
||||||
#include <stdbool.h>
|
|
||||||
#elif defined(ESP_PLATFORM)
|
|
||||||
#include "esp_compat.h"
|
|
||||||
#elif defined(PICO_PLATFORM)
|
|
||||||
#include "pico/util/queue.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PICO_PLATFORM
|
|
||||||
#include "pico/bootrom.h"
|
|
||||||
#include "hardware/watchdog.h"
|
|
||||||
#include "pico/aon_timer.h"
|
|
||||||
#else
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern bool wait_button(void);
|
|
||||||
extern int picokey_init(void);
|
|
||||||
|
|
||||||
extern void low_flash_init_core1(void);
|
|
||||||
|
|
||||||
static inline uint16_t make_uint16_t_be(uint8_t b1, uint8_t b2) {
|
|
||||||
return (b1 << 8) | b2;
|
|
||||||
}
|
|
||||||
static inline uint16_t make_uint16_t_le(uint8_t b1, uint8_t b2) {
|
|
||||||
return (b2 << 8) | b1;
|
|
||||||
}
|
|
||||||
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 uint8_t put_uint16_t_be(uint16_t n, uint8_t *b) {
|
|
||||||
*b++ = (n >> 8) & 0xff;
|
|
||||||
*b = n & 0xff;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
static inline uint8_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(void);
|
|
||||||
extern int flash_clear_file(file_t *file);
|
|
||||||
|
|
||||||
extern int (*button_pressed_cb)(uint8_t);
|
|
||||||
|
|
||||||
extern bool is_req_button_pending(void);
|
|
||||||
|
|
||||||
#define SW_BYTES_REMAINING_00() set_res_sw(0x61, 0x00)
|
|
||||||
#define SW_WARNING_STATE_UNCHANGED() set_res_sw(0x62, 0x00)
|
|
||||||
#define SW_WARNING_CORRUPTED() set_res_sw(0x62, 0x81)
|
|
||||||
#define SW_WARNING_EOF() set_res_sw(0x62, 0x82)
|
|
||||||
#define SW_WARNING_EF_DEACTIVATED() set_res_sw(0x62, 0x83)
|
|
||||||
#define SW_WARNING_WRONG_FCI() set_res_sw(0x62, 0x84)
|
|
||||||
#define SW_WARNING_EF_TERMINATED() set_res_sw(0x62, 0x85)
|
|
||||||
|
|
||||||
#define SW_WARNING_NOINFO() set_res_sw(0x63, 0x00)
|
|
||||||
#define SW_WARNING_FILLUP() set_res_sw(0x63, 0x81)
|
|
||||||
|
|
||||||
#define SW_EXEC_ERROR() set_res_sw(0x64, 0x00)
|
|
||||||
|
|
||||||
#define SW_MEMORY_FAILURE() set_res_sw(0x65, 0x81)
|
|
||||||
|
|
||||||
#define SW_SECURE_MESSAGE_EXEC_ERROR() set_res_sw(0x66, 0x00)
|
|
||||||
|
|
||||||
#define SW_WRONG_LENGTH() set_res_sw(0x67, 0x00)
|
|
||||||
#define SW_WRONG_DATA() set_res_sw(0x67, 0x00)
|
|
||||||
|
|
||||||
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED() set_res_sw(0x68, 0x81)
|
|
||||||
#define SW_SECURE_MESSAGING_NOT_SUPPORTED() set_res_sw(0x68, 0x82)
|
|
||||||
|
|
||||||
#define SW_COMMAND_INCOMPATIBLE() set_res_sw(0x69, 0x81)
|
|
||||||
#define SW_SECURITY_STATUS_NOT_SATISFIED() set_res_sw(0x69, 0x82)
|
|
||||||
#define SW_PIN_BLOCKED() set_res_sw(0x69, 0x83)
|
|
||||||
#define SW_DATA_INVALID() set_res_sw(0x69, 0x84)
|
|
||||||
#define SW_CONDITIONS_NOT_SATISFIED() set_res_sw(0x69, 0x85)
|
|
||||||
#define SW_COMMAND_NOT_ALLOWED() set_res_sw(0x69, 0x86)
|
|
||||||
#define SW_SECURE_MESSAGING_MISSING_DO() set_res_sw(0x69, 0x87)
|
|
||||||
#define SW_SECURE_MESSAGING_INCORRECT_DO() set_res_sw(0x69, 0x88)
|
|
||||||
#define SW_APPLET_SELECT_FAILED() set_res_sw(0x69, 0x99)
|
|
||||||
|
|
||||||
#define SW_INCORRECT_PARAMS() set_res_sw(0x6A, 0x80)
|
|
||||||
#define SW_FUNC_NOT_SUPPORTED() set_res_sw(0x6A, 0x81)
|
|
||||||
#define SW_FILE_NOT_FOUND() set_res_sw(0x6A, 0x82)
|
|
||||||
#define SW_RECORD_NOT_FOUND() set_res_sw(0x6A, 0x83)
|
|
||||||
#define SW_FILE_FULL() set_res_sw(0x6A, 0x84)
|
|
||||||
#define SW_WRONG_NE() set_res_sw(0x6A, 0x85)
|
|
||||||
#define SW_INCORRECT_P1P2() set_res_sw(0x6A, 0x86)
|
|
||||||
#define SW_WRONG_NC() set_res_sw(0x6A, 0x87)
|
|
||||||
#define SW_REFERENCE_NOT_FOUND() set_res_sw(0x6A, 0x88)
|
|
||||||
#define SW_FILE_EXISTS() set_res_sw(0x6A, 0x89)
|
|
||||||
|
|
||||||
#define SW_WRONG_P1P2() set_res_sw(0x6B, 0x00)
|
|
||||||
|
|
||||||
#define SW_CORRECT_LENGTH_00() set_res_sw(0x6C, 0x00)
|
|
||||||
|
|
||||||
#define SW_INS_NOT_SUPPORTED() set_res_sw(0x6D, 0x00)
|
|
||||||
|
|
||||||
#define SW_CLA_NOT_SUPPORTED() set_res_sw(0x6E, 0x00)
|
|
||||||
|
|
||||||
#define SW_UNKNOWN() set_res_sw(0x6F, 0x00)
|
|
||||||
|
|
||||||
#define SW_OK() set_res_sw(0x90, 0x00)
|
|
||||||
|
|
||||||
#define PICOKEY_OK 0
|
|
||||||
#define PICOKEY_ERR_NO_MEMORY -1000
|
|
||||||
#define PICOKEY_ERR_MEMORY_FATAL -1001
|
|
||||||
#define PICOKEY_ERR_NULL_PARAM -1002
|
|
||||||
#define PICOKEY_ERR_FILE_NOT_FOUND -1003
|
|
||||||
#define PICOKEY_ERR_BLOCKED -1004
|
|
||||||
#define PICOKEY_NO_LOGIN -1005
|
|
||||||
#define PICOKEY_EXEC_ERROR -1006
|
|
||||||
#define PICOKEY_WRONG_LENGTH -1007
|
|
||||||
#define PICOKEY_WRONG_DATA -1008
|
|
||||||
#define PICOKEY_WRONG_DKEK -1009
|
|
||||||
#define PICOKEY_WRONG_SIGNATURE -1010
|
|
||||||
#define PICOKEY_WRONG_PADDING -1011
|
|
||||||
#define PICOKEY_VERIFICATION_FAILED -1012
|
|
||||||
|
|
||||||
#define PICOKEY_CHECK(x) do { ret = (x); if (ret != PICOKEY_OK) goto err; } while (0)
|
|
||||||
|
|
||||||
#if !defined (PICO_PLATFORM)
|
|
||||||
#define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8
|
|
||||||
typedef struct { uint8_t id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES]; } pico_unique_board_id_t;
|
|
||||||
#endif
|
|
||||||
extern pico_unique_board_id_t pico_serial;
|
|
||||||
extern char pico_serial_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1];
|
|
||||||
extern uint8_t pico_serial_hash[32];
|
|
||||||
|
|
||||||
#if defined(PICO_PLATFORM)
|
|
||||||
#define multicore_launch_func_core1(a) multicore_launch_core1((void (*) (void))a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern bool has_set_rtc(void);
|
|
||||||
extern time_t get_rtc_time(void);
|
|
||||||
extern void set_rtc_time(time_t tv_sec);
|
|
||||||
|
|
||||||
extern int set_atr(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
87
src/pico_time.c
Normal file
87
src/pico_time.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
|
#include "pico_time.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <windows.h>
|
||||||
|
struct timezone
|
||||||
|
{
|
||||||
|
__int32 tz_minuteswest; /* minutes W of Greenwich */
|
||||||
|
bool tz_dsttime; /* type of dst correction */
|
||||||
|
};
|
||||||
|
int gettimeofday(struct timeval* tp, struct timezone* tzp)
|
||||||
|
{
|
||||||
|
(void)tzp;
|
||||||
|
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
|
||||||
|
// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
|
||||||
|
// until 00:00:00 January 1, 1970
|
||||||
|
static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
|
||||||
|
|
||||||
|
SYSTEMTIME system_time;
|
||||||
|
FILETIME file_time;
|
||||||
|
uint64_t time;
|
||||||
|
|
||||||
|
GetSystemTime(&system_time);
|
||||||
|
SystemTimeToFileTime(&system_time, &file_time);
|
||||||
|
time = ((uint64_t)file_time.dwLowDateTime);
|
||||||
|
time += ((uint64_t)file_time.dwHighDateTime) << 32;
|
||||||
|
|
||||||
|
tp->tv_sec = (long)((time - EPOCH) / 10000000L);
|
||||||
|
tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool set_rtc = false;
|
||||||
|
|
||||||
|
bool has_set_rtc(void) {
|
||||||
|
return set_rtc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_rtc_time(time_t t) {
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
struct timespec tv = {.tv_sec = t, .tv_nsec = 0};
|
||||||
|
aon_timer_set_time(&tv);
|
||||||
|
#else
|
||||||
|
struct timeval tv = {.tv_sec = t, .tv_usec = 0};
|
||||||
|
settimeofday(&tv, NULL);
|
||||||
|
#endif
|
||||||
|
set_rtc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t get_rtc_time(void) {
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
struct timespec tv;
|
||||||
|
aon_timer_get_time(&tv);
|
||||||
|
return tv.tv_sec;
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return tv.tv_sec;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_rtc(void) {
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
struct timespec tv = {0};
|
||||||
|
tv.tv_sec = 1577836800; // 2020-01-01
|
||||||
|
aon_timer_start(&tv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
33
src/pico_time.h
Normal file
33
src/pico_time.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIME_H
|
||||||
|
#define TIME_H
|
||||||
|
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
#include "pico/aon_timer.h"
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern bool has_set_rtc(void);
|
||||||
|
extern time_t get_rtc_time(void);
|
||||||
|
extern void set_rtc_time(time_t tv_sec);
|
||||||
|
extern void init_rtc(void);
|
||||||
|
|
||||||
|
#endif // TIME_H
|
||||||
171
src/picokeys.h
Normal file
171
src/picokeys.h
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PICOKEYS_H_
|
||||||
|
#define _PICOKEYS_H_
|
||||||
|
|
||||||
|
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||||
|
|
||||||
|
#if defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#define PICO_PLATFORM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#if !defined(MIN)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#else
|
||||||
|
#define MIN(a, b) \
|
||||||
|
({ __typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a < _b ? _a : _b; })
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if !defined(MAX)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#else
|
||||||
|
#define MAX(a, b) \
|
||||||
|
({ __typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a > _b ? _a : _b; })
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int picokey_init(void);
|
||||||
|
|
||||||
|
extern void low_flash_init_core1(void);
|
||||||
|
|
||||||
|
static inline uint16_t make_uint16_be(uint8_t b1, uint8_t b2) {
|
||||||
|
return (b1 << 8) | b2;
|
||||||
|
}
|
||||||
|
static inline uint16_t make_uint16_le(uint8_t b1, uint8_t b2) {
|
||||||
|
return (b2 << 8) | b1;
|
||||||
|
}
|
||||||
|
static inline uint16_t get_uint16_be(const uint8_t *b) {
|
||||||
|
return make_uint16_be(b[0], b[1]);
|
||||||
|
}
|
||||||
|
static inline uint16_t get_uint16_le(const uint8_t *b) {
|
||||||
|
return make_uint16_le(b[0], b[1]);
|
||||||
|
}
|
||||||
|
static inline uint8_t put_uint16_be(uint16_t n, uint8_t *b) {
|
||||||
|
*b++ = (n >> 8) & 0xff;
|
||||||
|
*b = n & 0xff;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
static inline uint8_t put_uint16_le(uint16_t n, uint8_t *b) {
|
||||||
|
*b++ = n & 0xff;
|
||||||
|
*b = (n >> 8) & 0xff;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t make_uint32_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_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_be(const uint8_t *b) {
|
||||||
|
return make_uint32_be(b[0], b[1], b[2], b[3]);
|
||||||
|
}
|
||||||
|
static inline uint32_t get_uint32_le(const uint8_t *b) {
|
||||||
|
return make_uint32_le(b[0], b[1], b[2], b[3]);
|
||||||
|
}
|
||||||
|
static inline uint32_t put_uint32_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_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_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_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_be(const uint8_t *b) {
|
||||||
|
return make_uint64_be(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
|
||||||
|
}
|
||||||
|
static inline uint64_t get_uint64_le(const uint8_t *b) {
|
||||||
|
return make_uint64_le(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
|
||||||
|
}
|
||||||
|
static inline uint32_t put_uint64_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_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(void);
|
||||||
|
extern int flash_clear_file(file_t *file);
|
||||||
|
|
||||||
|
extern int (*button_pressed_cb)(uint8_t);
|
||||||
|
|
||||||
|
extern bool is_req_button_pending(void);
|
||||||
|
|
||||||
|
#define PICOKEYS_OK 0
|
||||||
|
#define PICOKEYS_ERR_NO_MEMORY -1000
|
||||||
|
#define PICOKEYS_ERR_MEMORY_FATAL -1001
|
||||||
|
#define PICOKEYS_ERR_NULL_PARAM -1002
|
||||||
|
#define PICOKEYS_ERR_FILE_NOT_FOUND -1003
|
||||||
|
#define PICOKEYS_ERR_BLOCKED -1004
|
||||||
|
#define PICOKEYS_NO_LOGIN -1005
|
||||||
|
#define PICOKEYS_EXEC_ERROR -1006
|
||||||
|
#define PICOKEYS_WRONG_LENGTH -1007
|
||||||
|
#define PICOKEYS_WRONG_DATA -1008
|
||||||
|
#define PICOKEYS_WRONG_DKEK -1009
|
||||||
|
#define PICOKEYS_WRONG_SIGNATURE -1010
|
||||||
|
#define PICOKEYS_WRONG_PADDING -1011
|
||||||
|
#define PICOKEYS_VERIFICATION_FAILED -1012
|
||||||
|
|
||||||
|
#define PICOKEYS_CHECK(x) do { ret = (x); if (ret != PICOKEYS_OK) goto err; } while (0)
|
||||||
|
|
||||||
|
extern int set_atr(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -18,9 +18,9 @@
|
|||||||
#ifndef __VERSION_H_
|
#ifndef __VERSION_H_
|
||||||
#define __VERSION_H_
|
#define __VERSION_H_
|
||||||
|
|
||||||
#define PICO_KEYS_SDK_VERSION 0x0806
|
#define PICOKEYS_SDK_VERSION 0x0806
|
||||||
|
|
||||||
#define PICO_KEYS_SDK_VERSION_MAJOR ((PICO_KEYS_SDK_VERSION >> 8) & 0xff)
|
#define PICOKEYS_SDK_VERSION_MAJOR ((PICOKEYS_SDK_VERSION >> 8) & 0xff)
|
||||||
#define PICO_KEYS_SDK_VERSION_MINOR (PICO_KEYS_SDK_VERSION & 0xff)
|
#define PICOKEYS_SDK_VERSION_MINOR (PICOKEYS_SDK_VERSION & 0xff)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
52
src/rescue.c
52
src/rescue.c
@@ -15,9 +15,16 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include "pico_time.h"
|
||||||
|
#ifdef PICO_PLATFORM
|
||||||
|
#include "hardware/watchdog.h"
|
||||||
|
#endif
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "pico_keys_version.h"
|
#include "picokeys_version.h"
|
||||||
#include "otp.h"
|
#include "otp.h"
|
||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
@@ -25,6 +32,7 @@
|
|||||||
#include "crypto_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
extern char __flash_binary_start;
|
extern char __flash_binary_start;
|
||||||
extern char __flash_binary_end;
|
extern char __flash_binary_end;
|
||||||
@@ -70,7 +78,7 @@ static int rescue_select(app_t *a, uint8_t force) {
|
|||||||
if (force) {
|
if (force) {
|
||||||
scan_flash();
|
scan_flash();
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t atr_rescue[] = {
|
const uint8_t atr_rescue[] = {
|
||||||
@@ -90,7 +98,7 @@ INITIALIZER ( rescue_ctor ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int rescue_unload(void) {
|
static int rescue_unload(void) {
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id ec_id) {
|
static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id ec_id) {
|
||||||
@@ -103,7 +111,7 @@ static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id e
|
|||||||
if (file_has_data(ef_devcert_key)) {
|
if (file_has_data(ef_devcert_key)) {
|
||||||
uint8_t pkey[32] = {0};
|
uint8_t pkey[32] = {0};
|
||||||
memcpy(pkey, file_get_data(ef_devcert_key), 32);
|
memcpy(pkey, file_get_data(ef_devcert_key), 32);
|
||||||
aes_decrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32);
|
aes_decrypt(kbase, pico_serial_hash, 32 * 8, PICOKEYS_AES_MODE_CBC, pkey, 32);
|
||||||
int ret = mbedtls_ecp_read_key(ec_id, ecp, pkey, 32);
|
int ret = mbedtls_ecp_read_key(ec_id, ecp, pkey, 32);
|
||||||
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -117,12 +125,12 @@ static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id e
|
|||||||
mbedtls_ecp_gen_key(ec_id, ecp, random_fill_iterator, NULL);
|
mbedtls_ecp_gen_key(ec_id, ecp, random_fill_iterator, NULL);
|
||||||
mbedtls_ecp_write_key_ext(ecp, &olen, pkey, sizeof(pkey));
|
mbedtls_ecp_write_key_ext(ecp, &olen, pkey, sizeof(pkey));
|
||||||
|
|
||||||
aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32);
|
aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICOKEYS_AES_MODE_CBC, pkey, 32);
|
||||||
file_put_data(ef_devcert_key, pkey, (uint16_t)olen);
|
file_put_data(ef_devcert_key, pkey, (uint16_t)olen);
|
||||||
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
}
|
}
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_keydev_sign(void) {
|
static int cmd_keydev_sign(void) {
|
||||||
@@ -136,7 +144,7 @@ static int cmd_keydev_sign(void) {
|
|||||||
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
|
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
|
||||||
if (!otp_key_2) {
|
if (!otp_key_2) {
|
||||||
int ret = load_internal_keydev(&ecp, ec_id);
|
int ret = load_internal_keydev(&ecp, ec_id);
|
||||||
if (ret != PICOKEY_OK) {
|
if (ret != PICOKEYS_OK) {
|
||||||
mbedtls_ecp_keypair_free(&ecp);
|
mbedtls_ecp_keypair_free(&ecp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -177,7 +185,7 @@ static int cmd_keydev_sign(void) {
|
|||||||
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
|
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
|
||||||
if (!otp_key_2) {
|
if (!otp_key_2) {
|
||||||
int ret = load_internal_keydev(&ecp, ec_id);
|
int ret = load_internal_keydev(&ecp, ec_id);
|
||||||
if (ret != PICOKEY_OK) {
|
if (ret != PICOKEYS_OK) {
|
||||||
mbedtls_ecp_keypair_free(&ecp);
|
mbedtls_ecp_keypair_free(&ecp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -242,8 +250,8 @@ static int cmd_write(void) {
|
|||||||
if (p1 == 0x1) { // PHY
|
if (p1 == 0x1) { // PHY
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
int ret = phy_unserialize_data(apdu.data, (uint16_t)apdu.nc, &phy_data);
|
int ret = phy_unserialize_data(apdu.data, (uint16_t)apdu.nc, &phy_data);
|
||||||
if (ret == PICOKEY_OK) {
|
if (ret == PICOKEYS_OK) {
|
||||||
if (phy_save() != PICOKEY_OK) {
|
if (phy_save() != PICOKEYS_OK) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,7 +267,7 @@ static int cmd_write(void) {
|
|||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
}
|
}
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
tm.tm_year = get_uint16_t_be(apdu.data) - 1900;
|
tm.tm_year = get_uint16_be(apdu.data) - 1900;
|
||||||
tm.tm_mon = apdu.data[2];
|
tm.tm_mon = apdu.data[2];
|
||||||
tm.tm_mday = apdu.data[3];
|
tm.tm_mday = apdu.data[3];
|
||||||
tm.tm_wday = apdu.data[4];
|
tm.tm_wday = apdu.data[4];
|
||||||
@@ -291,7 +299,7 @@ static int cmd_read(void) {
|
|||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
uint16_t len = 0;
|
uint16_t len = 0;
|
||||||
int ret = phy_serialize_data(&phy_data, apdu.rdata, &len);
|
int ret = phy_serialize_data(&phy_data, apdu.rdata, &len);
|
||||||
if (ret != PICOKEY_OK) {
|
if (ret != PICOKEYS_OK) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
res_APDU_size = len;
|
res_APDU_size = len;
|
||||||
@@ -300,16 +308,16 @@ static int cmd_read(void) {
|
|||||||
else if (p1 == 0x2) { // FLASH INFO
|
else if (p1 == 0x2) { // FLASH INFO
|
||||||
res_APDU_size = 0;
|
res_APDU_size = 0;
|
||||||
uint32_t free = flash_free_space(), total = flash_total_space(), used = flash_used_space(), nfiles = flash_num_files(), size = flash_size();
|
uint32_t free = flash_free_space(), total = flash_total_space(), used = flash_used_space(), nfiles = flash_num_files(), size = flash_size();
|
||||||
res_APDU_size += put_uint32_t_be(free, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint32_be(free, res_APDU + res_APDU_size);
|
||||||
res_APDU_size += put_uint32_t_be(used, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint32_be(used, res_APDU + res_APDU_size);
|
||||||
res_APDU_size += put_uint32_t_be(total, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint32_be(total, res_APDU + res_APDU_size);
|
||||||
res_APDU_size += put_uint32_t_be(nfiles, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint32_be(nfiles, res_APDU + res_APDU_size);
|
||||||
res_APDU_size += put_uint32_t_be(size, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint32_be(size, res_APDU + res_APDU_size);
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
uintptr_t start = (uintptr_t) &__flash_binary_start;
|
uintptr_t start = (uintptr_t) &__flash_binary_start;
|
||||||
uintptr_t end = (uintptr_t) &__flash_binary_end;
|
uintptr_t end = (uintptr_t) &__flash_binary_end;
|
||||||
uint32_t fw_size = (uint32_t)(end - start);
|
uint32_t fw_size = (uint32_t)(end - start);
|
||||||
res_APDU_size += put_uint32_t_be(fw_size, res_APDU + res_APDU_size);
|
res_APDU_size += put_uint32_be(fw_size, res_APDU + res_APDU_size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (p1 == 0x3) { // OTP SECURE BOOT STATUS
|
else if (p1 == 0x3) { // OTP SECURE BOOT STATUS
|
||||||
@@ -337,7 +345,7 @@ static int cmd_read(void) {
|
|||||||
#endif
|
#endif
|
||||||
if (p2 == 0x1) {
|
if (p2 == 0x1) {
|
||||||
struct tm *tm = localtime(&tv.tv_sec);
|
struct tm *tm = localtime(&tv.tv_sec);
|
||||||
res_APDU_size += put_uint16_t_be(tm->tm_year + 1900, res_APDU);
|
res_APDU_size += put_uint16_be(tm->tm_year + 1900, res_APDU);
|
||||||
res_APDU[res_APDU_size++] = tm->tm_mon;
|
res_APDU[res_APDU_size++] = tm->tm_mon;
|
||||||
res_APDU[res_APDU_size++] = tm->tm_mday;
|
res_APDU[res_APDU_size++] = tm->tm_mday;
|
||||||
res_APDU[res_APDU_size++] = tm->tm_wday;
|
res_APDU[res_APDU_size++] = tm->tm_wday;
|
||||||
@@ -346,7 +354,7 @@ static int cmd_read(void) {
|
|||||||
res_APDU[res_APDU_size++] = tm->tm_sec;
|
res_APDU[res_APDU_size++] = tm->tm_sec;
|
||||||
}
|
}
|
||||||
else if (p2 == 0x2) {
|
else if (p2 == 0x2) {
|
||||||
res_APDU_size += put_uint32_t_be((uint32_t)tv.tv_sec, res_APDU);
|
res_APDU_size += put_uint32_be((uint32_t)tv.tv_sec, res_APDU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
@@ -362,7 +370,7 @@ static int cmd_secure(void) {
|
|||||||
bool secure_lock = P2(apdu) == 0x1;
|
bool secure_lock = P2(apdu) == 0x1;
|
||||||
|
|
||||||
int ret = otp_enable_secure_boot(bootkey, secure_lock);
|
int ret = otp_enable_secure_boot(bootkey, secure_lock);
|
||||||
if (ret != 0) {
|
if (ret != PICOKEYS_OK) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
led_3_blinks();
|
led_3_blinks();
|
||||||
|
|||||||
@@ -15,24 +15,19 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "picokeys.h"
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "hwrng.h"
|
#include "hwrng.h"
|
||||||
|
|
||||||
#if defined(PICO_PLATFORM)
|
#if defined(PICO_PLATFORM)
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "bsp/board.h"
|
#include "bsp/board.h"
|
||||||
#include "pico/rand.h"
|
#include "pico/rand.h"
|
||||||
#elif defined(ESP_PLATFORM)
|
#elif defined(ESP_PLATFORM)
|
||||||
#include "bootloader_random.h"
|
#include "bootloader_random.h"
|
||||||
#include "esp_random.h"
|
#include "esp_random.h"
|
||||||
#include "esp_compat.h"
|
#include "compat/esp_compat.h"
|
||||||
#else
|
#else
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "board.h"
|
#include "compat/board.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void hwrng_start(void) {
|
static void hwrng_start(void) {
|
||||||
|
|||||||
@@ -17,12 +17,7 @@
|
|||||||
|
|
||||||
#define HWRNG_PRE_LOOP 32
|
#define HWRNG_PRE_LOOP 32
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "picokeys.h"
|
||||||
#if defined(PICO_PLATFORM)
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "hwrng.h"
|
#include "hwrng.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
|
|||||||
43
src/serial.c
Normal file
43
src/serial.c
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "mbedtls/sha256.h"
|
||||||
|
#if defined(ESP_PLATFORM)
|
||||||
|
#include "esp_efuse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char pico_serial_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1];
|
||||||
|
uint8_t pico_serial_hash[32];
|
||||||
|
picokey_serial_t pico_serial;
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#define pico_get_unique_board_id(a) do { uint32_t value; esp_efuse_read_block(EFUSE_BLK1, &value, 0, 32); memcpy((uint8_t *)(a), &value, sizeof(uint32_t)); esp_efuse_read_block(EFUSE_BLK1, &value, 32, 32); memcpy((uint8_t *)(a)+4, &value, sizeof(uint32_t)); } while(0)
|
||||||
|
#else
|
||||||
|
#ifndef PICO_PLATFORM
|
||||||
|
#define pico_get_unique_board_id(a) memset(a, 0, sizeof(*(a)))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void serial_init(void) {
|
||||||
|
pico_get_unique_board_id(&pico_serial);
|
||||||
|
memset(pico_serial_str, 0, sizeof(pico_serial_str));
|
||||||
|
for (size_t i = 0; i < sizeof(pico_serial); i++) {
|
||||||
|
snprintf(&pico_serial_str[2 * i], 3, "%02X", pico_serial.id[i]);
|
||||||
|
}
|
||||||
|
mbedtls_sha256(pico_serial.id, sizeof(pico_serial.id), pico_serial_hash, false);
|
||||||
|
}
|
||||||
36
src/serial.h
Normal file
36
src/serial.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SERIAL_H_
|
||||||
|
#define _SERIAL_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if !defined (PICO_PLATFORM)
|
||||||
|
#define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8
|
||||||
|
typedef struct { uint8_t id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES]; } picokey_serial_t;
|
||||||
|
#else
|
||||||
|
#include "pico/unique_id.h"
|
||||||
|
typedef pico_unique_board_id_t picokey_serial_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern picokey_serial_t pico_serial;
|
||||||
|
extern char pico_serial_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1];
|
||||||
|
extern uint8_t pico_serial_hash[32];
|
||||||
|
extern void serial_init(void);
|
||||||
|
|
||||||
|
#endif //_SERIAL_H_
|
||||||
@@ -15,8 +15,9 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
|
#include "led/led.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
#ifdef PICO_PLATFORM
|
#ifdef PICO_PLATFORM
|
||||||
#include "bsp/board.h"
|
#include "bsp/board.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -27,7 +28,6 @@
|
|||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#endif
|
#endif
|
||||||
#include "ccid.h"
|
#include "ccid.h"
|
||||||
#include "usb_descriptors.h"
|
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ static int driver_init_ccid(uint8_t itf) {
|
|||||||
|
|
||||||
//ccid_tx[itf].w_ptr = ccid_tx[itf].r_ptr = 0;
|
//ccid_tx[itf].w_ptr = ccid_tx[itf].r_ptr = 0;
|
||||||
|
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_vendor_rx_cb(uint8_t itf, const uint8_t *buffer, uint16_t bufsize) {
|
void tud_vendor_rx_cb(uint8_t itf, const uint8_t *buffer, uint16_t bufsize) {
|
||||||
@@ -347,10 +347,10 @@ void driver_exec_finished_cont_ccid(uint8_t itf, uint16_t size_next, uint16_t of
|
|||||||
void ccid_task(void) {
|
void ccid_task(void) {
|
||||||
for (int itf = 0; itf < ITF_SC_TOTAL; itf++) {
|
for (int itf = 0; itf < ITF_SC_TOTAL; itf++) {
|
||||||
int status = card_status(sc_itf_to_usb_itf(itf));
|
int status = card_status(sc_itf_to_usb_itf(itf));
|
||||||
if (status == PICOKEY_OK) {
|
if (status == PICOKEYS_OK) {
|
||||||
driver_exec_finished_ccid(itf, finished_data_size);
|
driver_exec_finished_ccid(itf, finished_data_size);
|
||||||
}
|
}
|
||||||
else if (status == PICOKEY_ERR_BLOCKED) {
|
else if (status == PICOKEYS_ERR_BLOCKED) {
|
||||||
driver_exec_timeout_ccid(itf);
|
driver_exec_timeout_ccid(itf);
|
||||||
}
|
}
|
||||||
if (ccid_tx[itf].w_ptr > ccid_tx[itf].r_ptr) {
|
if (ccid_tx[itf].w_ptr > ccid_tx[itf].r_ptr) {
|
||||||
|
|||||||
@@ -40,4 +40,30 @@ enum ccid_state {
|
|||||||
|
|
||||||
extern const uint8_t *ccid_atr;
|
extern const uint8_t *ccid_atr;
|
||||||
|
|
||||||
|
PACK(
|
||||||
|
struct ccid_class_descriptor {
|
||||||
|
uint8_t bLength;
|
||||||
|
uint8_t bDescriptorType;
|
||||||
|
uint16_t bcdCCID;
|
||||||
|
uint8_t bMaxSlotIndex;
|
||||||
|
uint8_t bVoltageSupport;
|
||||||
|
uint32_t dwProtocols;
|
||||||
|
uint32_t dwDefaultClock;
|
||||||
|
uint32_t dwMaximumClock;
|
||||||
|
uint8_t bNumClockSupport;
|
||||||
|
uint32_t dwDataRate;
|
||||||
|
uint32_t dwMaxDataRate;
|
||||||
|
uint8_t bNumDataRatesSupported;
|
||||||
|
uint32_t dwMaxIFSD;
|
||||||
|
uint32_t dwSynchProtocols;
|
||||||
|
uint32_t dwMechanical;
|
||||||
|
uint32_t dwFeatures;
|
||||||
|
uint32_t dwMaxCCIDMessageLength;
|
||||||
|
uint8_t bClassGetResponse;
|
||||||
|
uint8_t bclassEnvelope;
|
||||||
|
uint16_t wLcdLayout;
|
||||||
|
uint8_t bPINSupport;
|
||||||
|
uint8_t bMaxCCIDBusySlots;
|
||||||
|
});
|
||||||
|
|
||||||
#endif //_CCID_H_
|
#endif //_CCID_H_
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "queue.h"
|
#include "compat/queue.h"
|
||||||
#include "board.h"
|
#include "compat/board.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define USB_BUFFER_SIZE 4096
|
#define USB_BUFFER_SIZE 4096
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
|
#include "serial.h"
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#if defined(PICO_PLATFORM)
|
#if defined(PICO_PLATFORM)
|
||||||
@@ -27,7 +28,7 @@ static portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED;
|
|||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#endif
|
#endif
|
||||||
#include "ctap_hid.h"
|
#include "ctap_hid.h"
|
||||||
#include "pico_keys_version.h"
|
#include "picokeys_version.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
@@ -399,8 +400,8 @@ int driver_process_usb_packet_hid(uint16_t read) {
|
|||||||
memcpy(resp->nonce, req->nonce, sizeof(resp->nonce));
|
memcpy(resp->nonce, req->nonce, sizeof(resp->nonce));
|
||||||
resp->cid = 0x01000000;
|
resp->cid = 0x01000000;
|
||||||
resp->versionInterface = CTAPHID_IF_VERSION;
|
resp->versionInterface = CTAPHID_IF_VERSION;
|
||||||
resp->versionMajor = get_version_major ? get_version_major() : PICO_KEYS_SDK_VERSION_MAJOR;
|
resp->versionMajor = get_version_major ? get_version_major() : PICOKEYS_SDK_VERSION_MAJOR;
|
||||||
resp->versionMinor = get_version_minor ? get_version_minor() : PICO_KEYS_SDK_VERSION_MINOR;
|
resp->versionMinor = get_version_minor ? get_version_minor() : PICOKEYS_SDK_VERSION_MINOR;
|
||||||
resp->capFlags = CAPFLAG_WINK | CAPFLAG_CBOR;
|
resp->capFlags = CAPFLAG_WINK | CAPFLAG_CBOR;
|
||||||
|
|
||||||
ctap_resp->cid = ctap_req->cid;
|
ctap_resp->cid = ctap_req->cid;
|
||||||
@@ -467,8 +468,8 @@ int driver_process_usb_packet_hid(uint16_t read) {
|
|||||||
else if (ctap_req->init.cmd == CTAPHID_VERSION) {
|
else if (ctap_req->init.cmd == CTAPHID_VERSION) {
|
||||||
ctap_resp->cid = ctap_req->cid;
|
ctap_resp->cid = ctap_req->cid;
|
||||||
ctap_resp->init.cmd = ctap_req->init.cmd;
|
ctap_resp->init.cmd = ctap_req->init.cmd;
|
||||||
ctap_resp->init.data[0] = PICO_KEYS_SDK_VERSION_MAJOR;
|
ctap_resp->init.data[0] = PICOKEYS_SDK_VERSION_MAJOR;
|
||||||
ctap_resp->init.data[1] = PICO_KEYS_SDK_VERSION_MINOR;
|
ctap_resp->init.data[1] = PICOKEYS_SDK_VERSION_MINOR;
|
||||||
ctap_resp->init.bcntl = 4;
|
ctap_resp->init.bcntl = 4;
|
||||||
driver_write_hid(ITF_HID_CTAP, (const uint8_t *)ctap_resp, 64);
|
driver_write_hid(ITF_HID_CTAP, (const uint8_t *)ctap_resp, 64);
|
||||||
msg_packet.len = msg_packet.current_len = 0;
|
msg_packet.len = msg_packet.current_len = 0;
|
||||||
@@ -577,7 +578,7 @@ void driver_exec_finished_hid(uint16_t size_next) {
|
|||||||
else {
|
else {
|
||||||
if (is_nk) {
|
if (is_nk) {
|
||||||
memmove(apdu.rdata + 2, apdu.rdata, size_next - 2);
|
memmove(apdu.rdata + 2, apdu.rdata, size_next - 2);
|
||||||
put_uint16_t_be(apdu.sw, apdu.rdata);
|
put_uint16_be(apdu.sw, apdu.rdata);
|
||||||
}
|
}
|
||||||
driver_exec_finished_cont_hid(ITF_HID_CTAP, size_next, 7);
|
driver_exec_finished_cont_hid(ITF_HID_CTAP, size_next, 7);
|
||||||
}
|
}
|
||||||
@@ -620,10 +621,10 @@ void hid_task(void) {
|
|||||||
driver_process_usb_nopacket_hid();
|
driver_process_usb_nopacket_hid();
|
||||||
}
|
}
|
||||||
int status = card_status(ITF_HID);
|
int status = card_status(ITF_HID);
|
||||||
if (status == PICOKEY_OK) {
|
if (status == PICOKEYS_OK) {
|
||||||
driver_exec_finished_hid(finished_data_size);
|
driver_exec_finished_hid(finished_data_size);
|
||||||
}
|
}
|
||||||
else if (status == PICOKEY_ERR_BLOCKED) {
|
else if (status == PICOKEYS_ERR_BLOCKED) {
|
||||||
send_keepalive();
|
send_keepalive();
|
||||||
}
|
}
|
||||||
if (hid_tx[ITF_HID_CTAP].w_ptr > hid_tx[ITF_HID_CTAP].r_ptr && last_write_result[ITF_HID_CTAP] != WRITE_PENDING) {
|
if (hid_tx[ITF_HID_CTAP].w_ptr > hid_tx[ITF_HID_CTAP].r_ptr && last_write_result[ITF_HID_CTAP] != WRITE_PENDING) {
|
||||||
|
|||||||
@@ -43,31 +43,31 @@ The smartphone may be artificially picky about which Ethernet MAC address to rec
|
|||||||
try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 (clearing bit 1).
|
try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 (clearing bit 1).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(ESP_PLATFORM)
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
#include "tusb.h"
|
|
||||||
|
|
||||||
#include "dhserver.h"
|
#include "dhserver.h"
|
||||||
#include "dnserver.h"
|
#include "dnserver.h"
|
||||||
#include "lwip/ethip6.h"
|
#include "lwip/ethip6.h"
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
#include "lwip/timeouts.h"
|
#include "lwip/timeouts.h"
|
||||||
|
#endif
|
||||||
#include "rest_server.h"
|
#include "rest_server.h"
|
||||||
#include "rest_server_tls.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
|
/* shared between tud_network_recv_cb() and service_traffic() */
|
||||||
|
static struct pbuf *received_frame;
|
||||||
|
|
||||||
|
#if !defined(ESP_PLATFORM)
|
||||||
|
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
|
||||||
|
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
|
||||||
|
/* it is suggested that the first byte is 0x02 to indicate a link-local address */
|
||||||
|
uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00};
|
||||||
|
|
||||||
#define INIT_IP4(a, b, c, d) \
|
#define INIT_IP4(a, b, c, d) \
|
||||||
{ PP_HTONL(LWIP_MAKEU32(a, b, c, d)) }
|
{ PP_HTONL(LWIP_MAKEU32(a, b, c, d)) }
|
||||||
|
|
||||||
/* lwip context */
|
/* lwip context */
|
||||||
static struct netif netif_data;
|
static struct netif netif_data;
|
||||||
|
|
||||||
/* shared between tud_network_recv_cb() and service_traffic() */
|
|
||||||
static struct pbuf *received_frame;
|
|
||||||
|
|
||||||
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
|
|
||||||
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
|
|
||||||
/* it is suggested that the first byte is 0x02 to indicate a link-local address */
|
|
||||||
uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00};
|
|
||||||
|
|
||||||
/* network parameters of this MCU */
|
/* network parameters of this MCU */
|
||||||
static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1);
|
static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1);
|
||||||
static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0);
|
static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0);
|
||||||
@@ -201,8 +201,9 @@ void service_traffic(void) {
|
|||||||
received_frame = NULL;
|
received_frame = NULL;
|
||||||
tud_network_recv_renew();
|
tud_network_recv_renew();
|
||||||
}
|
}
|
||||||
|
#if !defined(ESP_PLATFORM)
|
||||||
sys_check_timeouts();
|
sys_check_timeouts();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_network_init_cb(void) {
|
void tud_network_init_cb(void) {
|
||||||
@@ -213,11 +214,14 @@ void tud_network_init_cb(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
int lwip_itf_init(void) {
|
int lwip_itf_init(void) {
|
||||||
|
#if !defined(ESP_PLATFORM)
|
||||||
init_lwip();
|
init_lwip();
|
||||||
while (!netif_is_up(&netif_data));
|
while (!netif_is_up(&netif_data));
|
||||||
while (dhserv_init(&dhcp_config) != ERR_OK);
|
while (dhserv_init(&dhcp_config) != ERR_OK);
|
||||||
while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK);
|
while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK);
|
||||||
|
#endif
|
||||||
while (rest_server_init(REST_CONN_ALL) != ERR_OK);
|
while (rest_server_init(REST_CONN_ALL) != ERR_OK);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
|
#include "pico_time.h"
|
||||||
#include "rest.h"
|
#include "rest.h"
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef REST_SERVER_H
|
#ifndef REST_H
|
||||||
#define REST_SERVER_H
|
#define REST_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
|
|
||||||
#define REST_MAX_REQUEST_SIZE 1024
|
#define REST_MAX_REQUEST_SIZE 1024
|
||||||
#define REST_MAX_METHOD_SIZE 8
|
#define REST_MAX_METHOD_SIZE 8
|
||||||
|
|||||||
@@ -15,18 +15,12 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
#include "picokeys.h"
|
||||||
#include "rest_server.h"
|
#include "rest_server.h"
|
||||||
#include "rest_server_tls.h"
|
#include "rest_server_tls.h"
|
||||||
#include "pico_keys.h"
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#ifdef ENABLE_EMULATION
|
#ifdef ENABLE_EMULATION
|
||||||
@@ -127,7 +121,7 @@ void rest_task(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
status = card_status(ITF_LWIP);
|
status = card_status(ITF_LWIP);
|
||||||
if (status != PICOKEY_OK) {
|
if (status != PICOKEYS_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef PICO_KEYS_REST_SERVER_H
|
#ifndef REST_SERVER_H
|
||||||
#define PICO_KEYS_REST_SERVER_H
|
#define REST_SERVER_H
|
||||||
|
|
||||||
#ifdef ENABLE_EMULATION
|
#ifdef ENABLE_EMULATION
|
||||||
typedef int err_t;
|
typedef int err_t;
|
||||||
|
|||||||
@@ -15,13 +15,9 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
#include "picokeys.h"
|
||||||
#include "rest_server_tls.h"
|
#include "rest_server_tls.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
extern void rest_close_conn(rest_conn_t *conn);
|
extern void rest_close_conn(rest_conn_t *conn);
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PICO_KEYS_REST_SERVER_TLS_H
|
#ifndef REST_SERVER_TLS_H
|
||||||
#define PICO_KEYS_REST_SERVER_TLS_H
|
#define REST_SERVER_TLS_H
|
||||||
|
|
||||||
#ifdef ENABLE_EMULATION
|
#ifdef ENABLE_EMULATION
|
||||||
typedef int err_t;
|
typedef int err_t;
|
||||||
@@ -58,4 +58,4 @@ extern void tls_handle_client(int client_fd);
|
|||||||
extern struct tcp_pcb *tls_listener_pcb;
|
extern struct tcp_pcb *tls_listener_pcb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif // REST_SERVER_TLS_H
|
||||||
|
|||||||
@@ -15,15 +15,17 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "picokeys.h"
|
||||||
#include "pico_keys.h"
|
#include "usb.h"
|
||||||
|
#include "led/led.h"
|
||||||
|
#include "button.h"
|
||||||
#if defined(PICO_PLATFORM)
|
#if defined(PICO_PLATFORM)
|
||||||
#include "pico/stdlib.h"
|
#include "pico/bootrom.h"
|
||||||
#include "pico/multicore.h"
|
#include "pico/multicore.h"
|
||||||
#include "hardware/sync.h"
|
#include "hardware/sync.h"
|
||||||
#include "bsp/board.h"
|
#include "bsp/board.h"
|
||||||
|
#define multicore_launch_func_core1(a) multicore_launch_core1((void (*) (void))a)
|
||||||
#endif
|
#endif
|
||||||
#include "usb.h"
|
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
@@ -31,10 +33,6 @@
|
|||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For memcpy
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// Device specific functions
|
// Device specific functions
|
||||||
static uint32_t *timeout_counter = NULL;
|
static uint32_t *timeout_counter = NULL;
|
||||||
static uint8_t card_locked_itf = 0; // no locked
|
static uint8_t card_locked_itf = 0; // no locked
|
||||||
@@ -44,7 +42,7 @@ static mutex_t mutex;
|
|||||||
#endif
|
#endif
|
||||||
#if !defined(PICO_PLATFORM) && !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
#if !defined(PICO_PLATFORM) && !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include "pthread_win32.h"
|
#include "compat/pthread_win32.h"
|
||||||
#endif
|
#endif
|
||||||
pthread_t hcore0, hcore1;
|
pthread_t hcore0, hcore1;
|
||||||
#endif
|
#endif
|
||||||
@@ -327,7 +325,7 @@ void usb_task(void) {
|
|||||||
int card_status(uint8_t itf) {
|
int card_status(uint8_t itf) {
|
||||||
if (card_locked_itf == itf) {
|
if (card_locked_itf == itf) {
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
uint32_t m = 0x0;
|
uint32_t m = 0x0;
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
@@ -343,11 +341,11 @@ int card_status(uint8_t itf) {
|
|||||||
if (m == EV_EXEC_FINISHED) {
|
if (m == EV_EXEC_FINISHED) {
|
||||||
timeout_stop();
|
timeout_stop();
|
||||||
led_set_mode(MODE_MOUNTED);
|
led_set_mode(MODE_MOUNTED);
|
||||||
return PICOKEY_OK;
|
return PICOKEYS_OK;
|
||||||
}
|
}
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
else if (m == EV_PRESS_BUTTON) {
|
else if (m == EV_PRESS_BUTTON) {
|
||||||
uint32_t flag = wait_button() ? EV_BUTTON_TIMEOUT : EV_BUTTON_PRESSED;
|
uint32_t flag = button_wait() ? EV_BUTTON_TIMEOUT : EV_BUTTON_PRESSED;
|
||||||
queue_try_add(&usb_to_card_q, &flag);
|
queue_try_add(&usb_to_card_q, &flag);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -356,18 +354,18 @@ int card_status(uint8_t itf) {
|
|||||||
usb_secure_reboot_now();
|
usb_secure_reboot_now();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (timeout > 0) {
|
if (timeout > 0) {
|
||||||
if (timeout + timeout_counter[itf] < board_millis()) {
|
if (timeout + timeout_counter[itf] < board_millis()) {
|
||||||
timeout = board_millis();
|
timeout = board_millis();
|
||||||
return PICOKEY_ERR_BLOCKED;
|
return PICOKEYS_ERR_BLOCKED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USB_ITF_CCID
|
#ifndef USB_ITF_CCID
|
||||||
|
|||||||
@@ -18,18 +18,20 @@
|
|||||||
#ifndef _USB_H_
|
#ifndef _USB_H_
|
||||||
#define _USB_H_
|
#define _USB_H_
|
||||||
|
|
||||||
|
#include "picokeys.h"
|
||||||
|
|
||||||
#if defined(ENABLE_EMULATION)
|
#if defined(ENABLE_EMULATION)
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#elif defined(ESP_PLATFORM)
|
#elif defined(ESP_PLATFORM)
|
||||||
#include "esp_compat.h"
|
#include "compat/esp_compat.h"
|
||||||
#elif defined(PICO_PLATFORM)
|
#elif defined(PICO_PLATFORM)
|
||||||
#include "pico/util/queue.h"
|
#include "pico/util/queue.h"
|
||||||
#else
|
#else
|
||||||
#include "queue.h"
|
#include "compat/queue.h"
|
||||||
#include "board.h"
|
#include "compat/board.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat/compat.h"
|
||||||
|
|
||||||
/* USB thread */
|
/* USB thread */
|
||||||
#define EV_CARD_CHANGE 1
|
#define EV_CARD_CHANGE 1
|
||||||
|
|||||||
@@ -15,17 +15,14 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include "picokeys.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "usb_descriptors.h"
|
|
||||||
#if defined(PICO_PLATFORM)
|
|
||||||
#include "pico/unique_id.h"
|
|
||||||
#endif
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include "tinyusb.h"
|
#include "tinyusb.h"
|
||||||
#endif
|
#endif
|
||||||
#include "pico_keys_version.h"
|
#include "picokeys_version.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
#ifndef USB_VID
|
#ifndef USB_VID
|
||||||
#define USB_VID 0x2E8A
|
#define USB_VID 0x2E8A
|
||||||
@@ -59,7 +56,7 @@ tusb_desc_device_t desc_device = {
|
|||||||
|
|
||||||
.idVendor = (USB_VID),
|
.idVendor = (USB_VID),
|
||||||
.idProduct = (USB_PID),
|
.idProduct = (USB_PID),
|
||||||
.bcdDevice = PICO_KEYS_SDK_VERSION,
|
.bcdDevice = PICOKEYS_SDK_VERSION,
|
||||||
|
|
||||||
.iManufacturer = 1,
|
.iManufacturer = 1,
|
||||||
.iProduct = 2,
|
.iProduct = 2,
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
|
||||||
* Copyright (c) 2022 Pol Henarejos.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef USB_DESCRIPTORS_H_
|
|
||||||
#define USB_DESCRIPTORS_H_
|
|
||||||
|
|
||||||
#include "compat.h"
|
|
||||||
|
|
||||||
PACK(
|
|
||||||
struct ccid_class_descriptor {
|
|
||||||
uint8_t bLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint16_t bcdCCID;
|
|
||||||
uint8_t bMaxSlotIndex;
|
|
||||||
uint8_t bVoltageSupport;
|
|
||||||
uint32_t dwProtocols;
|
|
||||||
uint32_t dwDefaultClock;
|
|
||||||
uint32_t dwMaximumClock;
|
|
||||||
uint8_t bNumClockSupport;
|
|
||||||
uint32_t dwDataRate;
|
|
||||||
uint32_t dwMaxDataRate;
|
|
||||||
uint8_t bNumDataRatesSupported;
|
|
||||||
uint32_t dwMaxIFSD;
|
|
||||||
uint32_t dwSynchProtocols;
|
|
||||||
uint32_t dwMechanical;
|
|
||||||
uint32_t dwFeatures;
|
|
||||||
uint32_t dwMaxCCIDMessageLength;
|
|
||||||
uint8_t bClassGetResponse;
|
|
||||||
uint8_t bclassEnvelope;
|
|
||||||
uint16_t wLcdLayout;
|
|
||||||
uint8_t bPINSupport;
|
|
||||||
uint8_t bMaxCCIDBusySlots;
|
|
||||||
});
|
|
||||||
|
|
||||||
#endif /* USB_DESCRIPTORS_H_ */
|
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pico_keys.h"
|
#include <stdint.h>
|
||||||
#include "pico_keys_version.h"
|
#include "picokeys_version.h"
|
||||||
|
|
||||||
const uint8_t PICO_PRODUCT = 0;
|
const uint8_t PICO_PRODUCT = 0;
|
||||||
const uint8_t PICO_VERSION_MAJOR = PICO_KEYS_SDK_VERSION_MAJOR;
|
const uint8_t PICO_VERSION_MAJOR = PICOKEYS_SDK_VERSION_MAJOR;
|
||||||
const uint8_t PICO_VERSION_MINOR = PICO_KEYS_SDK_VERSION_MINOR;
|
const uint8_t PICO_VERSION_MINOR = PICOKEYS_SDK_VERSION_MINOR;
|
||||||
|
|||||||
Reference in New Issue
Block a user