From f30417772666a18fa2dbee97186f4a6dc781bdad Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 5 Oct 2017 19:25:29 +0300 Subject: [PATCH] [samr21] Add hardware acceleration for the AES block cipher (#3491) samr21 has HW aes-128 module. It couldn't be used before as mbedtls uses 256 bit random generator. Recently mbedtls introduces MBEDTLS_CTR_DRBG_USE_128_BIT_KEY flag which makes mbedtls to use 128 bit random generator. It limits the security of generated keys but allows to use HW aes-128 module for encrypt/decrypt 802.15.4 frames. Signed-off-by: Oleksandr Grytsov --- examples/Makefile-samr21 | 7 + examples/platforms/samr21/Makefile.am | 1 + examples/platforms/samr21/crypto/aes_alt.c | 142 +++++++++++++++ examples/platforms/samr21/crypto/aes_alt.h | 167 ++++++++++++++++++ .../samr21/crypto/samr21-mbedtls-config.h | 47 +++++ examples/platforms/samr21/radio.c | 2 + 6 files changed, 366 insertions(+) create mode 100644 examples/platforms/samr21/crypto/aes_alt.c create mode 100644 examples/platforms/samr21/crypto/aes_alt.h create mode 100644 examples/platforms/samr21/crypto/samr21-mbedtls-config.h diff --git a/examples/Makefile-samr21 b/examples/Makefile-samr21 index 9c7c4f863..bd19b8f44 100644 --- a/examples/Makefile-samr21 +++ b/examples/Makefile-samr21 @@ -66,11 +66,18 @@ configure_OPTIONS = \ --enable-radio-only \ --enable-linker-map \ --with-examples=samr21 \ + MBEDTLS_CPPFLAGS="$(SAMR21_MBEDTLS_CPPFLAGS)" \ $(NULL) TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST)))).. AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))).. +SAMR21_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"' +SAMR21_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"samr21-mbedtls-config.h\"' +SAMR21_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/samr21/crypto +SAMR21_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls +SAMR21_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include + CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-samr21-config.h\"' CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/samr21/ diff --git a/examples/platforms/samr21/Makefile.am b/examples/platforms/samr21/Makefile.am index a3aaade0d..ae805058b 100644 --- a/examples/platforms/samr21/Makefile.am +++ b/examples/platforms/samr21/Makefile.am @@ -87,6 +87,7 @@ libopenthread_samr21_a_CPPFLAGS $(NULL) PLATFORM_SOURCES = \ + crypto/aes_alt.c \ alarm.c \ diag.c \ cxx_helpers.c \ diff --git a/examples/platforms/samr21/crypto/aes_alt.c b/examples/platforms/samr21/crypto/aes_alt.c new file mode 100644 index 000000000..b943e443a --- /dev/null +++ b/examples/platforms/samr21/crypto/aes_alt.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "aes_alt.h" +#include "mbedtls/aes.h" + +#ifdef MBEDTLS_AES_ALT + +#include "sal.h" + +#include +#include + +void mbedtls_aes_init(mbedtls_aes_context *ctx) +{ + (void)ctx; +} + +void mbedtls_aes_free(mbedtls_aes_context *ctx) +{ + (void)ctx; +} + +int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits) +{ + int retval = 0; + + switch (keybits) + { + case 128: + sal_aes_setup((uint8_t *)key, AES_MODE_ECB, AES_DIR_ENCRYPT); + break; + + default: + retval = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; + break; + } + + return retval; +} + +int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits) +{ + int retval = 0; + + switch (keybits) + { + case 128: + sal_aes_setup((uint8_t *)key, AES_MODE_ECB, AES_DIR_DECRYPT); + break; + + default: + retval = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; + break; + } + + return retval; +} + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]) +{ + int retval = 0; + + sal_aes_wrrd((uint8_t *)input, NULL); + sal_aes_read((uint8_t *)output); + + return retval; +} + +int mbedtls_aes_self_test(int verbose) +{ + (void)verbose; + + /* 128-bit Key 2b7e151628aed2a6abf7158809cf4f3c */ + const uint8_t key_128b[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; + mbedtls_aes_context aes; + int retval = 0; + + uint8_t input[16] = {0}; + uint8_t output[16] = {0}; + uint8_t decrypt[16] = {0}; + + strcpy((char *)input, (const char *)"hw_aes_test"); + + mbedtls_aes_init(&aes); + + retval = mbedtls_aes_setkey_enc(&aes, (const unsigned char *)key_128b, 128); + VerifyOrExit(retval != 0, retval = -1); + + retval = mbedtls_aes_setkey_dec(&aes, (const unsigned char *)key_128b, 128); + VerifyOrExit(retval != 0, retval = -1); + + retval = mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, input, output); + VerifyOrExit(retval != 0, retval = -1); + + retval = mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_DECRYPT, output, decrypt); + VerifyOrExit(retval != 0, retval = -1); + + mbedtls_aes_free(&aes); + +exit: + + return retval; +} + +#endif /* MBEDTLS_AES_ALT */ diff --git a/examples/platforms/samr21/crypto/aes_alt.h b/examples/platforms/samr21/crypto/aes_alt.h new file mode 100644 index 000000000..7707688ec --- /dev/null +++ b/examples/platforms/samr21/crypto/aes_alt.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MBEDTLS_AES_ALT_H +#define MBEDTLS_AES_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "samr21-mbedtls-config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef MBEDTLS_AES_ALT + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint8_t hwKeyLen; + unsigned char aes_enc_key[32]; /* Encryption key */ + unsigned char aes_dec_key[32]; /* Decryption key */ +} mbedtls_aes_context; + +/** + * @brief Initialize AES context + * + * @param [in,out] ctx AES context to be initialized + */ +void mbedtls_aes_init(mbedtls_aes_context *ctx); + +/** + * @brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void mbedtls_aes_free(mbedtls_aes_context *ctx); + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], + unsigned char output[16]); + +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_AES_ALT */ + +#endif /* MBEDTLS_AES_ALT_H */ diff --git a/examples/platforms/samr21/crypto/samr21-mbedtls-config.h b/examples/platforms/samr21/crypto/samr21-mbedtls-config.h new file mode 100644 index 000000000..8da1d8b01 --- /dev/null +++ b/examples/platforms/samr21/crypto/samr21-mbedtls-config.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SAMR21_MBEDTLS_CONFIG_H +#define SAMR21_MBEDTLS_CONFIG_H + +/** + * \def MBEDTLS_AES_ALT + * + * Enable hardware acceleration for the AES block cipher + * + * Module: sl_crypto/src/sl_aes.c + * or + * sl_crypto/src/slcl_aes.c if MBEDTLS_SLCL_PLUGINS is defined. + * + * See MBEDTLS_AES_C for more information. + */ +#define MBEDTLS_AES_ALT + +#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + +#endif // SAMR21_MBEDTLS_CONFIG_H diff --git a/examples/platforms/samr21/radio.c b/examples/platforms/samr21/radio.c index 379404429..99efd9ad7 100644 --- a/examples/platforms/samr21/radio.c +++ b/examples/platforms/samr21/radio.c @@ -313,6 +313,8 @@ void samr21RadioInit(void) sReceiveFrame.mPsdu = NULL; PHY_Init(); + + sal_init(); } void samr21RadioProcess(otInstance *aInstance)