[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 <[email protected]>
This commit is contained in:
Oleksandr Grytsov
2019-02-04 18:24:37 -08:00
committed by Jonathan Hui
parent 0073a49dbd
commit f304177726
6 changed files with 366 additions and 0 deletions
+7
View File
@@ -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/
+1
View File
@@ -87,6 +87,7 @@ libopenthread_samr21_a_CPPFLAGS
$(NULL)
PLATFORM_SOURCES = \
crypto/aes_alt.c \
alarm.c \
diag.c \
cxx_helpers.c \
+142
View File
@@ -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 <common/code_utils.hpp>
#include <string.h>
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 */
+167
View File
@@ -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 */
@@ -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
+2
View File
@@ -313,6 +313,8 @@ void samr21RadioInit(void)
sReceiveFrame.mPsdu = NULL;
PHY_Init();
sal_init();
}
void samr21RadioProcess(otInstance *aInstance)