From d62fb7f99a02a80610ccb5233b886c2e260aa8cb Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 6 Nov 2024 16:32:28 +0000 Subject: [PATCH] Add support for Raspberry Pi Pico This adds improved support for the Raspberry Pi Pico range of microcontrollers. Benchmark now compiles, and added support for the RNG functions of the Pico SDK. This gives a ~2x RNG performance improvement on the RP2040 and over 3x improvement on the RP2350. The accelerated SHA256 in the RP2350 unfortunately cannot be used with wolfSSL. --- wolfcrypt/benchmark/benchmark.c | 8 +++ wolfcrypt/src/port/rpi_pico/pico.c | 70 ++++++++++++++++++++++++++ wolfcrypt/src/random.c | 3 +- wolfssl/wolfcrypt/port/rpi_pico/pico.h | 29 +++++++++++ wolfssl/wolfcrypt/settings.h | 3 ++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 wolfcrypt/src/port/rpi_pico/pico.c create mode 100644 wolfssl/wolfcrypt/port/rpi_pico/pico.h diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index a242ad9f2b..fe244b6b68 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -14498,7 +14498,15 @@ void bench_sphincsKeySign(byte level, byte optim) return (double) ticks/TICKS_PER_SECOND; } +#elif defined(WOLFSSL_RPIPICO) + #include "pico/stdlib.h" + double current_time(int reset) + { + (void)reset; + + return (double) time_us_64() / 1000000; + } #elif defined(THREADX) #include "tx_api.h" double current_time(int reset) diff --git a/wolfcrypt/src/port/rpi_pico/pico.c b/wolfcrypt/src/port/rpi_pico/pico.c new file mode 100644 index 0000000000..87abe1599b --- /dev/null +++ b/wolfcrypt/src/port/rpi_pico/pico.c @@ -0,0 +1,70 @@ +/* pico.c + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + + +#include +#include +#include +#include + +#if defined(WOLFSSL_RPIPICO) +#include "pico/rand.h" + + +/* On RP2040 this uses an optimized PRNG, on RP2350 this uses a hardware TRNG. + * There is a 128bit function, but internally this is just 2x 64bit calls. + * Likewise the 32bit call is just a truncated 64bit call, so just stick with + * the 64bit calls. + */ + +int wc_pico_rng_gen_block(unsigned char *output, unsigned int sz) +{ + uint32_t i = 0; + + while (i < sz) + { + uint64_t rnd = get_rand_64(); + if (i + 8 < sz) + { + XMEMCPY(output + i, &rnd, 8); + i += 8; + } else { + XMEMCPY(output + i, &rnd, sz - i); + i = sz; + } + } + + return 0; +} +#endif + +/* Note on RP2350 SHA256: + * Although RP2350 has SHA256 acceleration, we cannot use this. It is because + * we need to get an intermediate result using wc_Sha256GetHash(). The hardware + * will only deal with 64byte packets of data, so to get a result we need to do + * SHA padding. Once the SHA padding is done, it is not in a state to add more + * data. + * The only real workaround would be to cache everything being sent into the + * hardware and replay it as a new instance when trying to get an intermediate + * result. This would not very efficient for an embedded device. + */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 0eda13375c..80afe25af8 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -111,6 +111,8 @@ This library contains implementation for the random number generator. #include #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL) #include "wolfssl/wolfcrypt/port/xilinx/xil-versal-trng.h" +#elif defined(WOLFSSL_RPIPICO) + #include "wolfssl/wolfcrypt/port/rpi_pico/pico.h" #elif defined(NO_DEV_RANDOM) #elif defined(CUSTOM_RAND_GENERATE) #elif defined(CUSTOM_RAND_GENERATE_BLOCK) @@ -2968,7 +2970,6 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) } return RAN_BLOCK_E; } - #elif !defined(WOLFSSL_CAAM) && \ (defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \ defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)) diff --git a/wolfssl/wolfcrypt/port/rpi_pico/pico.h b/wolfssl/wolfcrypt/port/rpi_pico/pico.h new file mode 100644 index 0000000000..98f01bee7c --- /dev/null +++ b/wolfssl/wolfcrypt/port/rpi_pico/pico.h @@ -0,0 +1,29 @@ +/* pico.h + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _WOLFPORT_RPIPICO_H_ +#define _WOLFPORT_RPIPICO_H_ +#if defined(WOLFSSL_RPIPICO) + +WOLFSSL_LOCAL int wc_pico_rng_gen_block(unsigned char* output, unsigned int sz); + +#endif /* WOLFSSL_RPPICO */ +#endif /* _WOLFPORT_RPIPICO_H_ */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 674d21b075..89b3e597ac 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -264,6 +264,9 @@ /* Uncomment next line if using MAXQ108x */ /* #define WOLFSSL_MAXQ108X */ +/* Uncomment next line if using Raspberry Pi RP2040 or RP2350 */ +/* #define WOLFSSL_RPIPICO */ + /* Check PLATFORMIO first, as it may define other known environments. */ #ifdef PLATFORMIO #ifdef ESP_PLATFORM