mirror of
https://github.com/librekeys/pico-keys-sdk.git
synced 2026-07-28 08:01:51 -07:00
Compare commits
16
Commits
+14
-14
@@ -26,7 +26,7 @@ else()
|
||||
include(pico_sdk_import.cmake)
|
||||
endif()
|
||||
|
||||
project(picokey C CXX ASM)
|
||||
project(pico_rescue C CXX ASM)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
@@ -38,7 +38,7 @@ else()
|
||||
add_definitions(-D__FOR_CI)
|
||||
endif()
|
||||
|
||||
add_executable(picokey)
|
||||
add_executable(pico_rescue)
|
||||
endif()
|
||||
|
||||
set(USB_ITF_CCID 1)
|
||||
@@ -53,48 +53,48 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/version.c
|
||||
)
|
||||
|
||||
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/pico_keys_version.h" 2)
|
||||
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/pico_keys_version.h" 3)
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
project(picokey)
|
||||
project(pico_rescue)
|
||||
endif()
|
||||
|
||||
if(NOT ESP_PLATFORM)
|
||||
target_sources(picokey PUBLIC ${SOURCES})
|
||||
target_include_directories(picokey PUBLIC ${INCLUDES})
|
||||
target_sources(pico_rescue PUBLIC ${SOURCES})
|
||||
target_include_directories(pico_rescue PUBLIC ${INCLUDES})
|
||||
|
||||
target_compile_options(picokey PUBLIC
|
||||
target_compile_options(pico_rescue PUBLIC
|
||||
-Wall
|
||||
)
|
||||
if(NOT MSVC)
|
||||
target_compile_options(picokey PUBLIC
|
||||
target_compile_options(pico_rescue PUBLIC
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_EMULATION)
|
||||
if(NOT MSVC)
|
||||
target_compile_options(picokey PUBLIC
|
||||
target_compile_options(pico_rescue PUBLIC
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
)
|
||||
endif()
|
||||
if(APPLE)
|
||||
target_link_options(picokey PUBLIC
|
||||
target_link_options(pico_rescue PUBLIC
|
||||
-Wl,-dead_strip
|
||||
)
|
||||
elseif(MSVC)
|
||||
target_compile_options(picokey PUBLIC
|
||||
target_compile_options(pico_rescue PUBLIC
|
||||
-WX
|
||||
)
|
||||
|
||||
target_link_libraries(picokey PUBLIC wsock32 ws2_32 Bcrypt)
|
||||
target_link_libraries(pico_rescue PUBLIC wsock32 ws2_32 Bcrypt)
|
||||
else()
|
||||
target_link_options(picokey PUBLIC
|
||||
target_link_options(pico_rescue PUBLIC
|
||||
-Wl,--gc-sections
|
||||
)
|
||||
endif(APPLE)
|
||||
target_link_libraries(picokey PRIVATE pthread m)
|
||||
target_link_libraries(pico_rescue PRIVATE pthread m)
|
||||
else()
|
||||
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
Unless stated otherwise at the top of a file, all the files of this
|
||||
project are licensed under the GNU Affero General Public License v3
|
||||
(AGPLv3). The full text of this license is reproduced at the bottom of
|
||||
this document.
|
||||
The copyright holders are indicated at the top of each file.
|
||||
|
||||
The project is using the following libraries, sdk or portions of code:
|
||||
- mdebtls, licensed under Apache-2.0 and GPL-2.0-or-later licenses,
|
||||
https://github.com/Mbed-TLS/mbedtls
|
||||
- tinyUSB, licensed under the MIT License,
|
||||
https://github.com/hathach/tinyusb
|
||||
- tinycbor, licensed under the MIT license,
|
||||
https://github.com/intel/tinycbor
|
||||
- mlkem-native, the Apache-2.0 license OR the ISC license OR the MIT
|
||||
license, https://github.com/pq-code-package/mlkem-native
|
||||
- USB CCID from Raspberry Pi (Trading) Ltd, licensed under the BSD
|
||||
license,
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
@@ -658,4 +678,4 @@ specific requirements.
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Pico Keys SDK
|
||||
This is a fork of the community edition of the project located at https://github.com/polhenarejos/pico-keys-sdk
|
||||
|
||||
For licensing information and credits, see the LICENSE file
|
||||
+19
-4
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"partitions": [
|
||||
{
|
||||
"name": "Pico Keys Firmware",
|
||||
"name": "PicoKeys Firmware",
|
||||
"id": 0,
|
||||
"start": 0,
|
||||
"size": "1024K",
|
||||
@@ -22,10 +22,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Pico Keys Data",
|
||||
"name": "PicoKeys Data",
|
||||
"id": 1,
|
||||
"start": "1024K",
|
||||
"size": "3072K",
|
||||
"start": "1032K",
|
||||
"size": "3064K",
|
||||
"families": ["data"],
|
||||
"permissions": {
|
||||
"secure": "rw",
|
||||
@@ -35,6 +35,21 @@
|
||||
"link": ["owner", 0],
|
||||
"ignored_during_arm_boot": true,
|
||||
"ignored_during_riscv_boot": true
|
||||
},
|
||||
{
|
||||
"name": "PicoKeys Binding",
|
||||
"id": 2,
|
||||
"start": "1024K",
|
||||
"size": "8K",
|
||||
"families": ["data"],
|
||||
"permissions": {
|
||||
"secure": "r",
|
||||
"nonsecure": "",
|
||||
"bootloader": "w"
|
||||
},
|
||||
"link": ["owner", 0],
|
||||
"ignored_during_arm_boot": true,
|
||||
"ignored_during_riscv_boot": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -64,12 +64,12 @@ if(ESP_PLATFORM)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED USB_VID)
|
||||
set(USB_VID 0x2E8A)
|
||||
set(USB_VID 0x1D50)
|
||||
endif()
|
||||
add_definitions(-DUSB_VID=${USB_VID})
|
||||
|
||||
if(NOT DEFINED USB_PID)
|
||||
set(USB_PID 0x10FD)
|
||||
set(USB_PID 0x619B)
|
||||
endif()
|
||||
add_definitions(-DUSB_PID=${USB_PID})
|
||||
|
||||
@@ -126,7 +126,7 @@ if(NOT ESP_PLATFORM)
|
||||
)
|
||||
|
||||
if(ENABLE_EDDSA)
|
||||
set(MBEDTLS_ORIGIN "https://github.com/polhenarejos/mbedtls.git")
|
||||
set(MBEDTLS_ORIGIN "https://github.com/librekeys/mbedtls.git")
|
||||
set(MBEDTLS_REF "mbedtls-3.6-eddsa")
|
||||
|
||||
execute_process(
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ uint8_t *rdata_gr = NULL;
|
||||
uint16_t rdata_bk = 0x0;
|
||||
extern uint32_t timeout;
|
||||
bool is_chaining = false;
|
||||
uint8_t chain_buf[4096];
|
||||
uint8_t chain_buf[2038];
|
||||
uint8_t *chain_ptr = NULL;
|
||||
|
||||
int process_apdu() {
|
||||
|
||||
@@ -278,3 +278,16 @@ mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_
|
||||
}
|
||||
return MBEDTLS_ECP_DP_NONE;
|
||||
}
|
||||
|
||||
#define POLY 0xedb88320
|
||||
|
||||
uint32_t crc32c(const uint8_t *buf, size_t len) {
|
||||
uint32_t crc = 0xffffffff;
|
||||
while (len--) {
|
||||
crc ^= *buf++;
|
||||
for (int k = 0; k < 8; k++) {
|
||||
crc = (crc >> 1) ^ (POLY & (0 - (crc & 1)));
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
@@ -56,5 +56,6 @@ extern int aes_decrypt(const uint8_t *key, const uint8_t *iv, uint16_t key_size,
|
||||
extern int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len);
|
||||
extern int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len);
|
||||
extern mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len);
|
||||
extern uint32_t crc32c(const uint8_t *buf, size_t len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include <string.h>
|
||||
#include "crypto_utils.h"
|
||||
#ifdef PICO_PLATFORM
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/flash.h"
|
||||
@@ -158,8 +159,14 @@ void do_flash() {
|
||||
sem_release(&sem_flash);
|
||||
}
|
||||
|
||||
#ifdef PICO_RP2040
|
||||
void phymarker_write();
|
||||
#endif
|
||||
//this function has to be called from the core 0
|
||||
void low_flash_init() {
|
||||
#ifdef PICO_RP2040
|
||||
phymarker_write();
|
||||
#endif
|
||||
memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES);
|
||||
mutex_init(&mtx_flash);
|
||||
sem_init(&sem_flash, 0, 1);
|
||||
@@ -371,3 +378,42 @@ bool flash_check_blank(const uint8_t *p_start, size_t size) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef PICO_RP2040
|
||||
typedef struct {
|
||||
uint64_t magic;
|
||||
uint16_t version;
|
||||
uint16_t flags;
|
||||
uint8_t uid[PICO_UNIQUE_BOARD_ID_SIZE_BYTES];
|
||||
uint32_t crc32;
|
||||
} __attribute__ ((packed)) phymarker_t;
|
||||
|
||||
uintptr_t __phymarker_start = (uintptr_t)0x10100000;
|
||||
|
||||
const uint64_t PHYSICAL_MARKER_MAGIC = 0x5049434F4B455953ULL; // "PICOKEYS"
|
||||
|
||||
void phymarker_write() {
|
||||
const uint64_t magic = *(uint64_t *)__phymarker_start;
|
||||
if (magic == PHYSICAL_MARKER_MAGIC) {
|
||||
return;
|
||||
}
|
||||
phymarker_t pm = {
|
||||
.magic = PHYSICAL_MARKER_MAGIC, // "PICOKEYS"
|
||||
.version = 0x0001,
|
||||
.flags = 0x0000,
|
||||
.crc32 = 0x00000000
|
||||
};
|
||||
memcpy(pm.uid, pico_serial.id, PICO_UNIQUE_BOARD_ID_SIZE_BYTES);
|
||||
pm.crc32 = crc32c((const uint8_t *)&pm, sizeof(phymarker_t) - sizeof(uint32_t));
|
||||
|
||||
uint8_t buf[FLASH_PAGE_SIZE] = {0};
|
||||
memcpy(buf, &pm, sizeof(phymarker_t));
|
||||
uint32_t ints = save_and_disable_interrupts();
|
||||
|
||||
flash_range_erase((uint32_t)__phymarker_start - XIP_BASE, FLASH_SECTOR_SIZE);
|
||||
flash_range_program((uint32_t)__phymarker_start - XIP_BASE, (const uint8_t *)buf, sizeof(buf));
|
||||
|
||||
restore_interrupts(ints);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -235,6 +235,11 @@ bool wait_button() {
|
||||
req_button_pending = false;
|
||||
return timeout || cancel_button;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int picokey_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool set_rtc = false;
|
||||
@@ -393,6 +398,10 @@ int main(void) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
picokey_init();
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
xTaskCreatePinnedToCore(core0_loop, "core0", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, ESP32_CORE0);
|
||||
#else
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef __VERSION_H_
|
||||
#define __VERSION_H_
|
||||
|
||||
#define PICO_KEYS_SDK_VERSION 0x0804
|
||||
#define PICO_KEYS_SDK_VERSION 0x0805
|
||||
|
||||
#define PICO_KEYS_SDK_VERSION_MAJOR ((PICO_KEYS_SDK_VERSION >> 8) & 0xff)
|
||||
#define PICO_KEYS_SDK_VERSION_MINOR (PICO_KEYS_SDK_VERSION & 0xff)
|
||||
|
||||
+69
-20
@@ -22,6 +22,7 @@
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "random.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
#ifdef PICO_PLATFORM
|
||||
extern char __flash_binary_start;
|
||||
@@ -46,6 +47,8 @@ const uint8_t rescue_aid[] = {
|
||||
#define PICO_MCU 0
|
||||
#endif
|
||||
|
||||
#define EF_DEVCERT_KEY 0xE0C1
|
||||
|
||||
extern uint8_t PICO_PRODUCT;
|
||||
extern uint8_t PICO_VERSION_MAJOR;
|
||||
extern uint8_t PICO_VERSION_MINOR;
|
||||
@@ -75,30 +78,69 @@ int rescue_unload() {
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id ec_id) {
|
||||
file_t *ef_devcert_key = file_new(EF_DEVCERT_KEY);
|
||||
if (!ef_devcert_key) {
|
||||
return SW_FILE_NOT_FOUND();
|
||||
}
|
||||
uint8_t kbase[32] = {0};
|
||||
derive_kbase(kbase);
|
||||
if (file_has_data(ef_devcert_key)) {
|
||||
uint8_t pkey[32] = {0};
|
||||
memcpy(pkey, file_get_data(ef_devcert_key), 32);
|
||||
aes_decrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32);
|
||||
int ret = mbedtls_ecp_read_key(ec_id, ecp, pkey, 32);
|
||||
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
||||
if (ret != 0) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Generate new key
|
||||
uint8_t pkey[MBEDTLS_ECP_MAX_BYTES] = {0};
|
||||
size_t olen = 0;
|
||||
mbedtls_ecp_gen_key(ec_id, ecp, random_gen, NULL);
|
||||
mbedtls_ecp_write_key_ext(ecp, &olen, pkey, sizeof(pkey));
|
||||
|
||||
aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32);
|
||||
file_put_data(ef_devcert_key, pkey, (uint16_t)olen);
|
||||
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
||||
low_flash_available();
|
||||
}
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
int cmd_keydev_sign() {
|
||||
uint8_t p1 = P1(apdu);
|
||||
if (p1 == 0x01) {
|
||||
if (apdu.nc != 32) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
mbedtls_ecp_keypair ecp;
|
||||
mbedtls_ecp_keypair_init(&ecp);
|
||||
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
|
||||
if (!otp_key_2) {
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
int ret = load_internal_keydev(&ecp, ec_id);
|
||||
if (ret != PICOKEY_OK) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
mbedtls_ecdsa_context ecdsa;
|
||||
mbedtls_ecdsa_init(&ecdsa);
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecdsa, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
return SW_EXEC_ERROR();
|
||||
else {
|
||||
int ret = mbedtls_ecp_read_key(ec_id, &ecp, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(MBEDTLS_ECP_DP_SECP256K1)->bit_size + 7) / 8);
|
||||
uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(ec_id)->bit_size + 7) / 8);
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
ret = mbedtls_ecdsa_sign(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL);
|
||||
int ret = mbedtls_ecdsa_sign(&ecp.MBEDTLS_PRIVATE(grp), &r, &s, &ecp.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
return SW_EXEC_ERROR();
|
||||
@@ -106,32 +148,39 @@ int cmd_keydev_sign() {
|
||||
|
||||
mbedtls_mpi_write_binary(&r, res_APDU, key_size / 2); res_APDU_size = key_size / 2;
|
||||
mbedtls_mpi_write_binary(&s, res_APDU + res_APDU_size, key_size / 2); res_APDU_size += key_size / 2;
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
}
|
||||
else if (p1 == 0x02) {
|
||||
// Return public key
|
||||
if (!otp_key_2) {
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
}
|
||||
if (apdu.nc != 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
mbedtls_ecp_keypair ecp;
|
||||
mbedtls_ecp_keypair_init(&ecp);
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecp, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
|
||||
if (!otp_key_2) {
|
||||
int ret = load_internal_keydev(&ecp, ec_id);
|
||||
if (ret != PICOKEY_OK) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL);
|
||||
else {
|
||||
int ret = mbedtls_ecp_read_key(ec_id, &ecp, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
int ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
size_t olen = 0;
|
||||
ret = mbedtls_ecp_point_write_binary(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 4096);
|
||||
ret = mbedtls_ecp_point_write_binary(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 2038);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
#include "usb.h"
|
||||
|
||||
#ifndef USB_VID
|
||||
#define USB_VID 0x2E8A
|
||||
#define USB_VID 0x1D50
|
||||
#endif
|
||||
#ifndef USB_PID
|
||||
#define USB_PID 0x10FD
|
||||
#define USB_PID 0x619B
|
||||
#endif
|
||||
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
@@ -214,7 +214,7 @@ enum
|
||||
VENDOR_REQUEST_WEBUSB = 1,
|
||||
VENDOR_REQUEST_MICROSOFT = 2
|
||||
};
|
||||
#define URL "www.picokeys.com"
|
||||
#define URL "www.librekeys.org"
|
||||
static bool web_serial_connected = false;
|
||||
|
||||
const tusb_desc_webusb_url_t desc_url =
|
||||
@@ -318,11 +318,11 @@ uint8_t const *tud_descriptor_bos_cb(void) {
|
||||
// array of pointer to string descriptors
|
||||
char *string_desc_itf[4] = {0};
|
||||
char const *string_desc_arr [] = {
|
||||
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||
"Pol Henarejos", // 1: Manufacturer
|
||||
"Pico Key", // 2: Product
|
||||
"11223344", // 3: Serials, should use chip ID
|
||||
"Config" // 4: Vendor Interface
|
||||
(const char[]) { 0x09, 0x04 }, // 0: Supported language : English (0x0409)
|
||||
"LibreKeys", // 1: Manufacturer
|
||||
"One", // 2: Product
|
||||
"11223344", // 3: Serials, should use chip ID
|
||||
"Config" // 4: Vendor Interfaces
|
||||
, "HID Interface"
|
||||
, "HID Keyboard Interface"
|
||||
, "CCID OTP FIDO Interface"
|
||||
|
||||
Reference in New Issue
Block a user