From 755c385b1ffde972ecc3b24331824e5996761fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Thu, 30 Nov 2023 10:57:06 +0100 Subject: [PATCH] Liboqs: use WolfSSL RNG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve the interface to liboqs by properly configuring and using the RNG provided by WolfSSL from within liboqs. Signed-off-by: Tobias Frauenschläger --- cmake/functions.cmake | 6 ++ src/include.am | 1 + wolfcrypt/src/ext_kyber.c | 11 ++- wolfcrypt/src/include.am | 3 +- wolfcrypt/src/port/liboqs/liboqs.c | 111 +++++++++++++++++++++++++ wolfcrypt/src/wc_port.c | 10 +++ wolfssl/wolfcrypt/include.am | 3 +- wolfssl/wolfcrypt/port/liboqs/liboqs.h | 60 +++++++++++++ zephyr/CMakeLists.txt | 1 + 9 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 wolfcrypt/src/port/liboqs/liboqs.c create mode 100644 wolfssl/wolfcrypt/port/liboqs/liboqs.h diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 6b5b9a7f9..a8f0c851d 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -198,6 +198,7 @@ function(generate_build_flags) set(BUILD_SPHINCS "yes" PARENT_SCOPE) set(BUILD_DILITHIUM "yes" PARENT_SCOPE) set(BUILD_EXT_KYBER "yes" PARENT_SCOPE) + set(BUILD_OQS_HELPER "yes" PARENT_SCOPE) endif() if(WOLFSSL_ARIA OR WOLFSSL_USER_SETTINGS) message(STATUS "ARIA functions.cmake found WOLFSSL_ARIA") @@ -587,6 +588,11 @@ function(generate_lib_src_list LIB_SOURCES) wolfcrypt/src/wc_port.c wolfcrypt/src/error.c) + if(BUILD_OQS_HELPER) + list(APPEND LIB_SOURCES + wolfcrypt/src/port/liboqs/liboqs.c) + endif() + if(BUILD_ARIA) list(APPEND LIB_SOURCES wolfcrypt/src/port/aria/aria-crypt.c diff --git a/src/include.am b/src/include.am index a69822fff..aa1885ef3 100644 --- a/src/include.am +++ b/src/include.am @@ -835,6 +835,7 @@ src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/falcon.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/dilithium.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sphincs.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/ext_kyber.c +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/liboqs/liboqs.c endif if BUILD_LIBLMS diff --git a/wolfcrypt/src/ext_kyber.c b/wolfcrypt/src/ext_kyber.c index 834d98903..ea2ac83b1 100644 --- a/wolfcrypt/src/ext_kyber.c +++ b/wolfcrypt/src/ext_kyber.c @@ -39,6 +39,8 @@ #if defined (HAVE_LIBOQS) +#include + static const char* OQS_ID2name(int id) { switch (id) { case KYBER_LEVEL1: return OQS_KEM_alg_kyber_512; @@ -337,12 +339,16 @@ int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng) ret = BAD_FUNC_ARG; } } + if (ret == 0) { + ret = wolfSSL_liboqsRngMutexLock(rng); + } if (ret == 0) { if (OQS_KEM_keypair(kem, key->pub, key->priv) != OQS_SUCCESS) { ret = BAD_FUNC_ARG; } } + wolfSSL_liboqsRngMutexUnlock(); OQS_KEM_free(kem); #endif /* HAVE_LIBOQS */ #ifdef HAVE_PQM4 @@ -422,12 +428,15 @@ int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss, ret = BAD_FUNC_ARG; } } + if (ret == 0) { + ret = wolfSSL_liboqsRngMutexLock(rng); + } if (ret == 0) { if (OQS_KEM_encaps(kem, ct, ss, key->pub) != OQS_SUCCESS) { ret = BAD_FUNC_ARG; } } - + wolfSSL_liboqsRngMutexUnlock(); OQS_KEM_free(kem); #endif /* HAVE_LIBOQS */ #ifdef HAVE_PQM4 diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 2a501411f..b944c4258 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -132,7 +132,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c \ wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c \ wolfcrypt/src/port/Renesas/README.md \ - wolfcrypt/src/port/cypress/psoc6_crypto.c + wolfcrypt/src/port/cypress/psoc6_crypto.c \ + wolfcrypt/src/port/liboqs/liboqs.c $(ASYNC_FILES): $(AM_V_at)touch $(srcdir)/$@ diff --git a/wolfcrypt/src/port/liboqs/liboqs.c b/wolfcrypt/src/port/liboqs/liboqs.c new file mode 100644 index 000000000..9fcd6c57d --- /dev/null +++ b/wolfcrypt/src/port/liboqs/liboqs.c @@ -0,0 +1,111 @@ +/* liboqs.c + * + * Copyright (C) 2006-2023 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 + */ + +/* + +DESCRIPTION +This library provides the support interfaces to the liboqs library providing +implementations for Post-Quantum cryptography algorithms. + +*/ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include + +#include + +#if defined(HAVE_LIBOQS) + +/* RNG for liboqs */ +static WC_RNG liboqsDefaultRNG; +static WC_RNG* liboqsCurrentRNG; + +static wolfSSL_Mutex liboqsRNGMutex; + +static int liboqs_init = 0; + + +static void wolfSSL_liboqsGetRandomData(uint8_t* buffer, size_t numOfBytes) +{ + int ret = wc_RNG_GenerateBlock(liboqsCurrentRNG, buffer, numOfBytes); + if (ret != 0) { + // ToDo: liboqs exits programm if RNG fails, not sure what to do here + } +} + +int wolfSSL_liboqsInit(void) +{ + int ret = 0; + + if (liboqs_init == 0) { + ret = wc_InitMutex(&liboqsRNGMutex); + if (ret != 0) { + return ret; + } + ret = wc_LockMutex(&liboqsRNGMutex); + if (ret != 0) { + return ret; + } + ret = wc_InitRng(&liboqsDefaultRNG); + if (ret == 0) { + OQS_init(); + liboqs_init = 1; + } + liboqsCurrentRNG = &liboqsDefaultRNG; + wc_UnLockMutex(&liboqsRNGMutex); + + OQS_randombytes_custom_algorithm(wolfSSL_liboqsGetRandomData); + } + + return ret; +} + +int wolfSSL_liboqsRngMutexLock(WC_RNG* rng) +{ + int ret = wolfSSL_liboqsInit(); + if (ret == 0) { + ret = wc_LockMutex(&liboqsRNGMutex); + } + if (ret == 0 && rng != NULL) { + /* Update the pointer with the RNG to use. This is safe as we locked the mutex */ + liboqsCurrentRNG = rng; + } + return ret; +} + +int wolfSSL_liboqsRngMutexUnlock(void) +{ + int ret = BAD_MUTEX_E; + + liboqsCurrentRNG = &liboqsDefaultRNG; + + if (liboqs_init) { + ret = wc_UnLockMutex(&liboqsRNGMutex); + } + return ret; +} + +#endif /* HAVE_LIBOQS */ diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index ef61df84f..d47e62655 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -127,6 +127,10 @@ #include #endif +#if defined(HAVE_LIBOQS) + #include +#endif + /* prevent multiple mutex initializations */ static volatile int initRefCount = 0; @@ -386,6 +390,12 @@ int wolfCrypt_Init(void) } rpcmem_init(); #endif + +#if defined(HAVE_LIBOQS) + if ((ret = wolfSSL_liboqsInit()) != 0) { + return ret; + } +#endif } initRefCount++; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index dfdc80aca..373f09b22 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -115,7 +115,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/Renesas/renesas_sync.h \ wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h \ wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h \ - wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h + wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h \ + wolfssl/wolfcrypt/port/liboqs/liboqs.h if BUILD_CRYPTOAUTHLIB nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h diff --git a/wolfssl/wolfcrypt/port/liboqs/liboqs.h b/wolfssl/wolfcrypt/port/liboqs/liboqs.h new file mode 100644 index 000000000..b7a57ca0d --- /dev/null +++ b/wolfssl/wolfcrypt/port/liboqs/liboqs.h @@ -0,0 +1,60 @@ +/* liboqs.h + * + * Copyright (C) 2006-2023 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 + */ + +/*! + \file wolfssl/wolfcrypt/port/liboqs/liboqs.h +*/ +/* + +DESCRIPTION +This library provides the support interfaces to the liboqs library providing +implementations for Post-Quantum cryptography algorithms. +*/ + +#ifndef WOLF_CRYPT_LIBOQS_H +#define WOLF_CRYPT_LIBOQS_H + +#include +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(HAVE_LIBOQS) + +#include "oqs/oqs.h" + + +int wolfSSL_liboqsInit(void); + +int wolfSSL_liboqsRngMutexLock(WC_RNG* rng); + +int wolfSSL_liboqsRngMutexUnlock(void); + +#endif /* HAVE_LIBOQS */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_LIBOQS_H */ \ No newline at end of file diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 4f088c9ee..ec6dcba2c 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -109,6 +109,7 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfevent.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfmath.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/liboqs/liboqs.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/psa/psa.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/psa/psa_aes.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/psa/psa_hash.c)