From a9dc6fd7f87fff7505ad526c7392ec1bc3a811a9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 1 Jan 2024 01:54:49 +0100 Subject: [PATCH] Added support for building emulation in Windows. It has not been tested but it should not break any linux build. Signed-off-by: Pol Henarejos --- config/mbedtls_config.h | 2 + pico_keys_sdk_import.cmake | 284 +++++++++++++++++++--------------- src/apdu.c | 17 +- src/apdu.h | 15 +- src/asn1.c | 35 ++--- src/asn1.h | 12 +- src/compat.h | 52 +++++++ src/crypto_utils.c | 6 +- src/crypto_utils.h | 4 +- src/eac.c | 53 +++---- src/eac.h | 6 +- src/fs/file.c | 24 +-- src/fs/file.h | 9 +- src/fs/low_flash.c | 11 ++ src/fs/mman.c | 184 ++++++++++++++++++++++ src/fs/mman.h | 55 +++++++ src/main.c | 33 ++++ src/pico_keys.h | 12 ++ src/rng/random.c | 6 +- src/usb/emulation/emulation.c | 84 ++++++---- src/usb/usb.c | 16 +- src/usb/usb.h | 30 ++-- 22 files changed, 681 insertions(+), 269 deletions(-) create mode 100644 src/compat.h create mode 100644 src/fs/mman.c create mode 100644 src/fs/mman.h diff --git a/config/mbedtls_config.h b/config/mbedtls_config.h index ecc0ad1..aba124f 100644 --- a/config/mbedtls_config.h +++ b/config/mbedtls_config.h @@ -248,7 +248,9 @@ * * Uncomment to get warnings on using deprecated functions and features. */ +#if (defined(__GNUC__) || defined(__clang__)) #define MBEDTLS_DEPRECATED_WARNING +#endif /** * \def MBEDTLS_DEPRECATED_REMOVED diff --git a/pico_keys_sdk_import.cmake b/pico_keys_sdk_import.cmake index 2e38a0e..e013847 100644 --- a/pico_keys_sdk_import.cmake +++ b/pico_keys_sdk_import.cmake @@ -20,45 +20,47 @@ option(VIDPID "Set specific VID/PID from a known platform {NitroHSM, NitroFIDO2, message(STATUS "VIDPID:\t\t\t '${VIDPID}'") if (VIDPID STREQUAL "NitroHSM") - set(USB_VID 0x20A0) - set(USB_PID 0x4230) + set(USB_VID 0x20A0) + set(USB_PID 0x4230) elseif (VIDPID STREQUAL "NitroFIDO2") - set(USB_VID 0x20A0) - set(USB_PID 0x42B1) + set(USB_VID 0x20A0) + set(USB_PID 0x42B1) elseif (VIDPID STREQUAL "NitroStart") - set(USB_VID 0x20A0) - set(USB_PID 0x4211) + set(USB_VID 0x20A0) + set(USB_PID 0x4211) elseif (VIDPID STREQUAL "NitroPro") - set(USB_VID 0x20A0) - set(USB_PID 0x4108) + set(USB_VID 0x20A0) + set(USB_PID 0x4108) elseif (VIDPID STREQUAL "Nitro3") - set(USB_VID 0x20A0) - set(USB_PID 0x42B2) + set(USB_VID 0x20A0) + set(USB_PID 0x42B2) elseif (VIDPID STREQUAL "Yubikey5") - set(USB_VID 0x1050) - set(USB_PID 0x0407) + set(USB_VID 0x1050) + set(USB_PID 0x0407) elseif (VIDPID STREQUAL "YubikeyNeo") - set(USB_VID 0x1050) - set(USB_PID 0x0116) + set(USB_VID 0x1050) + set(USB_PID 0x0116) elseif (VIDPID STREQUAL "YubiHSM") - set(USB_VID 0x1050) - set(USB_PID 0x0030) + set(USB_VID 0x1050) + set(USB_PID 0x0030) elseif (VIDPID STREQUAL "Gnuk") - set(USB_VID 0x234B) - set(USB_PID 0x0000) + set(USB_VID 0x234B) + set(USB_PID 0x0000) elseif (VIDPID STREQUAL "GnuPG") - set(USB_VID 0x1209) - set(USB_PID 0x2440) + set(USB_VID 0x1209) + set(USB_PID 0x2440) endif() if (NOT DEFINED USB_VID) set(USB_VID 0xFEFF) endif() add_definitions(-DUSB_VID=${USB_VID}) + if (NOT DEFINED USB_PID) set(USB_PID 0xFCFD) endif() add_definitions(-DUSB_PID=${USB_PID}) + if (NOT DEFINED DEBUG_APDU) set(DEBUG_APDU 0) endif() @@ -71,7 +73,7 @@ if(ENABLE_DELAYED_BOOT) add_definitions(-DPICO_XOSC_STARTUP_DELAY_MULTIPLIER=64) message(STATUS "Delayed boot:\t\t enabled") else() -message(STATUS "Delayed boot:\t\t disabled") + message(STATUS "Delayed boot:\t\t disabled") endif(ENABLE_DELAYED_BOOT) if(USB_ITF_HID) add_definitions(-DUSB_ITF_HID=1) @@ -86,52 +88,54 @@ add_definitions(-DMBEDTLS_CONFIG_FILE="${CMAKE_CURRENT_LIST_DIR}/config/mbedtls_ message(STATUS "USB VID/PID: ${USB_VID}:${USB_PID}") -set(SOURCES ${SOURCES} -${CMAKE_CURRENT_LIST_DIR}/src/main.c -${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c -${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c -${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c -${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c -${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c -${CMAKE_CURRENT_LIST_DIR}/src/rng/hwrng.c -${CMAKE_CURRENT_LIST_DIR}/src/eac.c -${CMAKE_CURRENT_LIST_DIR}/src/crypto_utils.c -${CMAKE_CURRENT_LIST_DIR}/src/asn1.c -${CMAKE_CURRENT_LIST_DIR}/src/apdu.c +set(EXTERNAL_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aes.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/asn1parse.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/asn1write.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/bignum.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/bignum_core.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ccm.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cmac.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cipher.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cipher_wrap.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/constant_time.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecdsa.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecdh.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecp.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecp_curves.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/gcm.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/hkdf.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/md.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/md5.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/oid.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkcs5.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/platform_util.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/rsa.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/rsa_alt_helpers.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha1.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha512.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/chachapoly.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/chacha20.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/poly1305.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ripemd160.c +) -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aes.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/asn1parse.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/asn1write.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/bignum.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/bignum_core.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ccm.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cmac.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cipher.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cipher_wrap.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/constant_time.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecdsa.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecdh.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecp.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ecp_curves.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/gcm.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/hkdf.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/md.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/md5.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/oid.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkcs5.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/platform_util.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/rsa.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/rsa_alt_helpers.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha1.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha512.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/chachapoly.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/chacha20.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/poly1305.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ripemd160.c +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/src/main.c + ${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c + ${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c + ${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c + ${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c + ${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c + ${CMAKE_CURRENT_LIST_DIR}/src/rng/hwrng.c + ${CMAKE_CURRENT_LIST_DIR}/src/eac.c + ${CMAKE_CURRENT_LIST_DIR}/src/crypto_utils.c + ${CMAKE_CURRENT_LIST_DIR}/src/asn1.c + ${CMAKE_CURRENT_LIST_DIR}/src/apdu.c ) ## mbedTLS reports an stringop overflow for cmac.c -if (NOT ENABLE_EMULATION OR NOT APPLE) +if (NOT ENABLE_EMULATION AND NOT APPLE) set_source_files_properties( ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/cmac.c PROPERTIES @@ -139,43 +143,43 @@ if (NOT ENABLE_EMULATION OR NOT APPLE) ) endif() set(INCLUDES ${INCLUDES} -${CMAKE_CURRENT_LIST_DIR}/src -${CMAKE_CURRENT_LIST_DIR}/src/usb -${CMAKE_CURRENT_LIST_DIR}/src/fs -${CMAKE_CURRENT_LIST_DIR}/src/rng -${CMAKE_CURRENT_LIST_DIR}/mbedtls/include -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library + ${CMAKE_CURRENT_LIST_DIR}/src + ${CMAKE_CURRENT_LIST_DIR}/src/usb + ${CMAKE_CURRENT_LIST_DIR}/src/fs + ${CMAKE_CURRENT_LIST_DIR}/src/rng + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/include + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library ) if(USB_ITF_HID OR ENABLE_EMULATION) -set(SOURCES ${SOURCES} -${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborencoder.c -${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborparser.c -${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborparser_dup_string.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write_crt.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509_create.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write_csr.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk_wrap.c -${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkwrite.c -) + set(EXTERNAL_SOURCES ${EXTERNAL_SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write_crt.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509_create.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write_csr.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pk_wrap.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pkwrite.c + ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborencoder.c + ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborparser.c + ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src/cborparser_dup_string.c + ) -set(INCLUDES ${INCLUDES} -${CMAKE_CURRENT_LIST_DIR}/tinycbor/src -) + set(INCLUDES ${INCLUDES} + ${CMAKE_CURRENT_LIST_DIR}/tinycbor/src + ) endif() set(LIBRARIES -pico_stdlib -pico_multicore -hardware_flash -hardware_sync -hardware_adc -pico_unique_id -hardware_rtc -tinyusb_device -tinyusb_board -hardware_pio + pico_stdlib + pico_multicore + hardware_flash + hardware_sync + hardware_adc + pico_unique_id + hardware_rtc + tinyusb_device + tinyusb_board + hardware_pio ) if(PICO_BOARD STREQUAL "pico_w") @@ -189,64 +193,90 @@ function(add_impl_library target) endfunction() if(${USB_ITF_HID}) set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c + ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c ) set(INCLUDES ${INCLUDES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid + ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid ) endif() if (ENABLE_EMULATION) if(APPLE) set(CMAKE_OSX_SYSROOT "/Library/Developer/CommandLineTools//SDKs/MacOSX11.3.sdk") + elseif(MSVC) + set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/src/fs/mman.c + ) endif() add_definitions(-DENABLE_EMULATION) - set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/emulation.c - ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ctr_drbg.c - ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/entropy.c - ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/entropy_poll.c - ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aesni.c + set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/emulation.c + ) + set(EXTERNAL_SOURCES ${EXTERNAL_SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/ctr_drbg.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/entropy.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/entropy_poll.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aesni.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/pem.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/x509write.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/base64.c ) set(INCLUDES ${INCLUDES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation + ${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation ) - if (NOT TARGET pico_keys_sdk) - add_impl_library(pico_keys_sdk) - target_sources(pico_keys_sdk INTERFACE - ${SOURCES} - ) - target_include_directories(pico_keys_sdk INTERFACE - ${INCLUDES} - ) - endif() else() - if (${USB_ITF_CCID}) set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c + ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c ) set(INCLUDES ${INCLUDES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid + ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid ) endif() set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c + ${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c ) - if (NOT TARGET pico_keys_sdk) +endif() +if (MSVC) + target_compile_options(pico_hsm PUBLIC + -wd4820 + -wd4255 + -wd5045 + -wd4706 + -wd4061 + ) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS + __STDC_WANT_SECURE_LIB__=0 + _WIN32_WINNT_WIN10_TH2=0 + _WIN32_WINNT_WIN10_RS1=0 + _WIN32_WINNT_WIN10_RS2=0 + _WIN32_WINNT_WIN10_RS3=0 + _WIN32_WINNT_WIN10_RS4=0 + _WIN32_WINNT_WIN10_RS5=0 + _STRALIGN_USE_SECURE_CRT=0 + NTDDI_WIN10_CU=0) + set_source_files_properties( + ${EXTERNAL_SOURCES} + PROPERTIES + COMPILE_FLAGS " -W3 -wd4242 -wd4065" + ) +endif() +if (NOT TARGET pico_keys_sdk) + if (ENABLE_EMULATION) + add_impl_library(pico_keys_sdk) + else() pico_add_library(pico_keys_sdk) - - target_sources(pico_keys_sdk INTERFACE - ${SOURCES} - ) - - target_include_directories(pico_keys_sdk INTERFACE - ${INCLUDES} - ) - - target_link_libraries(pico_keys_sdk INTERFACE ${LIBRARIES}) endif() + set(SOURCES ${SOURCES} ${EXTERNAL_SOURCES}) + target_sources(pico_keys_sdk INTERFACE + ${SOURCES} + ) + target_include_directories(pico_keys_sdk INTERFACE + ${INCLUDES} + ) + target_link_libraries(pico_keys_sdk INTERFACE ${LIBRARIES}) endif() + diff --git a/src/apdu.c b/src/apdu.c index 2c5a3b4..aa69c4c 100644 --- a/src/apdu.c +++ b/src/apdu.c @@ -52,7 +52,7 @@ int process_apdu() { return set_res_sw(0x6a, 0x82); } -size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { +uint16_t apdu_process(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size) { apdu.header = (uint8_t *) buffer; apdu.nc = apdu.ne = 0; if (buffer_size == 4) { @@ -72,7 +72,7 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { if (buffer_size == 7) { apdu.ne = (apdu.header[5] << 8) | apdu.header[6]; if (apdu.ne == 0) { - apdu.ne = 65536; + //apdu.ne = 65536; // All underlying architecture assumes payloads are 65535 as max } } else { @@ -82,7 +82,7 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { if (apdu.nc + 7 + 2 == buffer_size) { apdu.ne = (apdu.header[buffer_size - 2] << 8) | apdu.header[buffer_size - 1]; if (apdu.ne == 0) { - apdu.ne = 65536; + //apdu.ne = 65536; } } } @@ -116,7 +116,7 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { } #endif #else - driver_exec_finished_cont_emul(itf, apdu.rlen + 2, rdata_gr - usb_get_tx(itf)); + driver_exec_finished_cont_emul(itf, apdu.rlen + 2, (uint16_t)(rdata_gr - usb_get_tx(itf))); #endif //Prepare next RAPDU apdu.sw = 0; @@ -131,7 +131,7 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { rdata_gr[1] = 0; } else { - rdata_gr[1] = apdu.rlen - apdu.ne; + rdata_gr[1] = (uint8_t)(apdu.rlen - apdu.ne); } #ifndef ENABLE_EMULATION #ifdef USB_ITF_HID @@ -145,11 +145,10 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { } #endif #else - driver_exec_finished_cont_emul(itf, apdu.ne + 2, rdata_gr - apdu.ne - usb_get_tx(itf)); + driver_exec_finished_cont_emul(itf, apdu.ne + 2, (uint16_t)(rdata_gr - apdu.ne - usb_get_tx(itf))); #endif apdu.rlen -= apdu.ne; } - return 0; } else { apdu.sw = 0; @@ -212,7 +211,7 @@ void apdu_finish() { #endif } -size_t apdu_next() { +uint16_t apdu_next() { if (apdu.sw != 0) { if (apdu.rlen <= apdu.ne) { return apdu.rlen + 2; @@ -225,7 +224,7 @@ size_t apdu_next() { rdata_gr[1] = 0; } else { - rdata_gr[1] = apdu.rlen - apdu.ne; + rdata_gr[1] = (uint8_t)(apdu.rlen - apdu.ne); } apdu.rlen -= apdu.ne; } diff --git a/src/apdu.h b/src/apdu.h index 62c8877..afeb1c0 100644 --- a/src/apdu.h +++ b/src/apdu.h @@ -21,6 +21,8 @@ #include #ifndef ENABLE_EMULATION #include "pico/stdlib.h" +#else +#include "compat.h" #endif #include #include @@ -79,15 +81,16 @@ extern uint8_t num_apps; extern app_t apps[4]; extern app_t *current_app; -struct apdu { +PACK(struct apdu { uint8_t *header; - uint32_t nc; - uint32_t ne; + uint16_t nc; + uint16_t ne; uint8_t *data; uint16_t sw; uint8_t *rdata; uint16_t rlen; -} __attribute__((__packed__)); + +}); #define CLA(a) a.header[0] #define INS(a) a.header[1] @@ -101,9 +104,9 @@ extern struct apdu apdu; extern uint16_t set_res_sw(uint8_t sw1, uint8_t sw2); extern int process_apdu(); -extern size_t apdu_process(uint8_t, const uint8_t *buffer, size_t buffer_size); +extern uint16_t apdu_process(uint8_t, const uint8_t *buffer, uint16_t buffer_size); extern void apdu_finish(); -extern size_t apdu_next(); +extern uint16_t apdu_next(); extern void apdu_thread(); #endif diff --git a/src/asn1.c b/src/asn1.c index 568276c..b114d7b 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -17,44 +17,41 @@ #include "asn1.h" -size_t asn1_len_tag(uint16_t tag, size_t len) { - size_t ret = 1 + format_tlv_len(len, NULL) + len; +uint16_t asn1_len_tag(uint16_t tag, uint16_t len) { + uint16_t ret = 1 + format_tlv_len(len, NULL) + len; if (tag > 0x00ff) { return ret + 1; } return ret; } -int format_tlv_len(size_t len, uint8_t *out) { +uint8_t format_tlv_len(uint16_t len, uint8_t *out) { if (len < 128) { if (out) { - *out = len; + *out = (uint8_t)len; } return 1; } else if (len < 256) { if (out) { *out++ = 0x81; - *out++ = len; + *out++ = (uint8_t)len; } return 2; } - else { - if (out) { - *out++ = 0x82; - *out++ = (len >> 8) & 0xff; - *out++ = len & 0xff; - } - return 3; + if (out) { + *out++ = 0x82; + *out++ = (len >> 8) & 0xff; + *out++ = len & 0xff; } - return 0; + return 3; } int walk_tlv(const uint8_t *cdata, - size_t cdata_len, + uint16_t cdata_len, uint8_t **p, uint16_t *tag, - size_t *tag_len, + uint16_t *tag_len, uint8_t **data) { if (!p) { return 0; @@ -66,7 +63,7 @@ int walk_tlv(const uint8_t *cdata, return 0; } uint16_t tg = 0x0; - size_t tgl = 0; + uint16_t tgl = 0; tg = *(*p)++; if ((tg & 0x1f) == 0x1f) { tg <<= 8; @@ -94,14 +91,14 @@ int walk_tlv(const uint8_t *cdata, } bool asn1_find_tag(const uint8_t *data, - size_t data_len, + uint16_t data_len, uint16_t itag, - size_t *tag_len, + uint16_t *tag_len, uint8_t **tag_data) { uint16_t tag = 0x0; uint8_t *p = NULL; uint8_t *tdata = NULL; - size_t tlen = 0; + uint16_t tlen = 0; while (walk_tlv(data, data_len, &p, &tag, &tlen, &tdata)) { if (itag == tag) { if (tag_data != NULL) { diff --git a/src/asn1.h b/src/asn1.h index 064efb8..474cb6d 100644 --- a/src/asn1.h +++ b/src/asn1.h @@ -27,17 +27,17 @@ #endif extern int walk_tlv(const uint8_t *cdata, - size_t cdata_len, + uint16_t cdata_len, uint8_t **p, uint16_t *tag, - size_t *tag_len, + uint16_t *tag_len, uint8_t **data); -extern int format_tlv_len(size_t len, uint8_t *out); +extern uint8_t format_tlv_len(uint16_t len, uint8_t *out); extern bool asn1_find_tag(const uint8_t *data, - size_t data_len, + uint16_t data_len, uint16_t itag, - size_t *tag_len, + uint16_t *tag_len, uint8_t **tag_data); -extern size_t asn1_len_tag(uint16_t tag, size_t len); +extern uint16_t asn1_len_tag(uint16_t tag, uint16_t len); #endif diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..e0ffdd4 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,52 @@ +/* + * 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 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +#ifdef __GNUC__ +#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) +#endif + +#ifdef _MSC_VER +#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) +#endif + +#ifdef __cplusplus +#define INITIALIZER(f) \ + static void f(void); \ + struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \ + static void f(void) +#elif defined(_MSC_VER) +#pragma section(".CRT$XCU",read) +#define INITIALIZER2_(f,p) \ + static void f(void); \ + __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \ + __pragma(comment(linker,"/include:" p #f "_")) \ + static void f(void) +#ifdef _WIN64 +#define INITIALIZER(f) INITIALIZER2_(f,"") +#else +#define INITIALIZER(f) INITIALIZER2_(f,"_") +#endif +#else +#define INITIALIZER(f) \ + static void f(void) __attribute__((constructor)); \ + static void f(void) +#endif + +#endif // _COMPAT_H diff --git a/src/crypto_utils.c b/src/crypto_utils.c index 99e6cfb..3c8d53a 100644 --- a/src/crypto_utils.c +++ b/src/crypto_utils.c @@ -24,7 +24,7 @@ #include "crypto_utils.h" #include "pico_keys.h" -void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]) { +void double_hash_pin(const uint8_t *pin, uint16_t len, uint8_t output[32]) { uint8_t o1[32]; hash_multi(pin, len, o1); for (int i = 0; i < sizeof(o1); i++) { @@ -33,10 +33,10 @@ void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]) { hash_multi(o1, sizeof(o1), output); } -void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]) { +void hash_multi(const uint8_t *input, uint16_t len, uint8_t output[32]) { mbedtls_sha256_context ctx; mbedtls_sha256_init(&ctx); - int iters = 256; + uint16_t iters = 256; #ifndef ENABLE_EMULATION pico_unique_board_id_t unique_id; diff --git a/src/crypto_utils.h b/src/crypto_utils.h index 7b2ca35..2a8d99b 100644 --- a/src/crypto_utils.h +++ b/src/crypto_utils.h @@ -42,8 +42,8 @@ #define IV_SIZE 16 -extern void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]); -extern void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]); +extern void double_hash_pin(const uint8_t *pin, uint16_t len, uint8_t output[32]); +extern void hash_multi(const uint8_t *input, uint16_t len, uint8_t output[32]); extern void hash256(const uint8_t *input, size_t len, uint8_t output[32]); extern void generic_hash(mbedtls_md_type_t md, const uint8_t *input, size_t len, uint8_t *output); extern int aes_encrypt(const uint8_t *key, diff --git a/src/eac.c b/src/eac.c index 0f5a826..8e9194d 100644 --- a/src/eac.c +++ b/src/eac.c @@ -22,14 +22,14 @@ #include "asn1.h" #include "apdu.h" -static uint8_t nonce[8]; +static uint8_t sm_nonce[8]; static uint8_t sm_kmac[16]; static uint8_t sm_kenc[16]; static MSE_protocol sm_protocol = MSE_NONE; static mbedtls_mpi sm_mSSC; static uint8_t sm_blocksize = 0; static uint8_t sm_iv[16]; -size_t sm_session_pin_len = 0; +uint16_t sm_session_pin_len = 0; uint8_t sm_session_pin[16]; bool is_secured_apdu() { @@ -57,9 +57,9 @@ void sm_derive_key(const uint8_t *input, } void sm_derive_all_keys(const uint8_t *derived, size_t derived_len) { - memcpy(nonce, random_bytes_get(8), 8); - sm_derive_key(derived, derived_len, 1, nonce, sizeof(nonce), sm_kenc); - sm_derive_key(derived, derived_len, 2, nonce, sizeof(nonce), sm_kmac); + memcpy(sm_nonce, random_bytes_get(8), 8); + sm_derive_key(derived, derived_len, 1, sm_nonce, sizeof(sm_nonce), sm_kenc); + sm_derive_key(derived, derived_len, 2, sm_nonce, sizeof(sm_nonce), sm_kmac); mbedtls_mpi_init(&sm_mSSC); mbedtls_mpi_grow(&sm_mSSC, sm_blocksize); mbedtls_mpi_lset(&sm_mSSC, 0); @@ -82,7 +82,7 @@ MSE_protocol sm_get_protocol() { } uint8_t *sm_get_nonce() { - return nonce; + return sm_nonce; } int sm_sign(uint8_t *in, size_t in_len, uint8_t *out) { @@ -103,16 +103,16 @@ int sm_unwrap() { if (r != CCID_OK) { return r; } - int le = sm_get_le(); + uint16_t le = sm_get_le(); if (le >= 0) { apdu.ne = le; } uint8_t *body = NULL; - size_t body_size = 0; + uint16_t body_size = 0; bool is87 = false; uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; + uint16_t tag_len = 0; while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x87 || tag == 0x85) { body = tag_data; @@ -168,20 +168,20 @@ int sm_wrap() { res_APDU_size++; if (res_APDU_size < 128) { memmove(res_APDU + 2, res_APDU, res_APDU_size); - res_APDU[1] = res_APDU_size; + res_APDU[1] = (uint8_t)res_APDU_size; res_APDU_size += 2; } else if (res_APDU_size < 256) { memmove(res_APDU + 3, res_APDU, res_APDU_size); res_APDU[1] = 0x81; - res_APDU[2] = res_APDU_size; + res_APDU[2] = (uint8_t)res_APDU_size; res_APDU_size += 3; } else { memmove(res_APDU + 4, res_APDU, res_APDU_size); res_APDU[1] = 0x82; - res_APDU[2] = res_APDU_size >> 8; - res_APDU[3] = res_APDU_size & 0xff; + res_APDU[2] = (uint8_t)(res_APDU_size >> 8); + res_APDU[3] = (uint8_t)(res_APDU_size & 0xff); res_APDU_size += 4; } res_APDU[0] = 0x87; @@ -204,20 +204,20 @@ int sm_wrap() { return CCID_OK; } -int sm_get_le() { +uint16_t sm_get_le() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; + uint16_t tag_len = 0; while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x97) { - uint32_t le = 0; - for (int t = 1; t <= tag_len; t++) { + uint16_t le = 0; + for (uint16_t t = 1; t <= tag_len; t++) { le |= (*tag_data++) << (tag_len - t); } return le; } } - return -1; + return 0; } void sm_update_iv() { @@ -231,7 +231,8 @@ void sm_update_iv() { int sm_verify() { uint8_t input[1024]; memset(input, 0, sizeof(input)); - int input_len = 0, r = 0; + uint16_t input_len = 0; + int r = 0; bool add_header = (CLA(apdu) & 0xC) == 0xC; int data_len = (int) (apdu.nc / sm_blocksize) * sm_blocksize; if (data_len % sm_blocksize) { @@ -260,14 +261,14 @@ int sm_verify() { } bool some_added = false; const uint8_t *mac = NULL; - size_t mac_len = 0; + uint16_t mac_len = 0; uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; + uint16_t tag_len = 0; while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag & 0x1) { - input[input_len++] = tag; - int tlen = format_tlv_len(tag_len, input + input_len); + input[input_len++] = (uint8_t)tag; + uint8_t tlen = format_tlv_len(tag_len, input + input_len); input_len += tlen; memcpy(input + input_len, tag_data, tag_len); input_len += tag_len; @@ -296,13 +297,13 @@ int sm_verify() { return CCID_VERIFICATION_FAILED; } -int sm_remove_padding(const uint8_t *data, size_t data_len) { - int i = data_len - 1; +uint16_t sm_remove_padding(const uint8_t *data, uint16_t data_len) { + uint16_t i = data_len - 1; for (; i >= 0 && data[i] == 0; i--) { ; } if (i < 0 || data[i] != 0x80) { - return -1; + return 0; } return i; } diff --git a/src/eac.h b/src/eac.h index a80baaf..6343906 100644 --- a/src/eac.h +++ b/src/eac.h @@ -37,12 +37,12 @@ extern uint8_t *sm_get_nonce(); extern int sm_sign(uint8_t *in, size_t in_len, uint8_t *out); int sm_verify(); void sm_update_iv(); -int sm_get_le(); +uint16_t sm_get_le(); extern int sm_unwrap(); -int sm_remove_padding(const uint8_t *data, size_t data_len); +uint16_t sm_remove_padding(const uint8_t *data, uint16_t data_len); extern int sm_wrap(); extern bool is_secured_apdu(); extern uint8_t sm_session_pin[16]; -extern size_t sm_session_pin_len; +extern uint16_t sm_session_pin_len; #endif diff --git a/src/fs/file.c b/src/fs/file.c index 7b01221..93be707 100644 --- a/src/fs/file.c +++ b/src/fs/file.c @@ -56,7 +56,7 @@ void process_fci(const file_t *pe, int fmd) { res_APDU[res_APDU_size++] = 2; if (pe->data) { if ((pe->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) { - uint16_t len = ((int (*)(const file_t *, int))(pe->data))(pe, 0); + uint16_t len = (uint16_t)((int (*)(const file_t *, int))(pe->data))(pe, 0); res_APDU[res_APDU_size++] = (len >> 8) & 0xff; res_APDU[res_APDU_size++] = len & 0xff; } @@ -100,17 +100,17 @@ void process_fci(const file_t *pe, int fmd) { memcpy(res_APDU + res_APDU_size, "\x8A\x01\x05", 3); //life-cycle (5 -> activated) res_APDU_size += 3; uint8_t *meta_data = NULL; - uint8_t meta_size = meta_find(pe->fid, &meta_data); + uint16_t meta_size = meta_find(pe->fid, &meta_data); if (meta_size > 0 && meta_data != NULL) { res_APDU[res_APDU_size++] = 0xA5; res_APDU[res_APDU_size++] = 0x81; - res_APDU[res_APDU_size++] = meta_size; + res_APDU[res_APDU_size++] = (uint8_t )meta_size; memcpy(res_APDU + res_APDU_size, meta_data, meta_size); res_APDU_size += meta_size; } - res_APDU[1] = res_APDU_size - 2; + res_APDU[1] = (uint8_t)res_APDU_size - 2; if (fmd) { - res_APDU[3] = res_APDU_size - 4; + res_APDU[3] = (uint8_t )res_APDU_size - 4; } } @@ -352,14 +352,14 @@ file_t *file_new(uint16_t fid) { //memset((uint8_t *)f->acl, 0x90, sizeof(f->acl)); return f; } -int meta_find(uint16_t fid, uint8_t **out) { +uint16_t meta_find(uint16_t fid, uint8_t **out) { file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF); if (!ef) { - return CCID_ERR_FILE_NOT_FOUND; + return 0; } uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef); - size_t tag_len = 0, data_len = file_get_size(ef); + uint16_t tag_len = 0, data_len = file_get_size(ef); while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) { if (tag_len < 2) { continue; @@ -381,7 +381,7 @@ int meta_delete(uint16_t fid) { } uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef); - size_t tag_len = 0, data_len = file_get_size(ef); + uint16_t tag_len = 0, data_len = file_get_size(ef); uint8_t *fdata = NULL; while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) { uint8_t *tpos = p - tag_len - format_tlv_len(tag_len, NULL) - 1; @@ -390,7 +390,7 @@ int meta_delete(uint16_t fid) { } uint16_t cfid = (tag_data[0] << 8 | tag_data[1]); if (cfid == fid) { - size_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL); + uint16_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL); if (new_len == 0) { flash_clear_file(ef); } @@ -425,7 +425,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) { memcpy(fdata, file_get_data(ef), ef_size); uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; + uint16_t tag_len = 0; while (walk_tlv(fdata, ef_size, &p, &tag, &tag_len, &tag_data)) { if (tag_len < 2) { continue; @@ -479,7 +479,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) { *f++ = fid >> 8; *f++ = fid & 0xff; memcpy(f, data, len); - r = flash_write_data_to_file(ef, fdata, ef_size + asn1_len_tag(fid & 0x1f, len + 2)); + r = flash_write_data_to_file(ef, fdata, ef_size + (uint16_t)asn1_len_tag(fid & 0x1f, len + 2)); free(fdata); if (r != CCID_OK) { return CCID_EXEC_ERROR; diff --git a/src/fs/file.h b/src/fs/file.h index aa53c7b..fd8ee39 100644 --- a/src/fs/file.h +++ b/src/fs/file.h @@ -25,9 +25,10 @@ #else #include #include +#include "compat.h" #endif -#define FILE_TYPE_UNKNOWN 0x00 +#define FILE_TYPE_NOT_KNOWN 0x00 #define FILE_TYPE_DF 0x04 #define FILE_TYPE_INTERNAL_EF 0x03 #define FILE_TYPE_WORKING_EF 0x01 @@ -68,7 +69,7 @@ #define MAX_DEPTH 4 -typedef struct file { +PACK(typedef struct file { const uint16_t fid; const uint8_t parent; //entry number in the whole table!! const uint8_t *name; @@ -76,7 +77,7 @@ typedef struct file { const uint8_t ef_structure; uint8_t *data; //should include 2 bytes len at begining const uint8_t acl[7]; -} __attribute__((packed)) file_t; +}) file_t; extern bool file_has_data(file_t *); @@ -119,7 +120,7 @@ extern int delete_dynamic_file(file_t *f); extern bool isUserAuthenticated; -extern int meta_find(uint16_t, uint8_t **out); +extern uint16_t meta_find(uint16_t, uint8_t **out); extern int meta_delete(uint16_t fid); extern int meta_add(uint16_t fid, const uint8_t *data, uint16_t len); extern int delete_file(file_t *ef); diff --git a/src/fs/low_flash.c b/src/fs/low_flash.c index a70a216..bb2cf5c 100644 --- a/src/fs/low_flash.c +++ b/src/fs/low_flash.c @@ -28,8 +28,19 @@ #include "pico/sem.h" #include "pico/multicore.h" #else +#ifdef _MSC_VER +#include +#include +#define O_RDWR _O_RDWR +#define open _open +#define write _write +#define mode_t unsigned short +#define lseek _lseek +#include "mman.h" +#else #include #include +#endif #include #define FLASH_SECTOR_SIZE 4096 #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) diff --git a/src/fs/mman.c b/src/fs/mman.c new file mode 100644 index 0000000..dfd987f --- /dev/null +++ b/src/fs/mman.c @@ -0,0 +1,184 @@ + +#include +#include +#include + +#include "mman.h" + +#ifndef FILE_MAP_EXECUTE +#define FILE_MAP_EXECUTE 0x0020 +#endif /* FILE_MAP_EXECUTE */ + +static int __map_mman_error(const DWORD err, const int deferr) +{ + (void)deferr; + if (err == 0) + return 0; + //TODO: implement + return err; +} + +static DWORD __map_mmap_prot_page(const int prot) +{ + DWORD protect = 0; + + if (prot == PROT_NONE) + return protect; + + if ((prot & PROT_EXEC) != 0) + { + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + } + else + { + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_READWRITE : PAGE_READONLY; + } + + return protect; +} + +static DWORD __map_mmap_prot_file(const int prot) +{ + DWORD desiredAccess = 0; + + if (prot == PROT_NONE) + return desiredAccess; + + if ((prot & PROT_READ) != 0) + desiredAccess |= FILE_MAP_READ; + if ((prot & PROT_WRITE) != 0) + desiredAccess |= FILE_MAP_WRITE; + if ((prot & PROT_EXEC) != 0) + desiredAccess |= FILE_MAP_EXECUTE; + + return desiredAccess; +} + +void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off) +{ + (void)addr; + HANDLE fm, h; + + void* map = MAP_FAILED; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4293) +#endif + + const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); + const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); + const DWORD protect = __map_mmap_prot_page(prot); + const DWORD desiredAccess = __map_mmap_prot_file(prot); + + const off_t maxSize = off + (off_t)len; + + const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); + const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + errno = 0; + + if (len == 0 + /* Unsupported flag combinations */ + || (flags & MAP_FIXED) != 0 + /* Usupported protection combinations */ + || prot == PROT_EXEC) + { + errno = EINVAL; + return MAP_FAILED; + } + + h = ((flags & MAP_ANONYMOUS) == 0) ? + (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; + + if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return MAP_FAILED; + } + + fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); + + if (fm == NULL) + { + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; + } + + map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); + + CloseHandle(fm); + + if (map == NULL) + { + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; + } + + return map; +} + +int munmap(void* addr, size_t len) +{ + (void)len; + if (UnmapViewOfFile(addr)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mprotect(void* addr, size_t len, int prot) +{ + DWORD newProtect = __map_mmap_prot_page(prot); + DWORD oldProtect = 0; + + if (VirtualProtect(addr, len, newProtect, &oldProtect)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int msync(void* addr, size_t len, int flags) +{ + (void)flags; + if (FlushViewOfFile(addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mlock(const void* addr, size_t len) +{ + if (VirtualLock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int munlock(const void* addr, size_t len) +{ + if (VirtualUnlock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} diff --git a/src/fs/mman.h b/src/fs/mman.h new file mode 100644 index 0000000..2191405 --- /dev/null +++ b/src/fs/mman.h @@ -0,0 +1,55 @@ +/* + * sys/mman.h + * mman-win32 + */ + +#ifndef _SYS_MMAN_H_ +#define _SYS_MMAN_H_ + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + + /* All the headers include this file. */ +#ifndef _MSC_VER +#include <_mingw.h> +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xf +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + + /* Flags for msync. */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + + void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off); + int munmap(void* addr, size_t len); + int mprotect(void* addr, size_t len, int prot); + int msync(void* addr, size_t len, int flags); + int mlock(const void* addr, size_t len); + int munlock(const void* addr, size_t len); + +#ifdef __cplusplus +}; +#endif + +#endif /* _SYS_MMAN_H_ */ diff --git a/src/main.c b/src/main.c index e83e5db..f7fc085 100644 --- a/src/main.c +++ b/src/main.c @@ -21,7 +21,9 @@ #ifndef ENABLE_EMULATION #include "pico/stdlib.h" #else +#if !defined(_MSC_VER) #include +#endif #include "emulation.h" #endif @@ -156,6 +158,35 @@ uint32_t button_timeout = 15000; bool cancel_button = false; #ifdef ENABLE_EMULATION +#ifdef _MSC_VER +#include +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 uint32_t board_millis() { struct timeval start; gettimeofday(&start, NULL); @@ -235,6 +266,7 @@ void led_blinking_task() { } void led_off_all() { +#ifndef ENABLE_EMULATION #ifdef PIMORONI_TINY2040 gpio_put(TINY2040_LED_R_PIN, 1); gpio_put(TINY2040_LED_G_PIN, 1); @@ -251,6 +283,7 @@ void led_off_all() { ws2812_program_init(pio, sm, offset, PICO_DEFAULT_WS2812_PIN, 800000, true); #endif +#endif } void init_rtc() { diff --git a/src/pico_keys.h b/src/pico_keys.h index ebe6509..f9b28d9 100644 --- a/src/pico_keys.h +++ b/src/pico_keys.h @@ -24,15 +24,27 @@ #else #include extern uint32_t board_millis(); +#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 +#endif #include extern bool wait_button(); diff --git a/src/rng/random.c b/src/rng/random.c index 2df3c4e..1e097ee 100644 --- a/src/rng/random.c +++ b/src/rng/random.c @@ -48,7 +48,7 @@ const uint8_t *random_bytes_get(size_t len) { return NULL; } static uint32_t return_word[MAX_RANDOM_BUFFER / sizeof(uint32_t)]; - for (int ix = 0; ix < len; ix += RANDOM_BYTES_LENGTH) { + for (size_t ix = 0; ix < len; ix += RANDOM_BYTES_LENGTH) { neug_wait_full(); memcpy(return_word + ix / sizeof(uint32_t), random_word, RANDOM_BYTES_LENGTH); random_bytes_free((const uint8_t *) random_word); @@ -84,14 +84,14 @@ void random_get_salt(uint8_t *p) { int random_gen(void *arg, unsigned char *out, size_t out_len) { uint8_t *index_p = (uint8_t *) arg; uint8_t index = index_p ? *index_p : 0; - size_t n; + uint8_t n; while (out_len) { neug_wait_full(); n = RANDOM_BYTES_LENGTH - index; if (n > out_len) { - n = out_len; + n = (uint8_t)out_len; } memcpy(out, ((unsigned char *) random_word) + index, n); diff --git a/src/usb/emulation/emulation.c b/src/usb/emulation/emulation.c index 6487b32..f93943d 100644 --- a/src/usb/emulation/emulation.c +++ b/src/usb/emulation/emulation.c @@ -17,31 +17,45 @@ #include "emulation.h" #include +#ifndef _MSC_VER #include #include -#include #include #include -#include -#include -#include #include +#include +typedef int socket_t; +#include +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) +#else +#include +#define O_NONBLOCK _O_NONBLOCK +#define close closesocket +typedef SOCKET socket_t; +typedef int socklen_t; +#define msleep Sleep +#pragma comment(lib, "Ws2_32.lib") +#endif +#include +#include +#include #include "pico_keys.h" #include "apdu.h" #include "usb.h" #include "ccid/ccid.h" -#include -int ccid_sock = 0; -int hid_server_sock = 0; -int hid_client_sock = -1; +socket_t ccid_sock = 0; +socket_t hid_server_sock = 0; +socket_t hid_client_sock = INVALID_SOCKET; extern uint8_t thread_type; extern const uint8_t *cbor_data; extern size_t cbor_len; extern uint8_t cmd; extern int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len); +#ifndef _MSC_VER int msleep(long msec) { struct timespec ts; int res; @@ -60,11 +74,18 @@ int msleep(long msec) { return res; } +#endif int emul_init(char *host, uint16_t port) { struct sockaddr_in serv_addr; fprintf(stderr, "\n Starting emulation envionrment\n"); - if ((ccid_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { +#ifdef _MSC_VER + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + printf("winsock initialization failure\n"); + } +#endif + if ((ccid_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { perror("socket"); return -1; } @@ -85,10 +106,17 @@ int emul_init(char *host, uint16_t port) { close(ccid_sock); return -1; } +#ifdef _MSC_VER + unsigned long on = 1; + if (0 != ioctlsocket(ccid_sock, FIONBIO, &on)) { + perror("ioctlsocket FIONBIO"); + } +#else int x = fcntl(ccid_sock, F_GETFL, 0); fcntl(ccid_sock, F_SETFL, x | O_NONBLOCK); int flag = 1; setsockopt(ccid_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); +#endif // HID server @@ -96,7 +124,7 @@ int emul_init(char *host, uint16_t port) { uint16_t hid_port = port - 1; struct sockaddr_in server_sockaddr; - if ((hid_server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + if ((hid_server_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { perror("socket"); return -1; } @@ -107,7 +135,7 @@ int emul_init(char *host, uint16_t port) { return 1; } -#if HAVE_DECL_SO_NOSIGPIPE +#if defined(HAVE_DECL_SO_NOSIGPIPE) if (setsockopt(hid_server_sock, SOL_SOCKET, SO_NOSIGPIPE, (void *) &yes, sizeof yes) != 0) { perror("setsockopt"); close(hid_server_sock); @@ -145,7 +173,7 @@ uint8_t *driver_prepare_response_emul(uint8_t itf) { return apdu.rdata; } -int get_sock_itf(uint8_t itf) { +socket_t get_sock_itf(uint8_t itf) { #ifdef USB_ITF_CCID if (itf == ITF_CCID) { return ccid_sock; @@ -156,7 +184,7 @@ int get_sock_itf(uint8_t itf) { return hid_client_sock; } #endif - return -1; + return INVALID_SOCKET; } extern void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len); @@ -164,20 +192,20 @@ const uint8_t *complete_report = NULL; uint16_t complete_len = 0; extern bool last_write_result; extern uint16_t send_buffer_size[ITF_TOTAL]; -int driver_write_emul(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { +uint16_t driver_write_emul(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size) { uint16_t size = htons(buffer_size); - int sock = get_sock_itf(itf); + socket_t sock = get_sock_itf(itf); // DEBUG_PAYLOAD(buffer,buffer_size); int ret = 0; do { - ret = send(sock, &size, sizeof(size), 0); - if (ret < 0) { + ret = send(sock, (const char *)&size, sizeof(size), 0); + if (ret == SOCKET_ERROR) { msleep(10); } } while (ret <= 0); do { - ret = send(sock, buffer, (uint16_t) buffer_size, 0); - if (ret < 0) { + ret = send(sock, (const char *)buffer, buffer_size, 0); + if (ret == SOCKET_ERROR) { msleep(10); } } while (ret <= 0); @@ -203,7 +231,7 @@ uint32_t emul_write(uint8_t itf, uint16_t size) { return emul_write_offset(itf, size, 0); } -void driver_exec_finished_cont_emul(uint8_t itf, size_t size_next, size_t offset) { +void driver_exec_finished_cont_emul(uint8_t itf, uint16_t size_next, uint16_t offset) { #ifdef USB_ITF_HID if (itf == ITF_HID) { driver_exec_finished_cont_hid(size_next, offset); @@ -218,7 +246,7 @@ void driver_exec_finished_cont_emul(uint8_t itf, size_t size_next, size_t offset int driver_process_usb_packet_emul(uint8_t itf, uint16_t len) { if (len > 0) { - uint8_t *data = usb_get_rx(itf), *rdata = usb_get_tx(itf); + uint8_t *data = usb_get_rx(itf); #ifdef USB_ITF_CCID if (itf == ITF_CCID) { if (len == 1) { @@ -228,14 +256,14 @@ int driver_process_usb_packet_emul(uint8_t itf, uint16_t len) { } } else { - size_t sent = 0; + uint16_t sent = 0; DEBUG_PAYLOAD(data, len); if ((sent = apdu_process(itf, data, len)) > 0) { process_apdu(); } apdu_finish(); if (sent > 0) { - size_t ret = apdu_next(); + uint16_t ret = apdu_next(); DEBUG_PAYLOAD(rdata, ret); emul_write(itf, ret); } @@ -301,7 +329,7 @@ uint16_t emul_read(uint8_t itf) { } } #endif - int sock = get_sock_itf(itf); + socket_t sock = get_sock_itf(itf); //printf("get_sockt itf %d - %d\n", itf, sock); uint16_t len = 0; fd_set input; @@ -310,7 +338,7 @@ uint16_t emul_read(uint8_t itf) { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0 * 1000; - int n = select(sock + 1, &input, NULL, NULL, &timeout); + int n = select((int)(sock + 1), &input, NULL, NULL, &timeout); if (n == -1) { //printf("read wrong [itf:%d]\n", itf); //something wrong @@ -319,13 +347,13 @@ uint16_t emul_read(uint8_t itf) { //printf("read timeout [itf:%d]\n", itf); } if (FD_ISSET(sock, &input)) { - int valread = recv(sock, &len, sizeof(len), 0); + int valread = recv(sock, (char *)&len, sizeof(len), 0); len = ntohs(len); if (len > 0) { while (true) { - valread = recv(sock, usb_get_rx(itf), len, 0); + valread = recv(sock, (char *)usb_get_rx(itf), len, 0); if (valread > 0) { - return valread; + return (uint16_t)valread; } msleep(10); } diff --git a/src/usb/usb.c b/src/usb/usb.c index ca8939a..6b8ab3e 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -47,7 +47,7 @@ uint32_t usb_write_offset(uint8_t itf, uint16_t len, uint16_t offset) { #ifndef ENABLE_EMULATION uint8_t pkt_max = 64; #endif - int w = 0; + uint16_t w = 0; if (len > sizeof(tx_buffer[itf])) { len = sizeof(tx_buffer[itf]); } @@ -72,8 +72,9 @@ uint32_t usb_write_offset(uint8_t itf, uint16_t len, uint16_t offset) { return w; } -size_t usb_rx(uint8_t itf, const uint8_t *buffer, size_t len) { - uint16_t size = MIN(sizeof(rx_buffer[itf]) - w_offset[itf], len); +#ifndef ENABLE_EMULATION +uint16_t usb_rx(uint8_t itf, const uint8_t *buffer, uint16_t len) { + uint16_t size = MIN((uint16_t)sizeof(rx_buffer[itf]) - w_offset[itf], (uint16_t)len); if (size > 0) { if (buffer == NULL) { #ifdef USB_ITF_HID @@ -83,7 +84,7 @@ size_t usb_rx(uint8_t itf, const uint8_t *buffer, size_t len) { #endif #ifdef USB_ITF_CCID if (itf == ITF_CCID) { - size = driver_read_ccid(rx_buffer[itf] + w_offset[itf], size); + size = (uint16_t)driver_read_ccid(rx_buffer[itf] + w_offset[itf], size); } #endif } @@ -94,9 +95,10 @@ size_t usb_rx(uint8_t itf, const uint8_t *buffer, size_t len) { } return size; } +#endif uint32_t usb_write_flush(uint8_t itf) { - int w = 0; + uint16_t w = 0; if (w_len[itf] > 0) { #ifndef ENABLE_EMULATION #ifdef USB_ITF_HID @@ -217,7 +219,7 @@ void card_init_core1() { #endif } -size_t finished_data_size = 0; +uint16_t finished_data_size = 0; void card_start(void (*func)(void)) { #ifndef ENABLE_EMULATION @@ -237,6 +239,8 @@ void card_start(void (*func)(void)) { multicore_launch_core1(func); } led_set_blink(BLINK_MOUNTED); +#else + (void)func; #endif } diff --git a/src/usb/usb.h b/src/usb/usb.h index 4e6ebd0..fd95180 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -66,43 +66,43 @@ extern uint8_t card_locked_itf; #ifdef USB_ITF_HID extern int driver_process_usb_packet_hid(uint16_t rx_read); -extern void driver_exec_finished_hid(size_t size_next); -extern void driver_exec_finished_cont_hid(size_t size_next, size_t offset); +extern void driver_exec_finished_hid(uint16_t size_next); +extern void driver_exec_finished_cont_hid(uint16_t size_next, uint16_t offset); extern void driver_exec_timeout_hid(); extern bool driver_mounted_hid(); extern uint8_t *driver_prepare_response_hid(); -extern int driver_write_hid(uint8_t, const uint8_t *, size_t); -extern size_t driver_read_hid(uint8_t *, size_t); +extern int driver_write_hid(uint8_t, const uint8_t *, uint16_t); +extern uint16_t driver_read_hid(uint8_t *, uint16_t); extern int driver_process_usb_nopacket_hid(); #endif #ifdef USB_ITF_CCID extern int driver_process_usb_packet_ccid(uint16_t rx_read); -extern void driver_exec_finished_ccid(size_t size_next); -extern void driver_exec_finished_cont_ccid(size_t size_next, size_t offset); +extern void driver_exec_finished_ccid(uint16_t size_next); +extern void driver_exec_finished_cont_ccid(uint16_t size_next, uint16_t offset); extern void driver_exec_timeout_ccid(); extern bool driver_mounted_ccid(); extern uint8_t *driver_prepare_response_ccid(); -extern int driver_write_ccid(const uint8_t *, size_t); -extern size_t driver_read_ccid(uint8_t *, size_t); +extern int driver_write_ccid(const uint8_t *, uint16_t); +extern uint16_t driver_read_ccid(uint8_t *, uint16_t); extern int driver_process_usb_nopacket_ccid(); #endif #ifdef ENABLE_EMULATION extern int driver_process_usb_packet_emul(uint8_t, uint16_t rx_read); -extern void driver_exec_finished_emul(uint8_t, size_t size_next); -extern void driver_exec_finished_cont_emul(uint8_t, size_t size_next, size_t offset); +extern void driver_exec_finished_emul(uint8_t, uint16_t size_next); +extern void driver_exec_finished_cont_emul(uint8_t, uint16_t size_next, uint16_t offset); extern void driver_exec_timeout_emul(uint8_t); extern bool driver_mounted_emul(uint8_t); extern uint8_t *driver_prepare_response_emul(uint8_t); -extern int driver_write_emul(uint8_t, const uint8_t *, size_t); -extern size_t driver_read_emul(uint8_t, uint8_t *, size_t); +extern uint16_t driver_write_emul(uint8_t, const uint8_t *, uint16_t); +extern uint16_t driver_read_emul(uint8_t, uint8_t *, uint16_t); extern int driver_process_usb_nopacket_emul(uint8_t); extern uint16_t emul_read(uint8_t); +#else +extern uint16_t usb_rx(uint8_t itf, const uint8_t *buffer, uint16_t len); #endif -extern size_t usb_rx(uint8_t itf, const uint8_t *buffer, size_t len); - extern void card_start(void (*func)(void)); extern void card_exit(); extern void usb_init(); @@ -111,7 +111,7 @@ extern uint8_t *usb_get_rx(uint8_t itf); extern uint8_t *usb_get_tx(uint8_t itf); extern uint32_t usb_write_offset(uint8_t itf, uint16_t len, uint16_t offset); extern void usb_clear_rx(uint8_t itf); -extern size_t finished_data_size; +extern uint16_t finished_data_size; extern void usb_set_timeout_counter(uint8_t itf, uint32_t v); extern void card_init_core1(); extern uint32_t usb_write_flush(uint8_t itf);