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 <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2024-01-01 01:54:49 +01:00
parent adf53b4231
commit a9dc6fd7f8
22 changed files with 681 additions and 269 deletions

View file

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

View file

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

View file

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

View file

@ -21,6 +21,8 @@
#include <stdlib.h>
#ifndef ENABLE_EMULATION
#include "pico/stdlib.h"
#else
#include "compat.h"
#endif
#include <stdio.h>
#include <inttypes.h>
@ -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

View file

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

View file

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

52
src/compat.h Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -25,9 +25,10 @@
#else
#include <stdbool.h>
#include <stdint.h>
#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);

View file

@ -28,8 +28,19 @@
#include "pico/sem.h"
#include "pico/multicore.h"
#else
#ifdef _MSC_VER
#include <windows.h>
#include <io.h>
#define O_RDWR _O_RDWR
#define open _open
#define write _write
#define mode_t unsigned short
#define lseek _lseek
#include "mman.h"
#else
#include <unistd.h>
#include <sys/mman.h>
#endif
#include <fcntl.h>
#define FLASH_SECTOR_SIZE 4096
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)

184
src/fs/mman.c Normal file
View file

@ -0,0 +1,184 @@
#include <windows.h>
#include <errno.h>
#include <io.h>
#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;
}

55
src/fs/mman.h Normal file
View file

@ -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 <sys/types.h>
#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_ */

View file

@ -21,7 +21,9 @@
#ifndef ENABLE_EMULATION
#include "pico/stdlib.h"
#else
#if !defined(_MSC_VER)
#include <sys/time.h>
#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 <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
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() {

View file

@ -24,15 +24,27 @@
#else
#include <stdint.h>
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 <string.h>
extern bool wait_button();

View file

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

View file

@ -17,31 +17,45 @@
#include "emulation.h"
#include <stdio.h>
#ifndef _MSC_VER
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <poll.h>
#include <netinet/tcp.h>
typedef int socket_t;
#include <fcntl.h>
#define INVALID_SOCKET (-1)
#define SOCKET_ERROR (-1)
#else
#include <ws2tcpip.h>
#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 <stdlib.h>
#include <errno.h>
#include <time.h>
#include "pico_keys.h"
#include "apdu.h"
#include "usb.h"
#include "ccid/ccid.h"
#include <netinet/tcp.h>
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);
}

View file

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

View file

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