diff --git a/pkg/Kconfig b/pkg/Kconfig index f1df46303a..ab58765ca8 100644 --- a/pkg/Kconfig +++ b/pkg/Kconfig @@ -30,6 +30,7 @@ rsource "libhydrogen/Kconfig" rsource "lora-serialization/Kconfig" rsource "lvgl/Kconfig" rsource "lz4/Kconfig" +rsource "mbedtls/Kconfig" rsource "micro-ecc/Kconfig" rsource "microcoap/Kconfig" rsource "minmea/Kconfig" diff --git a/pkg/mbedtls/Kconfig b/pkg/mbedtls/Kconfig new file mode 100644 index 0000000000..162c3a2c6e --- /dev/null +++ b/pkg/mbedtls/Kconfig @@ -0,0 +1,66 @@ +# Copyright (c) 2021 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +menuconfig KCONFIG_USEPKG_MBEDTLS + bool "Configure mbed TLS" + help + Configure mbed TLS using Kconfig. + +if KCONFIG_USEPKG_MBEDTLS + +config MBEDTLS_SELF_TEST + bool "Enable the checkup functions (*_self_test)" + default y + +config MBEDTLS_ENTROPY_C + bool "Enable the platform-specific entropy code." + default y + depends on MBEDTLS_SHA256_C # || MBEDTLS_SHA512_C + help + This module provides a generic entropy pool. + +config MBEDTLS_SHA256_C + bool "Enable the SHA-224 and SHA-256 cryptographic hash algorithms" + default y + help + This module adds support for SHA-224 and SHA-256. + This module is required for the SSL/TLS 1.2 PRF + function. + +config MBEDTLS_SHA256_ALT + bool "Enable to let mbed TLS use an alternate SHA2xx core implementation" + default y + help + In case you enable MBEDTLS_SHA256_ALT, mbed TLS + will no longer provide the "struct + mbedtls_sha256_context" definition and omit the + base function declarations and implementations. + "sha256_alt.h" will be included from "sha256.h" + to include the new function definitions. + +config MBEDTLS_THREADING_C + bool "Enable this layer to allow use of mutexes within mbed TLS" + default y + help + Enable the threading abstraction layer. If you do intend to + use contexts between threads, you will need to enable this + layer to prevent race condition. See also the mbed TLS + Knowledge Base article about threading: https://tls.mbed.org/ + kb/development/thread-safety-and-multi-threading + This allows different threading implementations + (self-implemented or provided). In RIOT, we enable this + layer by default and utilize MBEDTLS_THREADING_ALT with RIOT + mutexes. + +config MBEDTLS_THREADING_ALT + bool "Provide your own alternate threading implementation" + default y if MBEDTLS_THREADING_C + help + This to allows your own alternate threading implementation. + +rsource "contrib/entropy/Kconfig" + +endif # KCONFIG_USEPKG_MBEDTLS diff --git a/pkg/mbedtls/Makefile b/pkg/mbedtls/Makefile new file mode 100644 index 0000000000..bf6c695767 --- /dev/null +++ b/pkg/mbedtls/Makefile @@ -0,0 +1,10 @@ +PKG_NAME=mbedtls +PKG_URL=https://github.com/ARMmbed/mbedtls.git +PKG_VERSION=v2.26.0 +PKG_LICENSE=Apache-2.0 + +include $(RIOTBASE)/pkg/pkg.mk + +all: + $(QQ)"$(MAKE)" -C $(PKGDIRBASE)/mbedtls/library/ \ + -f $(RIOTBASE)/Makefile.base MODULE=$(PKG_NAME) diff --git a/pkg/mbedtls/Makefile.dep b/pkg/mbedtls/Makefile.dep new file mode 100644 index 0000000000..b2d7c85c5b --- /dev/null +++ b/pkg/mbedtls/Makefile.dep @@ -0,0 +1,21 @@ +ifneq (,$(filter mbedtls_entropy,$(USEMODULE))) + USEMODULE += mbedtls_contrib + USEMODULE += hashes + + FEATURES_REQUIRED_ANY += periph_adc|periph_hwrng + + # include sources if hardware is available + FEATURES_OPTIONAL += periph_hwrng + ifneq (,$(filter periph_hwrng,$(FEATURES_USED))) + DEFAULT_MODULE += mbedtls_entropy_source_hwrng + endif + + FEATURES_OPTIONAL += periph_adc + ifneq (,$(filter periph_adc,$(FEATURES_USED))) + DEFAULT_MODULE += mbedtls_entropy_source_adc + endif + + ifneq (,$(filter mbedtls_entropy_source_adc,$(USEMODULE) $(DEFAULT_MODULE))) + USEMODULE += entropy_source_adc_noise + endif +endif diff --git a/pkg/mbedtls/Makefile.include b/pkg/mbedtls/Makefile.include new file mode 100644 index 0000000000..a9f247d8b9 --- /dev/null +++ b/pkg/mbedtls/Makefile.include @@ -0,0 +1,26 @@ +INCLUDES += -I$(PKGDIRBASE)/mbedtls/include +INCLUDES += -I$(PKGDIRBASE)/mbedtls/include/mbedtls + +INCLUDES += -I$(RIOTPKG)/mbedtls/include + +CFLAGS += -DMBEDTLS_CONFIG_FILE='' + +# these PSEUDOMODULES can be used to enable/disable an entropy source +PSEUDOMODULES += mbedtls_entropy_source_hwrng +PSEUDOMODULES += mbedtls_entropy_source_adc + +ifneq (,$(filter mbedtls_contrib,$(USEMODULE))) + DIRS += $(RIOTPKG)/mbedtls/contrib +endif + +ifneq (,$(filter mbedtls_entropy,$(USEMODULE))) + DIRS += $(RIOTPKG)/mbedtls/contrib/entropy +endif + +ifneq (,$(filter entropy_source_adc_noise,$(USEMODULE))) + ifndef CONFIG_KCONFIG_USEMODULE_ENTROPY_SOURCE_ADC_NOISE + # disable conditioning by default, enable health tests + CFLAGS += -DCONFIG_ENTROPY_SOURCE_ADC_COND=0 + CFLAGS += -DCONFIG_ENTROPY_SOURCE_ADC_HEALTH_TEST=1 + endif +endif diff --git a/pkg/mbedtls/contrib/Makefile b/pkg/mbedtls/contrib/Makefile new file mode 100644 index 0000000000..6b42b203ac --- /dev/null +++ b/pkg/mbedtls/contrib/Makefile @@ -0,0 +1,3 @@ +MODULE := mbedtls_contrib + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/mbedtls/contrib/entropy/Kconfig b/pkg/mbedtls/contrib/entropy/Kconfig new file mode 100644 index 0000000000..ddd949c217 --- /dev/null +++ b/pkg/mbedtls/contrib/entropy/Kconfig @@ -0,0 +1,43 @@ +# Copyright (c) 2021 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +menuconfig KCONFIG_USEMODULE_MBEDTLS_ENTROPY + bool "Configure mbed TLS mbedtls entropy" + help + Configure mbed TLS mbedtls entropy using Kconfig. + +if KCONFIG_USEMODULE_MBEDTLS_ENTROPY + +config MBEDTLS_ENTROPY_HARDWARE_ALT + bool "Let mbed TLS use your own implementation of a hardware entropy collector" + default y + help + Your function must be called + mbedtls_hardware_poll(), have the same prototype + as declared in entropy_poll.h, and accept NULL as + first argument. + +config MBEDTLS_NO_PLATFORM_ENTROPY + bool "Disable the built-in platform entropy functions" + default y if !CPU_NATIVE + help + Do not use built-in platform entropy functions. + This is useful if your platform does not support + standards like the /dev/urandom or Windows + CryptoAPI. + +config MBEDTLS_ENTROPY_FORCE_SHA256 + bool "Force the entropy accumulator to use a SHA-256." + default y + depends on MBEDTLS_SHA256_C + help + Force the entropy accumulator to use a SHA-256 + accumulator instead of the default SHA-512 based + one (if both are available). On 32-bit systems SHA-256 + can be much faster than SHA-512. Use this option if you + have performance concerns. + +endif # KCONFIG_USEMODULE_MBEDTLS_ENTROPY diff --git a/pkg/mbedtls/contrib/entropy/Makefile b/pkg/mbedtls/contrib/entropy/Makefile new file mode 100644 index 0000000000..dfbf597293 --- /dev/null +++ b/pkg/mbedtls/contrib/entropy/Makefile @@ -0,0 +1,3 @@ +MODULE := mbedtls_entropy + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/mbedtls/contrib/entropy/entropy_mbedtls_riot.c b/pkg/mbedtls/contrib/entropy/entropy_mbedtls_riot.c new file mode 100644 index 0000000000..3c6e71b0ae --- /dev/null +++ b/pkg/mbedtls/contrib/entropy/entropy_mbedtls_riot.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_mbedtls_entropy + * + * @{ + * @file + * + * @author Peter Kietzmann + * + * @} + */ + +#include +#include "mbedtls/entropy.h" + +#include "entropy_sources_mbedtls_riot.h" +#include "entropy_mbedtls_riot.h" + +/* Internal mbedtls entropy context for convenience functions */ +static mbedtls_entropy_context ctx; + +int entropy_mbedtls_riot_init(void) +{ + mbedtls_entropy_init(&ctx); + + return riot_add_entropy_src_avail(&ctx); +} + +int entropy_mbedtls_riot_retrieve(unsigned char *output, size_t len) +{ + assert(output != NULL); + + return mbedtls_entropy_func(&ctx, output, len); +} + +void entropy_mbedtls_riot_uninit(void) +{ + mbedtls_entropy_free(&ctx); +} + +int entropy_mbedtls_riot_get(unsigned char *output, size_t len) +{ + assert(output != NULL); + + int ret = 0; + + if ((ret = entropy_mbedtls_riot_init()) < 0) { + entropy_mbedtls_riot_uninit(); + return ret; + } + + ret = entropy_mbedtls_riot_retrieve(output, len); + + /* Always uninitialize at the end */ + entropy_mbedtls_riot_uninit(); + + return ret; +} diff --git a/pkg/mbedtls/contrib/entropy/entropy_sources_mbedtls_riot.c b/pkg/mbedtls/contrib/entropy/entropy_sources_mbedtls_riot.c new file mode 100644 index 0000000000..22ccf44a44 --- /dev/null +++ b/pkg/mbedtls/contrib/entropy/entropy_sources_mbedtls_riot.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_mbedtls_entropy + * + * @{ + * @file + * @brief + * + * @author Peter Kietzmann + * + * @} + */ +#include + +#include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" + +#include "entropy_sources_mbedtls_riot.h" + +#include "kernel_defines.h" +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_HWRNG) +#include "periph/hwrng.h" +#endif + +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_ADC) +#include "entropy_source/adc_noise.h" +#endif + +/** + * @brief Number of available entropy sources. + */ +#define NUM_ENTROPY_FUNCS ARRAY_SIZE(entropy_funcs) + +/** + * @brief Configuration of available entropy sources. + * + * @note First source must be the best source available. It is + * expected to be strong. + * @note An entropy source is configured if the platform provides + the underlying feature and the PSEUDOMODULE (which is + included by default) is not manually disabled. + * @{ + */ +const entropy_source_mbedtls_riot_t entropy_funcs[] = { +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_HWRNG) +{ .func = riot_hwrng_poll, .strong = MBEDTLS_ENTROPY_SOURCE_STRONG }, +#endif +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_ADC) +{ .func = riot_adc_poll, .strong = MBEDTLS_ENTROPY_SOURCE_WEAK }, +#endif + /* Additional sources need to be added here */ +}; +/** @} */ + +/* Connect first entropy source because this function + * is used for internal tests + */ +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, + size_t *olen) +{ + assert(output != NULL && olen!= NULL); + + return entropy_funcs[0].func(data, output, len, olen); +} + +/* Add more entropy sources. Start from index=1 because index=0 is used in + * mbedtls_hardware_poll already + */ +int riot_add_entropy_src_avail(mbedtls_entropy_context *ctx) +{ + assert(ctx); + int ret = 0; + +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_ADC) + entropy_source_adc_init(); +#endif + + for (unsigned i = 1; i < NUM_ENTROPY_FUNCS; i++) { + ret = mbedtls_entropy_add_source(ctx, entropy_funcs[i].func, NULL, + 1, entropy_funcs[i].strong); + if (ret != 0) { + return ret; + } + } + + return ret; +} + +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_HWRNG) +int riot_hwrng_poll(void *data, unsigned char *output, size_t len, + size_t *olen) +{ + + assert(output != NULL && olen!= NULL); + + (void)data; + + hwrng_read(output, len); + *olen = len; + + return 0; +} +#endif + +#if IS_USED(MODULE_MBEDTLS_ENTROPY_SOURCE_ADC) +int riot_adc_poll(void *data, unsigned char *output, size_t len, + size_t *olen) +{ + assert(output != NULL && olen!= NULL); + + (void)data; + + if (entropy_source_adc_get(output, len) < 0) { + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } + *olen=len; + + return 0; +} +#endif diff --git a/pkg/mbedtls/contrib/sha256_alt.c b/pkg/mbedtls/contrib/sha256_alt.c new file mode 100644 index 0000000000..588b3faa37 --- /dev/null +++ b/pkg/mbedtls/contrib/sha256_alt.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_mbedtls + * + * @{ + * @file + * + * @author Peter Kietzmann + * + * @} + */ + +#include +#include + +#include "sha256_alt.h" + +#if IS_ACTIVE(MBEDTLS_SHA256_ALT) +#include "mbedtls/sha256.h" +#include "mbedtls/platform.h" + +void mbedtls_sha256_init(mbedtls_sha256_context *ctx) +{ + assert(ctx != NULL); + + memset(ctx, 0, sizeof(mbedtls_sha256_context)); +} + +void mbedtls_sha256_free(mbedtls_sha256_context *ctx) +{ + if (ctx == NULL ) { + return; + } + memset(ctx, 0, sizeof(mbedtls_sha256_context)); +} + +void mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + if (dst == NULL || src == NULL) { + return; + } + memcpy(dst, src, sizeof(mbedtls_sha256_context)); +} + +int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) +{ + assert(ctx != NULL); + + ctx->is224 = is224; + if (is224) { + sha224_init(&ctx->riot_sha256_ctx); + } + else { + sha256_init(&ctx->riot_sha256_ctx); + } + return 0; +} + +int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, + const unsigned char data[64]) +{ + (void)ctx; + (void)data; + + return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; +} + +int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen) +{ + assert(ctx != NULL && input != NULL); + + sha256_update(&ctx->riot_sha256_ctx, input, ilen); + return 0; +} + +int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, + unsigned char output[32]) +{ + assert(ctx != NULL && output != NULL); + + if (ctx->is224) { + sha224_final(&ctx->riot_sha256_ctx, output); + } + else { + sha256_final(&ctx->riot_sha256_ctx, output); + } + return 0; +} +#endif /* MBEDTLS_SHA256_ALT */ diff --git a/pkg/mbedtls/contrib/threading_alt.c b/pkg/mbedtls/contrib/threading_alt.c new file mode 100644 index 0000000000..4de02e0829 --- /dev/null +++ b/pkg/mbedtls/contrib/threading_alt.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_mbedtls + * + * @{ + * @file + * + * @author Peter Kietzmann + * + * @} + */ + +#include +#include + +#include "threading_alt.h" + +#if IS_ACTIVE(MBEDTLS_THREADING_ALT) +#include "mbedtls/threading.h" + +void mbedtls_platform_mutex_init(mbedtls_threading_mutex_t *mutex) +{ + mutex_init(&mutex->riot_mutex); +} + +void mbedtls_platform_mutex_free(mbedtls_threading_mutex_t *mutex) +{ + (void)mutex; +} + +int mbedtls_platform_mutex_lock(mbedtls_threading_mutex_t *mutex) +{ + mutex_lock(&mutex->riot_mutex); + return 0; +} + +int mbedtls_platform_mutex_unlock(mbedtls_threading_mutex_t *mutex) +{ + mutex_unlock(&mutex->riot_mutex); + return 0; +} + +void auto_init_mbedtls(void) +{ + /* Configure mbedTLS to use RIOT specific threading functions. */ + mbedtls_threading_set_alt( mbedtls_platform_mutex_init, + mbedtls_platform_mutex_free, + mbedtls_platform_mutex_lock, + mbedtls_platform_mutex_unlock ); +} +#endif /* MBEDTLS_THREADING_ALT */ diff --git a/pkg/mbedtls/doc.txt b/pkg/mbedtls/doc.txt new file mode 100644 index 0000000000..ba75c1c26c --- /dev/null +++ b/pkg/mbedtls/doc.txt @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + + +/** + * @defgroup pkg_mbedtls ARM Mbed TLS + * @ingroup pkg + * @brief SSL crypto library + * @see https://github.com/ARMmbed/mbedtls.git + * @warning Entropy sources need to be thoroughly evaluated before deployment. + * @experimental This port is in an early state - expect changes. + * + * + * # Overview + * + * This port includes the ARM Mbed TLS library as a package. A more comprehensive + * library documentation can be found in the [knowledge base](https://tls.mbed.org/kb) and the + * [source code documentation](https://tls.mbed.org/api/). Mbed TLS is highly + * configurable and it allows inclusion of alternative hardware or OS specific implementations + * to be used by the library. + * A porting guide can be found [here](https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS). + * The configuration and enablement of alternative implementations has to be defined in + * the [configuration file](include/riot_mbedtls_config.h) of this package. + * + * + * # Tested Submodules + * + * ## Entropy + * The `entropy` and `entropy_poll` components of the Mbed TLS library + * have been tested in RIOT. The module uses a SHA-256 or a SHA-512 based + * accumulator. This port enables the SHA-256 accumulator and it adapts the RIOT SHA-256 + * implementation to be used as a backend. Our reconfiguration disables the internal + * Mbed TLS implementation. A future + * compile time configuration in RIOT with transparent hardware crypto acceleration + * support will be used by the package seamlessly. + * + * The entropy module is initialized with one or more entropy + * sources which are polled iteratively and accumulated. Sources for entropy are + * registered with a function pointer and an assumption about their strength (strong/weak). + * The module is designed for cryptographic purposes, thus, an entropy poll will + * fail if there is not a single strong source. Strong sources are typically true + * (hardware) random number generators with conditioning which will provide full entropy + * per sample. In contrast, weak sources do not necessarily provide full entropy per + * sample and act as a complement, even if they only contain few random bits in a sample, + * which is typically the case for sampled noise sources. + * + * + * ### Entropy Sources + * + * RIOT provides default sources to feed the entropy module. Yet, only + * @ref drivers_periph_hwrng and @ref sys_entropy_source_adc are enabled in this package. It is planned to + * extend this list. In addition, a user can connect a personal source to the entropy + * poll by implementing [`mbedtls_entropy_add_source`](https://tls.mbed.org/api/entropy_8h.html). + * + * It is noteworthy that an entropy module might be required during OS bootstrapping, + * hence, a module that is added in `main()` will not be incorporated during `auto_init()`. + * + * Mbed TLS entropy sources are expressed as pseudomodules. + * + * ``` + * PSEUDOMODULES += mbedtls_entropy_source_hwrng + * PSEUDOMODULES += mbedtls_entropy_source_adc + * ``` + * + * Clearly, these sources require hardware capabilities which are indicated by a platform. + * + * ``` + * FEATURES_PROVIDED += periph_hwrng + * FEATURES_PROVIDED += periph_adc + * ``` + * + * All sources will be enabled by default, if available. Furthermore, a single source + * can be manually excluded from the entropy poll by disabling it in the applications Makefile. + * + * ``` + * DISABLE_MODULE += mbedtls_entropy_source_hwrng + * ``` + * + * ### Usage + * The RIOT API @ref pkg_mbedtls_entropy + * can be used which wraps around the Mbed TLS API and handles one entropy context internally. + * Thereby, @ref entropy_mbedtls_riot_get initializes the module, retrieves entropy + * values and uninitializes the context afterwards. + * Alternatively, the entropy module can be used directly by calling the Mbed TLS API which requires + * the entropy context to be allocated from application code. The adaptation in this + * package will then only utilize the first configured entropy source + * during initialization. + * + * # Testing + * Many Mbed TLS implementations provide self tests within the boundaries of + * a module and the [test folder](../../tests/pkg_mbedtls) acts as a place to execute + * these tests in RIOT context. It is noteworthy, that built-in Mbed TLS entropy source tests + * only execute on the source that is implemented in `mbedtls_hardware_poll`. + * The additional sources that were added using `mbedtls_entropy_add_source` are ignored in the test. + * + */ diff --git a/pkg/mbedtls/include/entropy_mbedtls_riot.h b/pkg/mbedtls/include/entropy_mbedtls_riot.h new file mode 100644 index 0000000000..29dcb0f0da --- /dev/null +++ b/pkg/mbedtls/include/entropy_mbedtls_riot.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup pkg_mbedtls_entropy Access API to Mbed TLS entropy module + * @ingroup pkg_mbedtls + * + * @{ + * @file + * @brief Convenience functions to retrieve entropy from Mbed TLS. Direct + * use of the Mbed TLS API is also possible without this API. + * + * @author Peter Kietzmann + * + */ + +#ifndef ENTROPY_MBEDTLS_RIOT_H +#define ENTROPY_MBEDTLS_RIOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the Mbed TLS entropy module. + * + * A context structure is allocated and managed internally. + * Connect all available entropy sources to the poll. + * + * @retval 0 if successful + * @retval MBEDTLS_ERR_ENTROPY_MAX_SOURCES on failure + */ +int entropy_mbedtls_riot_init(void); + +/** + * @brief Retrieve entropy values after initialization. + * + * @pre Module is initialized already (i.e. @ref entropy_mbedtls_riot_init has been called). + * + * @param[out] output Pointer to the output buffer to fill with entropy values. + * @param[in] len Length of requested entropy in bytes. + * + * @retval 0 if successful + * @retval MBEDTLS_ERR_ENTROPY_SOURCE_FAILED if source failed + */ +int entropy_mbedtls_riot_retrieve(unsigned char *output, size_t len); + +/** + * @brief Uninitialize the Mbed TLS entropy module. + * + * Frees the internally allocated context. Mbed TLS zeroizes the memory. + */ +void entropy_mbedtls_riot_uninit(void); + +/** + * @brief Get entropy values. + * + * Convenience function. A context structure is allocated and managed + * internally. Requested entropy values are gathered and the context is + * uninitialized afterwards. + * + * @param[out] output Pointer to the output buffer to fill with entropy values. + * @param[in] len Length of requested entropy in bytes. + * + * @retval 0 if successful + * @retval MBEDTLS_ERR_ENTROPY_MAX_SOURCES on failure + * @retval MBEDTLS_ERR_ENTROPY_SOURCE_FAILED if source failed + */ +int entropy_mbedtls_riot_get(unsigned char *output, size_t len); + +#ifdef __cplusplus +} +#endif +/** @} */ + +#endif /* ENTROPY_MBEDTLS_RIOT_H */ diff --git a/pkg/mbedtls/include/entropy_sources_mbedtls_riot.h b/pkg/mbedtls/include/entropy_sources_mbedtls_riot.h new file mode 100644 index 0000000000..fa7791ef7b --- /dev/null +++ b/pkg/mbedtls/include/entropy_sources_mbedtls_riot.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup pkg_mbedtls_entropy_sources Entropy source API to Mbed TLS + * @ingroup pkg_mbedtls + * + * @{ + * @file + * @brief Functions to register and poll with the Mbed TLS entropy module. + * + * @author Peter Kietzmann + * + */ + +#ifndef ENTROPY_SOURCES_MBEDTLS_RIOT_H +#define ENTROPY_SOURCES_MBEDTLS_RIOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Structure containing entropy function and its strength + */ +typedef struct { + mbedtls_entropy_f_source_ptr func; /**< Pointer to entropy callback func. */ + int strong; /**< Strength of the entropy function + * (strong=1 for high entropy sources, + * strong=0 for weak entropy sources)*/ +} entropy_source_mbedtls_riot_t; + +/** + * @brief Add all available entropy sources to poll. + * + * This function would typically not be called by a user. It is called during + * initialization by @ref entropy_mbedtls_riot_init. + * + * @param[out] ctx Pointer to mbedtls context. + * + * @return 0 if successful + * @return MBEDTLS_ERR_ENTROPY_MAX_SOURCES on failure + */ +int riot_add_entropy_src_avail(mbedtls_entropy_context *ctx); + +/** + * @brief Wrapper around RIOTs HWRNG API. + * + * Required to comply with mbed TLS entropy callback function signature. + * + * @param[in] data Not used. + * @param[in] output Pointer to the output buffer to fill. + * @param[in] len Length of requested entropy in bytes. + * @param[out] olen Equals len. + * + * @return 0 always + */ +int riot_hwrng_poll(void *data, unsigned char *output, size_t len, + size_t *olen); + +/** + * @brief Wrapper around RIOTs ADC entropy API. + * + * Required to comply with mbed TLS entropy callback function signature. + * + * @param[in] data Not used. + * @param[in] output Pointer to the output buffer to fill. + * @param[in] len Length of requested entropy in bytes. + * @param[out] olen Equals len. + * + * @return 0 if no critical failures occurred, + * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise. + */ +int riot_adc_poll(void *data, unsigned char *output, size_t len, + size_t *olen); + +#if !defined(MODULE_MBEDTLS_ENTROPY_SOURCE_HWRNG) && \ + !defined(MODULE_ENTROPY_SOURCE_ADC_NOISE) +#error "You must enable at least one entropy source. Currently supported are \ + HWRNG and ADC_NOISE" +#endif + +#ifdef __cplusplus +} +#endif +/** @} */ + +#endif /* ENTROPY_SOURCES_MBEDTLS_RIOT_H */ diff --git a/pkg/mbedtls/include/riot_mbedtls_config.h b/pkg/mbedtls/include/riot_mbedtls_config.h new file mode 100644 index 0000000000..68879b3e9c --- /dev/null +++ b/pkg/mbedtls/include/riot_mbedtls_config.h @@ -0,0 +1,239 @@ +/** + * @defgroup pkg_mbedtls_config Mbed TLS package compile configurations + * @ingroup pkg_mbedtls + * + * @{ + * @file + * + * @brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RIOT_MBEDTLS_CONFIG_H +#define RIOT_MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +#include "kernel_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !IS_ACTIVE(CONFIG_KCONFIG_USEPKG_MBEDTLS) || defined(DOXYGEN) + +/** + * + * @brief Enable the checkup functions (*_self_test). + */ +#ifndef CONFIG_MBEDTLS_SELF_TEST +#define CONFIG_MBEDTLS_SELF_TEST 1 +#endif + +/** + * + * @brief Enable the platform-specific entropy code. + * + * Module: mbedtls/library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +#ifndef CONFIG_MBEDTLS_ENTROPY_C +#define CONFIG_MBEDTLS_ENTROPY_C 1 +#endif + +/** + * + * @brief Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: mbedtls/library/sha256.c + * Caller: mbedtls/library/entropy.c + * mbedtls/library/md.c + * mbedtls/library/ssl_cli.c + * mbedtls/library/ssl_srv.c + * mbedtls/library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#ifndef CONFIG_MBEDTLS_SHA256_C +#define CONFIG_MBEDTLS_SHA256_C 1 +#endif + +/** + * + * @brief MBEDTLS__MODULE_NAME__ALT: Enable a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you enable MBEDTLS_SHA256_ALT, mbed TLS will no longer + * provide the "struct mbedtls_sha256_context" definition and omit the base + * function declarations and implementations. "sha256_alt.h" will be included from + * "sha256.h" to include the new function definitions. + * + * Enable a macro to enable alternate implementation of the corresponding + * module. + * + * @warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +#ifndef CONFIG_MBEDTLS_SHA256_ALT +#define CONFIG_MBEDTLS_SHA256_ALT 1 +#endif + +/** + * + * @brief Enable the threading abstraction layer. By default mbed TLS + * assumes it is used in a non-threaded environment or that contexts + * are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + * + * @note In RIOT, we enable this layer by default and utilize + * MBEDTLS_THREADING_ALT with RIOT mutexes. + */ +#ifndef CONFIG_MBEDTLS_THREADING_C +#define CONFIG_MBEDTLS_THREADING_C 1 +#endif + +/** + * @brief Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * This to allows your own alternate threading implementation. + */ +#if !defined (CONFIG_MBEDTLS_THREADING_ALT) && defined (CONFIG_MBEDTLS_THREADING_C) +#define CONFIG_MBEDTLS_THREADING_ALT 1 +#endif + +#endif /* !CONFIG_KCONFIG_USEPKG_MBEDTLS || DOXYGEN */ + +#if !IS_ACTIVE(CONFIG_KCONFIG_USEMODULE_MBEDTLS_ENTROPY) || defined(DOXYGEN) + +/** + * + * @brief Enable this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Enable to use your own hardware entropy collector. + */ +#ifndef CONFIG_MBEDTLS_ENTROPY_HARDWARE_ALT +#define CONFIG_MBEDTLS_ENTROPY_HARDWARE_ALT 1 +#endif + +/** + * + * @brief Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Disable the built-in platform entropy functions. + */ +#ifndef CONFIG_MBEDTLS_NO_PLATFORM_ENTROPY +#define CONFIG_MBEDTLS_NO_PLATFORM_ENTROPY 1 +#endif + +/** + * + * @brief Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +#ifndef CONFIG_MBEDTLS_ENTROPY_FORCE_SHA256 +#define CONFIG_MBEDTLS_ENTROPY_FORCE_SHA256 1 +#endif + +#endif /* !CONFIG_KCONFIG_USEMODULE_MBEDTLS_ENTROPY || DOXYGEN */ + +/** + * @cond + * This translates RIOT exposed options to Mbed TLS macros, it is hidden from Doxygen. + */ +#if CONFIG_MBEDTLS_SHA256_ALT +#define MBEDTLS_SHA256_ALT 1 +#endif +#if CONFIG_MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_ENTROPY_HARDWARE_ALT 1 +#endif +#if CONFIG_MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_NO_PLATFORM_ENTROPY 1 +#endif +#if CONFIG_MBEDTLS_ENTROPY_FORCE_SHA256 +#define MBEDTLS_ENTROPY_FORCE_SHA256 1 +#endif +#if CONFIG_MBEDTLS_THREADING_C +#define MBEDTLS_THREADING_C 1 +#endif +#if CONFIG_MBEDTLS_THREADING_ALT +#define MBEDTLS_THREADING_ALT 1 +#endif +#if CONFIG_MBEDTLS_SELF_TEST +#define MBEDTLS_SELF_TEST 1 +#endif +#if CONFIG_MBEDTLS_ENTROPY_C +#define MBEDTLS_ENTROPY_C 1 +#endif +#if CONFIG_MBEDTLS_SHA256_C +#define MBEDTLS_SHA256_C 1 +#endif +/** @endcond */ + +#include "mbedtls/check_config.h" + +#ifdef __cplusplus +} +#endif + +#endif /* RIOT_MBEDTLS_CONFIG_H */ +/** @} */ diff --git a/pkg/mbedtls/include/sha256_alt.h b/pkg/mbedtls/include/sha256_alt.h new file mode 100644 index 0000000000..cbb015dea2 --- /dev/null +++ b/pkg/mbedtls/include/sha256_alt.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_mbedtls + * + * @{ + * @file + * + * @author Peter Kietzmann + * + */ + +#ifndef SHA256_ALT_H +#define SHA256_ALT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "kernel_defines.h" +#include "riot_mbedtls_config.h" + +#if IS_ACTIVE(MBEDTLS_SHA256_ALT) +#include "hashes/sha256.h" +#include "hashes/sha224.h" + +/** + * @brief Context structure for alternative mbedtls SHA-256 implementation. + */ +typedef struct { + sha256_context_t riot_sha256_ctx; /**< RIOT SHA-256 context structure */ + uint8_t is224; /**< SHA-224/256 switch */ +} mbedtls_sha256_context; + +#endif /* MBEDTLS_SHA256_ALT */ + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif /* SHA256_ALT_H */ diff --git a/pkg/mbedtls/include/threading_alt.h b/pkg/mbedtls/include/threading_alt.h new file mode 100644 index 0000000000..3d442127a3 --- /dev/null +++ b/pkg/mbedtls/include/threading_alt.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_mbedtls + * + * @{ + * @file + * + * @author Peter Kietzmann + * + */ + +#ifndef THREADING_ALT_H +#define THREADING_ALT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "riot_mbedtls_config.h" + +#if IS_ACTIVE(MBEDTLS_THREADING_ALT) +#include "mutex.h" + +/** + * @brief Context structure for alternative mbedtls threading implementation. + */ +typedef struct { + mutex_t riot_mutex; /**< RIOT mutex structure */ +} mbedtls_threading_mutex_t; + +#endif /* MBEDTLS_THREADING_ALT */ + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif /* THREADING_ALT_H */ diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index d28eccde1f..7c7a564a18 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -248,6 +248,12 @@ void auto_init(void) suit_init_conditions(); } + if (IS_USED(MODULE_MBEDTLS)) { + LOG_DEBUG("Auto init mbed TLS.\n"); + extern void auto_init_mbedtls(void); + auto_init_mbedtls(); + } + if (IS_USED(MODULE_AUTO_INIT_SECURITY)) { if (IS_USED(MODULE_CRYPTOAUTHLIB)) { LOG_DEBUG("Auto init cryptoauthlib.\n"); diff --git a/tests/pkg_mbedtls/Makefile b/tests/pkg_mbedtls/Makefile new file mode 100644 index 0000000000..5634c3938c --- /dev/null +++ b/tests/pkg_mbedtls/Makefile @@ -0,0 +1,21 @@ +include ../Makefile.tests_common + +USEPKG += mbedtls +USEMODULE += mbedtls_entropy + +# Increase stack size of main thread. +CFLAGS += -DTHREAD_STACKSIZE_MAIN=THREAD_STACKSIZE_LARGE + +# You can disable single entropy source to be used with the entropy module +# DISABLE_MODULE += mbedtls_entropy_source_hwrng + +include $(RIOTBASE)/Makefile.include + +ifneq (,$(filter mbedtls_entropy_source_adc,$(USEMODULE))) + ifndef CONFIG_KCONFIG_USEMODULE_ENTROPY_SOURCE_ADC_NOISE + # This is an exemplary entropy value of 1 bit/sample provided by + # the ADC noise source. To avoid float, this value has to be + # multiplied by 65536 beforehand. + CFLAGS += -DCONFIG_ENTROPY_SOURCE_ADC_HMIN=65536 + endif +endif diff --git a/tests/pkg_mbedtls/Makefile.ci b/tests/pkg_mbedtls/Makefile.ci new file mode 100644 index 0000000000..aa5a53e22a --- /dev/null +++ b/tests/pkg_mbedtls/Makefile.ci @@ -0,0 +1,16 @@ +BOARD_INSUFFICIENT_MEMORY := \ + arduino-duemilanove \ + arduino-leonardo \ + arduino-nano \ + arduino-uno \ + atmega328p-xplained-mini \ + atmega328p \ + nucleo-f302r8 \ + nucleo-f303k8 \ + nucleo-f303re \ + nucleo-f303ze \ + nucleo-f334r8 \ + nucleo-l011k4 \ + nucleo-l476rg \ + qn9080dk \ + # diff --git a/tests/pkg_mbedtls/main.c b/tests/pkg_mbedtls/main.c new file mode 100644 index 0000000000..42905d502f --- /dev/null +++ b/tests/pkg_mbedtls/main.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Test the correct loading and linking of the mbedtls package and + execute built-in selftests. + * + * @author Peter Kietzmann + * + * @} + */ + +#include + +#include "mbedtls/sha256.h" +#include "mbedtls/entropy.h" + +#include "entropy_mbedtls_riot.h" + +int main(void) +{ + puts("mbedtls test\n"); + + /* Execute built-in tests */ + mbedtls_sha256_self_test(1); + mbedtls_entropy_self_test(1); + + /* Execute convenience functions */ + unsigned char out[4]; + entropy_mbedtls_riot_init(); + entropy_mbedtls_riot_retrieve(out, sizeof(out)); + entropy_mbedtls_riot_uninit(); + + entropy_mbedtls_riot_get(out, sizeof(out)); + + return 0; +} diff --git a/tests/pkg_mbedtls/tests/01-run.py b/tests/pkg_mbedtls/tests/01-run.py new file mode 100755 index 0000000000..590e362e17 --- /dev/null +++ b/tests/pkg_mbedtls/tests/01-run.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2020 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import sys +from testrunner import run + + +def testfunc(child): + child.expect_exact('SHA-224 test #1: passed') + child.expect_exact('SHA-224 test #2: passed') + child.expect_exact('SHA-224 test #3: passed') + child.expect_exact('SHA-256 test #1: passed') + child.expect_exact('SHA-256 test #2: passed') + child.expect_exact('SHA-256 test #3: passed') + child.expect_exact('ENTROPY test: passed') + + +if __name__ == "__main__": + sys.exit(run(testfunc))