From a01bd39f2173c8adf3c03e6c529068c81ab46140 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 25 Mar 2022 12:08:48 +0100 Subject: [PATCH] Adding license headers. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 17 ++++ patch_vidpid.sh | 25 ++++- src/fs/file.c | 17 ++++ src/fs/file.h | 18 ++++ src/fs/flash.c | 18 ++++ src/fs/low_flash.c | 60 ++++++----- src/hsm/hsm2040.c | 20 +++- src/hsm/hsm2040.h | 17 +++- src/hsm/sc_hsm.c | 19 +++- src/hsm/sc_hsm.h | 17 ++++ src/hsm/version.h | 17 ++++ src/rng/neug.c | 204 ++++++++++---------------------------- src/rng/neug.h | 35 +++++-- src/rng/random.c | 82 +++++++-------- src/rng/random.h | 23 +++++ src/usb/ccid.h | 23 ++++- src/usb/usb_descriptors.c | 163 +++++++++++++----------------- src/usb/usb_descriptors.h | 31 +++--- 18 files changed, 443 insertions(+), 363 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 72e8a12..79ecbfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,20 @@ + # + # This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + # 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 . + # + cmake_minimum_required(VERSION 3.13) include(pico_sdk_import.cmake) diff --git a/patch_vidpid.sh b/patch_vidpid.sh index b0a2568..9e37e45 100755 --- a/patch_vidpid.sh +++ b/patch_vidpid.sh @@ -1,5 +1,25 @@ #!/bin/bash +# +# This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). +# 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 . +# + +VERSION_MAJOR="1" +VERSION_MINOR="4" + echo "----------------------------" echo "VID/PID patcher for Pico HSM" echo "----------------------------" @@ -64,13 +84,10 @@ if [ "$UF2_FILE_IF" != "$UF2_FILE_OF" ]; then cp -R $UF2_FILE_IF $UF2_FILE_OF fi -BASE_ADDRESS=`xxd "$UF2_FILE_IF" | grep "fffe fdfc 0103 0102 0301" | cut -d " " -f1` -ADDRESS="0x${BASE_ADDRESS%?}" - LITTLE_VID="\x${VID:2:2}\x${VID:0:2}" LITTLE_PID="\x${PID:2:2}\x${PID:0:2}" -printf "$LITTLE_VID$LITTLE_PID" | dd of="$UF2_FILE_OF" bs=1 seek=$(($ADDRESS)) conv=notrunc 2> /dev/null +perl -pi -e "s/\xff\xfe\xfd\xfc\x$VERSION_MINOR\x$VERSION_MAJOR\x01\x02\x03\x01/$LITTLE_VID$LITTLE_PID\x$VERSION_MINOR\x$VERSION_MAJOR\x01\x02\x03\x01/" $UF2_FILE_OF echo "Done!" echo "" diff --git a/src/fs/file.c b/src/fs/file.c index 68c04d3..e79599d 100644 --- a/src/fs/file.c +++ b/src/fs/file.c @@ -1,3 +1,20 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 . + */ + #include "file.h" #include "tusb.h" #include "hsm2040.h" diff --git a/src/fs/file.h b/src/fs/file.h index cc1caa4..c87db66 100644 --- a/src/fs/file.h +++ b/src/fs/file.h @@ -1,3 +1,21 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 _FILE_H_ #define _FILE_H_ diff --git a/src/fs/flash.c b/src/fs/flash.c index 0646ac4..4895eb2 100644 --- a/src/fs/flash.c +++ b/src/fs/flash.c @@ -1,3 +1,21 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 . + */ + + #include #include diff --git a/src/fs/low_flash.c b/src/fs/low_flash.c index 2f06ea7..fe7ca72 100644 --- a/src/fs/low_flash.c +++ b/src/fs/low_flash.c @@ -1,3 +1,21 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 . + */ + + #include #include #include @@ -36,15 +54,11 @@ static bool locked_out = false; //this function has to be called from the core 0 void do_flash() { - if (mutex_try_enter(&mtx_flash, NULL) == true) - { - if (locked_out == true && flash_available == true && ready_pages > 0) - { + if (mutex_try_enter(&mtx_flash, NULL) == true) { + if (locked_out == true && flash_available == true && ready_pages > 0) { //printf(" DO_FLASH AVAILABLE\r\n"); - for (int r = 0; r < TOTAL_FLASH_PAGES; r++) - { - if (flash_pages[r].ready == true) - { + for (int r = 0; r < TOTAL_FLASH_PAGES; r++) { + if (flash_pages[r].ready == true) { //printf("WRITTING %X\r\n",flash_pages[r].address-XIP_BASE); while (multicore_lockout_start_timeout_us(1000) == false); //printf("WRITTING %X\r\n",flash_pages[r].address-XIP_BASE); @@ -58,8 +72,7 @@ void do_flash() flash_pages[r].ready = false; ready_pages--; } - else if (flash_pages[r].erase == true) - { + else if (flash_pages[r].erase == true) { while (multicore_lockout_start_timeout_us(1000) == false); //printf("WRITTING\r\n"); flash_range_erase(flash_pages[r].address-XIP_BASE, flash_pages[r].page_size ? ((int)(flash_pages[r].page_size/FLASH_SECTOR_SIZE))*FLASH_SECTOR_SIZE : FLASH_SECTOR_SIZE); @@ -79,8 +92,7 @@ void do_flash() } //this function has to be called from the core 0 -void low_flash_init() -{ +void low_flash_init() { mutex_init(&mtx_flash); sem_init(&sem_wait, 0, 1); memset(flash_pages, 0, sizeof(page_flash_t)*TOTAL_FLASH_PAGES); @@ -99,8 +111,7 @@ void wait_flash_finish() { sem_acquire_blocking(&sem_wait); //decrease permits } -void low_flash_available() -{ +void low_flash_available() { mutex_enter_blocking(&mtx_flash); flash_available = true; mutex_exit(&mtx_flash); @@ -152,18 +163,15 @@ int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len) { return HSM_OK; } -int flash_program_halfword (uintptr_t addr, uint16_t data) -{ +int flash_program_halfword (uintptr_t addr, uint16_t data) { return flash_program_block(addr, (const uint8_t *)&data, sizeof(uint16_t)); } -int flash_program_word (uintptr_t addr, uint32_t data) -{ +int flash_program_word (uintptr_t addr, uint32_t data) { return flash_program_block(addr, (const uint8_t *)&data, sizeof(uint32_t)); } -int flash_program_uintptr (uintptr_t addr, uintptr_t data) -{ +int flash_program_uintptr (uintptr_t addr, uintptr_t data) { return flash_program_block(addr, (const uint8_t *)&data, sizeof(uintptr_t)); } @@ -205,8 +213,7 @@ uint8_t flash_read_uint8(uintptr_t addr) { return *flash_read(addr); } -int flash_erase_page (uintptr_t addr, size_t page_size) -{ +int flash_erase_page (uintptr_t addr, size_t page_size) { uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE; page_flash_t *p = NULL; @@ -216,8 +223,7 @@ int flash_erase_page (uintptr_t addr, size_t page_size) DEBUG_INFO("ERROR: ALL FLASH PAGES CACHED\r\n"); return HSM_ERR_NO_MEMORY; } - if (!(p = find_free_page(addr))) - { + if (!(p = find_free_page(addr))) { DEBUG_INFO("ERROR: FLASH CANNOT FIND A PAGE (rare error)\r\n"); mutex_exit(&mtx_flash); return HSM_ERR_MEMORY_FATAL; @@ -230,13 +236,13 @@ int flash_erase_page (uintptr_t addr, size_t page_size) return HSM_OK; } -bool flash_check_blank (const uint8_t *p_start, size_t size) +bool flash_check_blank(const uint8_t *p_start, size_t size) { const uint8_t *p; - for (p = p_start; p < p_start + size; p++) + for (p = p_start; p < p_start + size; p++) { if (*p != 0xff) return false; - + } return true; } diff --git a/src/hsm/hsm2040.c b/src/hsm/hsm2040.c index 98780e9..93620a7 100644 --- a/src/hsm/hsm2040.c +++ b/src/hsm/hsm2040.c @@ -1,3 +1,21 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 . + */ + + #include // Pico @@ -283,7 +301,7 @@ static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, vendord_open(rhport, (tusb_desc_interface_t *)itf_vendor, max_len); free(itf_vendor); - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(class_desc_ccid_t) + 2*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(struct ccid_class_descriptor) + 2*sizeof(tusb_desc_endpoint_t); TU_VERIFY(max_len >= drv_len, 0); itf_num = itf_desc->bInterfaceNumber; diff --git a/src/hsm/hsm2040.h b/src/hsm/hsm2040.h index 72bb9a1..3e74ad2 100644 --- a/src/hsm/hsm2040.h +++ b/src/hsm/hsm2040.h @@ -1,7 +1,18 @@ -/** - * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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. * - * SPDX-License-Identifier: BSD-3-Clause + * 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 _HSM2040_H_ diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index acd7da3..8f434eb 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -1,3 +1,20 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 . + */ + #include "sc_hsm.h" #include "file.h" #include "libopensc/card-sc-hsm.h" @@ -197,7 +214,7 @@ static int cmd_select() { } int parse_token_info(const file_t *f, int mode) { - char *label = "PicoHSM"; + char *label = "SmartCard-HSM"; char *manu = "Pol Henarejos"; sc_pkcs15_tokeninfo_t *ti = (sc_pkcs15_tokeninfo_t *)calloc(1, sizeof(sc_pkcs15_tokeninfo_t)); ti->version = HSM_VERSION_MAJOR; diff --git a/src/hsm/sc_hsm.h b/src/hsm/sc_hsm.h index 619acac..d6be562 100644 --- a/src/hsm/sc_hsm.h +++ b/src/hsm/sc_hsm.h @@ -1,3 +1,20 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 _SC_HSM_H_ #define _SC_HSM_H_ diff --git a/src/hsm/version.h b/src/hsm/version.h index 7067e8c..3af0d2f 100644 --- a/src/hsm/version.h +++ b/src/hsm/version.h @@ -1,3 +1,20 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 __VERSION_H_ #define __VERSION_H_ diff --git a/src/rng/neug.c b/src/rng/neug.c index a381f94..dabe713 100644 --- a/src/rng/neug.c +++ b/src/rng/neug.c @@ -1,69 +1,56 @@ -/* - * neug.c - true random number generation +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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. * - * Copyright (C) 2011, 2012, 2013, 2016, 2017, 2018 - * Free Software Initiative of Japan - * Author: NIIBE Yutaka - * - * This file is a part of NeuG, a True Random Number Generator - * implementation based on quantization error of ADC (for STM32F103). - * - * NeuG 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, either version 3 of the License, or - * (at your option) any later version. - * - * NeuG 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 . + * 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 . */ + +//Part of the code is taken from GnuK (GPLv3) + #include #include #include #include "pico/stdlib.h" -//#include #include "neug.h" -//#include "adc.h" #include "hardware/structs/rosc.h" #include "hardware/gpio.h" #include "hardware/adc.h" #include "bsp/board.h" #include "pico/unique_id.h" -void adc_start () -{ +void adc_start() { adc_init(); adc_gpio_init(27); adc_select_input(1); } -void -adc_stop (void) -{ +void adc_stop() { } static uint64_t random_word = 0xcbf29ce484222325; static uint8_t ep_round = 0; -static void ep_init (int mode) -{ +static void ep_init() { random_word = 0xcbf29ce484222325; ep_round = 0; } /* Here, we assume a little endian architecture. */ -static int ep_process (int mode) -{ - if (ep_round == 0) - { - ep_init(mode); +static int ep_process () { + if (ep_round == 0) { + ep_init(); } uint64_t word = 0x0; for (int n = 0; n < 64; n++) { @@ -78,48 +65,34 @@ static int ep_process (int mode) } random_word ^= word^board_millis()^adc_read(); random_word *= 0x00000100000001B3; - if (++ep_round == 8) - { + if (++ep_round == 8) { ep_round = 0; return 2; //2 words } return 0; } -static const uint32_t *ep_output (int mode) -{ - (void) mode; +static const uint32_t *ep_output() { return (uint32_t *)&random_word; } -/* - * Ring buffer, filled by generator, consumed by neug_get routine. - */ struct rng_rb { uint32_t *buf; - //chopstx_mutex_t m; - //chopstx_cond_t data_available; - //chopstx_cond_t space_available; uint8_t head, tail; uint8_t size; unsigned int full :1; unsigned int empty :1; }; -static void rb_init (struct rng_rb *rb, uint32_t *p, uint8_t size) -{ +static void rb_init(struct rng_rb *rb, uint32_t *p, uint8_t size) { rb->buf = p; rb->size = size; - //chopstx_mutex_init (&rb->m); - //chopstx_cond_init (&rb->data_available); - //chopstx_cond_init (&rb->space_available); rb->head = rb->tail = 0; rb->full = 0; rb->empty = 1; } -static void rb_add (struct rng_rb *rb, uint32_t v) -{ +static void rb_add(struct rng_rb *rb, uint32_t v) { rb->buf[rb->tail++] = v; if (rb->tail == rb->size) rb->tail = 0; @@ -128,8 +101,7 @@ static void rb_add (struct rng_rb *rb, uint32_t v) rb->empty = 0; } -static uint32_t rb_del (struct rng_rb *rb) -{ +static uint32_t rb_del(struct rng_rb *rb) { uint32_t v = rb->buf[rb->head++]; if (rb->head == rb->size) @@ -141,140 +113,70 @@ static uint32_t rb_del (struct rng_rb *rb) return v; } -uint8_t neug_mode; -static int rng_should_terminate; - static struct rng_rb the_ring_buffer; -//static chopstx_t rng_thread; - -/** - * @brief Random number generation thread. - */ -void *neug_task () -{ +void *neug_task() { struct rng_rb *rb = &the_ring_buffer; - int mode = neug_mode; + + int n; - rng_should_terminate = 0; - //chopstx_mutex_init (&mode_mtx); - //chopstx_cond_init (&mode_cond); + if ((n = ep_process())) { + int i; + const uint32_t *vp; - //while (!rng_should_terminate) - { - int n; + vp = ep_output(); - if ((n = ep_process (mode))) - { - int i; - const uint32_t *vp; - - vp = ep_output (mode); - - //chopstx_mutex_lock (&rb->m); - //while (rb->full) - //chopstx_cond_wait (&rb->space_available, &rb->m); - - for (i = 0; i < n; i++) - { - rb_add (rb, *vp++); - if (rb->full) - break; - } - - //chopstx_cond_signal (&rb->data_available); - //chopstx_mutex_unlock (&rb->m); - } - } - - //adc_stop (); + for (i = 0; i < n; i++) { + rb_add (rb, *vp++); + if (rb->full) + break; + } + } return NULL; } -/** - * @brief Initialize NeuG. - */ -void neug_init (uint32_t *buf, uint8_t size) -{ +void neug_init(uint32_t *buf, uint8_t size) { pico_unique_board_id_t unique_id; pico_get_unique_board_id(&unique_id); const uint32_t *u = (const uint32_t *)unique_id.id; struct rng_rb *rb = &the_ring_buffer; int i; - - - /* - * This initialization ensures that it generates different sequence - * even if all physical conditions are same. - */ - - neug_mode = NEUG_MODE_CONDITIONED; - rb_init (rb, buf, size); - - /* Enable ADCs */ - adc_start (); - - ep_init (neug_mode); - //rng_thread = chopstx_create (PRIO_RNG, STACK_ADDR_RNG, STACK_SIZE_RNG, - // rng, rb); + rb_init(rb, buf, size); + + adc_start(); + + ep_init(); } -/** - * @breif Flush random bytes. - */ -void neug_flush (void) -{ +void neug_flush(void) { struct rng_rb *rb = &the_ring_buffer; - //chopstx_mutex_lock (&rb->m); while (!rb->empty) rb_del (rb); - //chopstx_cond_signal (&rb->space_available); - //chopstx_mutex_unlock (&rb->m); } - - -/** - * @brief Get random word (32-bit) from NeuG. - * @detail With NEUG_KICK_FILLING, it wakes up RNG thread. - * With NEUG_NO_KICK, it doesn't wake up RNG thread automatically, - * it is needed to call neug_kick_filling later. - */ -uint32_t neug_get (int kick) -{ +uint32_t neug_get(int kick) { struct rng_rb *rb = &the_ring_buffer; uint32_t v; - //chopstx_mutex_lock (&rb->m); while (rb->empty) - neug_task(); //chopstx_cond_wait (&rb->data_available, &rb->m); - v = rb_del (rb); - //if (kick) - //chopstx_cond_signal (&rb->space_available); - //chopstx_mutex_unlock (&rb->m); + neug_task(); + v = rb_del(rb); return v; } -void neug_wait_full (void) //should be called only on core1 -{ +void neug_wait_full(void) { //should be called only on core1 struct rng_rb *rb = &the_ring_buffer; - //chopstx_mutex_lock (&rb->m); while (!rb->full) { - //neug_task(); //chopstx_cond_wait (&rb->data_available, &rb->m); sleep_ms(1); } - //chopstx_mutex_unlock (&rb->m); } -void neug_fini (void) -{ - rng_should_terminate = 1; - neug_get (1); - //chopstx_join (rng_thread, NULL); +void neug_fini(void) { + neug_get(1); } diff --git a/src/rng/neug.h b/src/rng/neug.h index 7479b31..24fe1695 100644 --- a/src/rng/neug.h +++ b/src/rng/neug.h @@ -1,14 +1,29 @@ -#define NEUG_NO_KICK 0 -#define NEUG_KICK_FILLING 1 +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 _NEUG_H_ +#define _NEUG_H_ #define NEUG_PRE_LOOP 32 -#define NEUG_MODE_CONDITIONED 0 /* Conditioned data. */ -#define NEUG_MODE_RAW 1 /* CRC-32 filtered sample data. */ -#define NEUG_MODE_RAW_DATA 2 /* Sample data directly. */ +void neug_init(uint32_t *buf, uint8_t size); +uint32_t neug_get(); +void neug_flush(void); +void neug_wait_full(void); +void neug_fini(void); -void neug_init (uint32_t *buf, uint8_t size); -uint32_t neug_get (int kick); -void neug_flush (void); -void neug_wait_full (void); -void neug_fini (void); +#endif \ No newline at end of file diff --git a/src/rng/random.c b/src/rng/random.c index 34c5e00..e0c08bf 100644 --- a/src/rng/random.c +++ b/src/rng/random.c @@ -1,27 +1,21 @@ -/* - * random.c -- get random bytes +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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. * - * Copyright (C) 2010, 2011, 2012, 2013, 2015 - * Free Software Initiative of Japan - * Author: NIIBE Yutaka - * - * This file is a part of Gnuk, a GnuPG USB Token implementation. - * - * Gnuk 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, either version 3 of the License, or - * (at your option) any later version. - * - * Gnuk 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 . + * 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 . */ + #include #include @@ -30,18 +24,16 @@ #define RANDOM_BYTES_LENGTH 32 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)]; -void random_init (void) -{ +void random_init(void) { int i; - neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t)); + neug_init(random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t)); for (i = 0; i < NEUG_PRE_LOOP; i++) - neug_get (NEUG_KICK_FILLING); + neug_get(); } -void random_fini (void) -{ +void random_fini(void) { neug_fini (); } @@ -50,13 +42,12 @@ void random_fini (void) */ void random_bytes_free (const uint8_t *p); #define MAX_RANDOM_BUFFER 1024 -const uint8_t * random_bytes_get (size_t len) -{ +const uint8_t * random_bytes_get(size_t len) { if (len > MAX_RANDOM_BUFFER) return NULL; static uint32_t return_word[MAX_RANDOM_BUFFER/sizeof(uint32_t)]; for (int ix = 0; ix < len; ix += RANDOM_BYTES_LENGTH) { - neug_wait_full (); + neug_wait_full(); memcpy(return_word+ix/sizeof(uint32_t), random_word, RANDOM_BYTES_LENGTH); random_bytes_free((const uint8_t *)random_word); } @@ -66,53 +57,48 @@ const uint8_t * random_bytes_get (size_t len) /* * Free pointer to random 32-byte */ -void random_bytes_free (const uint8_t *p) -{ +void random_bytes_free(const uint8_t *p) { (void)p; - memset (random_word, 0, RANDOM_BYTES_LENGTH); - neug_flush (); + memset(random_word, 0, RANDOM_BYTES_LENGTH); + neug_flush(); } /* * Return 4-byte salt */ -void random_get_salt (uint8_t *p) -{ +void random_get_salt(uint8_t *p) { uint32_t rnd; - rnd = neug_get (NEUG_KICK_FILLING); - memcpy (p, &rnd, sizeof (uint32_t)); - rnd = neug_get (NEUG_KICK_FILLING); - memcpy (p + sizeof (uint32_t), &rnd, sizeof (uint32_t)); + rnd = neug_get(); + memcpy(p, &rnd, sizeof (uint32_t)); + rnd = neug_get(); + memcpy(p + sizeof (uint32_t), &rnd, sizeof (uint32_t)); } /* * Random byte iterator */ -int random_gen (void *arg, unsigned char *out, size_t out_len) -{ +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; - while (out_len) - { - neug_wait_full (); + while (out_len) { + neug_wait_full(); n = RANDOM_BYTES_LENGTH - index; if (n > out_len) n = out_len; - memcpy (out, ((unsigned char *)random_word) + index, n); + memcpy(out, ((unsigned char *)random_word) + index, n); out += n; out_len -= n; index += n; - if (index >= RANDOM_BYTES_LENGTH) - { + if (index >= RANDOM_BYTES_LENGTH) { index = 0; - neug_flush (); + neug_flush(); } } diff --git a/src/rng/random.h b/src/rng/random.h index 2045583..0bd11ad 100644 --- a/src/rng/random.h +++ b/src/rng/random.h @@ -1,3 +1,24 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 _RANDOM_H_ +#define _RANDOM_H_ + void random_init (void); void random_fini (void); @@ -10,3 +31,5 @@ void random_get_salt (uint8_t *p); /* iterator returning a byta at a time */ int random_gen (void *arg, unsigned char *output, size_t output_len); + +#endif \ No newline at end of file diff --git a/src/usb/ccid.h b/src/usb/ccid.h index cde954b..2c9f950 100644 --- a/src/usb/ccid.h +++ b/src/usb/ccid.h @@ -1,10 +1,27 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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 _CCID_H_ #define _CCID_H_ -#include "ccid-types.h" +#include "libopensc/ccid-types.h" -static const class_desc_ccid_t desc_ccid = { - .bLength = sizeof (class_desc_ccid_t), +static const struct ccid_class_descriptor desc_ccid = { + .bLength = sizeof(struct ccid_class_descriptor), .bDescriptorType = 0x21, .bcdCCID = (0x0110), .bMaxSlotIndex = 0, diff --git a/src/usb/usb_descriptors.c b/src/usb/usb_descriptors.c index d5264bb..49d021f 100644 --- a/src/usb/usb_descriptors.c +++ b/src/usb/usb_descriptors.c @@ -1,26 +1,18 @@ /* - * The MIT License (MIT) + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * 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. * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * 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 . */ #include "tusb.h" @@ -29,12 +21,6 @@ #include "pico/unique_id.h" #include "version.h" -/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. - * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. - * - * Auto ProductID layout's Bitmap: - * [MSB] MIDI | HID | MSC | CDC [LSB] - */ #ifndef USB_VID #define USB_VID 0xFEFF @@ -59,8 +45,6 @@ tusb_desc_device_t const desc_device = .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = (USB_BCD), - // Use Interface Association Descriptor (IAD) for CDC - // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = 0x00, .bDeviceSubClass = 0, .bDeviceProtocol = 0, @@ -77,11 +61,9 @@ tusb_desc_device_t const desc_device = .bNumConfigurations = 1 }; -// Invoked when received GET DEVICE DESCRIPTOR -// Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { - return (uint8_t const *) &desc_device; + return (uint8_t const *) &desc_device; } tusb_desc_interface_t const desc_interface = @@ -105,7 +87,7 @@ tusb_desc_configuration_t const desc_config = { .bLength = sizeof(tusb_desc_configuration_t), .bDescriptorType = TUSB_DESC_CONFIGURATION, - .wTotalLength = (sizeof(tusb_desc_configuration_t) + sizeof(tusb_desc_interface_t) + sizeof(class_desc_ccid_t) + 2*sizeof(tusb_desc_endpoint_t)), + .wTotalLength = (sizeof(tusb_desc_configuration_t) + sizeof(tusb_desc_interface_t) + sizeof(struct ccid_class_descriptor) + 2*sizeof(tusb_desc_endpoint_t)), .bNumInterfaces = 1, .bConfigurationValue = 1, .iConfiguration = 4, @@ -133,46 +115,39 @@ tusb_desc_endpoint_t const desc_ep2 = .bInterval = 0 }; - -// Invoked when received GET CONFIGURATION DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete - - -static uint8_t desc_config_extended[sizeof(tusb_desc_configuration_t) + sizeof(tusb_desc_interface_t) + sizeof(class_desc_ccid_t) + 2*sizeof(tusb_desc_endpoint_t)]; +static uint8_t desc_config_extended[sizeof(tusb_desc_configuration_t) + sizeof(tusb_desc_interface_t) + sizeof(struct ccid_class_descriptor) + 2*sizeof(tusb_desc_endpoint_t)]; uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { - (void) index; // for multiple configurations + (void) index; // for multiple configurations - static uint8_t initd = 0; - if (initd == 0) - { - uint8_t *p = desc_config_extended; - memcpy(p, &desc_config, sizeof(tusb_desc_configuration_t)); p += sizeof(tusb_desc_configuration_t); - memcpy(p, &desc_interface, sizeof(tusb_desc_interface_t)); p += sizeof(tusb_desc_interface_t); - memcpy(p, &desc_ccid, sizeof(class_desc_ccid_t)); p += sizeof(class_desc_ccid_t); - memcpy(p, &desc_ep1, sizeof(tusb_desc_endpoint_t)); p += sizeof(tusb_desc_endpoint_t); - memcpy(p, &desc_ep2, sizeof(tusb_desc_endpoint_t)); p += sizeof(tusb_desc_endpoint_t); - initd = 1; - } - return (const uint8_t *)desc_config_extended; + static uint8_t initd = 0; + if (initd == 0) + { + uint8_t *p = desc_config_extended; + memcpy(p, &desc_config, sizeof(tusb_desc_configuration_t)); p += sizeof(tusb_desc_configuration_t); + memcpy(p, &desc_interface, sizeof(tusb_desc_interface_t)); p += sizeof(tusb_desc_interface_t); + memcpy(p, &desc_ccid, sizeof(struct ccid_class_descriptor)); p += sizeof(struct ccid_class_descriptor); + memcpy(p, &desc_ep1, sizeof(tusb_desc_endpoint_t)); p += sizeof(tusb_desc_endpoint_t); + memcpy(p, &desc_ep2, sizeof(tusb_desc_endpoint_t)); p += sizeof(tusb_desc_endpoint_t); + initd = 1; + } + return (const uint8_t *)desc_config_extended; } #define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN) #define MS_OS_20_DESC_LEN 0xB2 -// BOS Descriptor is required for webUSB uint8_t const desc_bos[] = { - // total length, number of device caps - TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2) + // total length, number of device caps + TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2) }; uint8_t const * tud_descriptor_bos_cb(void) { - return desc_bos; + return desc_bos; } //--------------------------------------------------------------------+ @@ -182,57 +157,53 @@ uint8_t const * tud_descriptor_bos_cb(void) // array of pointer to string descriptors char const* string_desc_arr [] = { - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "Pol Henarejos", // 1: Manufacturer - "Pico HSM", // 2: Product - "11223344", // 3: Serials, should use chip ID - "Pico HSM Config", // 4: Vendor Interface - "Pico HSM Interface" + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "Pol Henarejos", // 1: Manufacturer + "Pico HSM", // 2: Product + "11223344", // 3: Serials, should use chip ID + "Pico HSM Config", // 4: Vendor Interface + "Pico HSM Interface" }; static uint16_t _desc_str[32]; -// Invoked when received GET STRING DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; + (void) langid; - uint8_t chr_count; + uint8_t chr_count; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. - // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + if (index == 0) { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } + else { + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) + return NULL; - const char* str = string_desc_arr[index]; - char unique_id_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1]; - if (index == 3) { - pico_unique_board_id_t unique_id; - pico_get_unique_board_id(&unique_id); - pico_get_unique_board_id_string(unique_id_str, 2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1); - str = unique_id_str; + const char* str = string_desc_arr[index]; + char unique_id_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1]; + if (index == 3) { + pico_unique_board_id_t unique_id; + pico_get_unique_board_id(&unique_id); + pico_get_unique_board_id_string(unique_id_str, 2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1); + str = unique_id_str; + } + + chr_count = strlen(str); + if ( chr_count > 31 ) + chr_count = 31; + + // Convert ASCII string into UTF-16 + for(uint8_t i=0; i 31 ) chr_count = 31; + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); - // Convert ASCII string into UTF-16 - for(uint8_t i=0; i. */ #ifndef USB_DESCRIPTORS_H_