diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index a242ad9f2..fe244b6b6 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/include.am b/wolfcrypt/src/include.am index 4cb5d30c1..b1fa3566f 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -147,7 +147,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/cypress/psoc6_crypto.c \ wolfcrypt/src/port/liboqs/liboqs.c \ wolfcrypt/src/port/maxim/max3266x.c \ - wolfcrypt/src/ASN_TEMPLATE.md + wolfcrypt/src/ASN_TEMPLATE.md \ + wolfcrypt/src/port/rpi_pico/pico.c \ + wolfcrypt/src/port/rpi_pico/README.md $(ASYNC_FILES): $(AM_V_at)touch $(srcdir)/$@ diff --git a/wolfcrypt/src/port/rpi_pico/README.md b/wolfcrypt/src/port/rpi_pico/README.md new file mode 100644 index 000000000..240cc9782 --- /dev/null +++ b/wolfcrypt/src/port/rpi_pico/README.md @@ -0,0 +1,72 @@ +# wolfSSL Raspberry Pi Pico Acceleration + +wolfSSL supports RNG acceleration on the Raspberry Pi RP2040 and RP2350 +microcontrollers. Everything here assumes you are using the standard [Raspberry +Pi Pico SDK](https://github.com/raspberrypi/pico-sdk). + +It has only been tested with the ARM cores of the RP2350, not the RISC-V cores. + +## RNG Acceleration + +The Pico SDK has RNG functions for both the RP2040 and RP2350. In the RP2040 +this is an optimised PRNG method, in the RP2350 it uses a built-in TRNG. The +same API is used for both. + +## Compiling wolfSSL + +In your `user_settings.h`, you should set the following to add support in +wolfSSL: + +```c +#define WOLFSSL_RPIPICO +``` + +Then for an RP2040, enable the ARM Thumb instructions: + +```c +#define WOLFSSL_SP_ARM_THUMB_ASM +``` + +or for an RP2350, the Cortex-M instructions should be used: + +```c +#define WOLFSSL_SP_ARM_CORTEX_M_ASM +``` + +To enable the RNG acceleration add the following: + +```c +#define WC_NO_HASHDRBG +#define CUSTOM_RAND_GENERATE_BLOCK wc_pico_rng_gen_block +``` + +In CMake you should add the following linking to both wolfSSL and the end +application: + +```cmake +target_link_libraries(wolfssl + pico_stdlib + pico_rand +) +``` + +A full example can be found in the +[`RPi-Pico`](https://github.com/wolfSSL/wolfssl-examples/tree/master/RPi-Pico) +directory of the +[`wolfssl-examples`](https://github.com/wolfSSL/wolfssl-examples) GitHub +repository. + +## 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. + +## Support + +For questions please email support@wolfssl.com diff --git a/wolfcrypt/src/port/rpi_pico/pico.c b/wolfcrypt/src/port/rpi_pico/pico.c new file mode 100644 index 000000000..454eab53f --- /dev/null +++ b/wolfcrypt/src/port/rpi_pico/pico.c @@ -0,0 +1,59 @@ +/* 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 diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 0eda13375..80afe25af 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/include.am b/wolfssl/wolfcrypt/include.am index 1ccb8426f..394631414 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -119,7 +119,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h \ wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h \ wolfssl/wolfcrypt/port/maxim/max3266x.h \ - wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h + wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h \ + wolfssl/wolfcrypt/port/rpi_pico/pico.h if BUILD_CRYPTOAUTHLIB nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h diff --git a/wolfssl/wolfcrypt/port/rpi_pico/pico.h b/wolfssl/wolfcrypt/port/rpi_pico/pico.h new file mode 100644 index 000000000..98f01bee7 --- /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 c71ac8819..4db07866e 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