mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 05:07:47 +00:00
[da15000] AES Hardware support (#2091)
This commit is contained in:
committed by
Jonathan Hui
parent
a8105f7fcc
commit
ff270a1233
@@ -47,6 +47,7 @@ configure_OPTIONS = \
|
||||
--with-ncp-bus=uart \
|
||||
--with-examples=da15000 \
|
||||
--enable-linker-map \
|
||||
MBEDTLS_CPPFLAGS="$(DA15000_MBEDTLS_CPPFLAGS)" \
|
||||
$(NULL)
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
|
||||
@@ -54,6 +55,20 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
|
||||
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
|
||||
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
|
||||
|
||||
DA15000_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"da15000-mbedtls-config.h\"'
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/examples/platforms/da15000/crypto
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/include
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/peripherals/include
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/adapters/include
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/memory/include
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/interfaces/ftdf/include
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/config
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/interfaces/ftdf/src
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/mbedtls/repo.patched/include
|
||||
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/mbedtls
|
||||
DA15000_MBEDTLS_CPPFLAGS += -include$(PWD)/examples/platforms/da15000/custom_config_qspi.h
|
||||
|
||||
CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-da15000-config.h\"'
|
||||
CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/da15000/
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ lib_LIBRARIES
|
||||
libopenthread_da15000_a_CPPFLAGS = \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/examples/platforms \
|
||||
-I$(top_srcdir)/examples/platforms/da15000 \
|
||||
-I$(top_srcdir)/examples/platforms/da15000/crypto \
|
||||
-I$(top_srcdir)/src/core \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/include \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/peripherals/include \
|
||||
@@ -42,6 +44,7 @@ libopenthread_da15000_a_CPPFLAGS
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/config \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/interfaces/ftdf/src \
|
||||
-I$(top_srcdir)/third_party/mbedtls/repo.patched/include \
|
||||
-include$(top_srcdir)/examples/platforms/da15000/custom_config_qspi.h \
|
||||
-Wno-unknown-pragmas \
|
||||
-Wno-sign-compare \
|
||||
@@ -52,6 +55,7 @@ libopenthread_da15000_a_CPPFLAGS
|
||||
-Wno-unused-variable \
|
||||
-Wno-missing-field-initializers \
|
||||
-fno-strict-aliasing \
|
||||
$(MBEDTLS_CPPFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
PLATFORM_SOURCES = \
|
||||
@@ -68,6 +72,7 @@ PLATFORM_SOURCES
|
||||
startup-gcc.c \
|
||||
clock.c \
|
||||
misc.c \
|
||||
crypto/aes_alt.c \
|
||||
$(NULL)
|
||||
|
||||
DIALOG_SOURCES = \
|
||||
@@ -82,6 +87,8 @@ DIALOG_SOURCES
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_watchdog.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/sys_tcs.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_uart.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_aes_hash.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_crypto.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_otpc.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_fem_sky66112-11.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_dma.c \
|
||||
|
||||
Executable → Regular
+22
@@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdk_defs.h"
|
||||
|
||||
//#include <tool.h>
|
||||
#define __NAKED __attribute__((naked))
|
||||
#define __USED __attribute__((used))
|
||||
@@ -111,4 +113,24 @@ void __USED __NAKED __NO_RETURN __gcc_program_start(void)
|
||||
while (1);
|
||||
}
|
||||
|
||||
uint32_t DA15000_phy_addr(uint32_t addr)
|
||||
{
|
||||
static const uint32_t remap[] =
|
||||
{
|
||||
MEMORY_ROM_BASE,
|
||||
MEMORY_OTP_BASE,
|
||||
MEMORY_QSPIF_BASE,
|
||||
MEMORY_SYSRAM_BASE,
|
||||
MEMORY_QSPIF_BASE,
|
||||
MEMORY_OTP_BASE,
|
||||
MEMORY_CACHERAM_BASE,
|
||||
0
|
||||
};
|
||||
|
||||
if (addr >= MEMORY_REMAPPED_END)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
return addr + remap[REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0)];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 "mbedtls/aes.h"
|
||||
#include "aes_alt.h"
|
||||
|
||||
#ifdef MBEDTLS_AES_ALT
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <common/code_utils.hpp>
|
||||
#include "hw_aes_hash.h"
|
||||
|
||||
static void mbedtls_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = (unsigned char *)v;
|
||||
|
||||
while (n--) { *p++ = 0; }
|
||||
}
|
||||
|
||||
void mbedtls_aes_init(mbedtls_aes_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_aes_context));
|
||||
}
|
||||
|
||||
void mbedtls_aes_free(mbedtls_aes_context *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hw_aes_hash_disable_clock();
|
||||
mbedtls_zeroize(ctx, sizeof(mbedtls_aes_context));
|
||||
}
|
||||
|
||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
switch (keybits)
|
||||
{
|
||||
case 128:
|
||||
ctx->hwKeyLen = HW_AES_128;
|
||||
memcpy(ctx->aes_enc_key, key, 16);
|
||||
break;
|
||||
|
||||
case 192:
|
||||
ctx->hwKeyLen = HW_AES_192;
|
||||
memcpy(ctx->aes_enc_key, key, 24);
|
||||
break;
|
||||
|
||||
case 256:
|
||||
ctx->hwKeyLen = HW_AES_256;
|
||||
memcpy(ctx->aes_enc_key, key, 32);
|
||||
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:
|
||||
ctx->hwKeyLen = HW_AES_128;
|
||||
memcpy(ctx->aes_dec_key, key, 16);
|
||||
break;
|
||||
|
||||
case 192:
|
||||
ctx->hwKeyLen = HW_AES_192;
|
||||
memcpy(ctx->aes_enc_key, key, 24);
|
||||
break;
|
||||
|
||||
case 256:
|
||||
ctx->hwKeyLen = HW_AES_256;
|
||||
memcpy(ctx->aes_enc_key, key, 32);
|
||||
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;
|
||||
|
||||
hw_aes_hash_enable_clock();
|
||||
hw_aes_hash_mark_input_block_as_last();
|
||||
hw_aes_hash_cfg_aes_ecb(ctx->hwKeyLen);
|
||||
hw_aes_hash_store_keys(ctx->hwKeyLen, ctx->aes_enc_key, HW_AES_PERFORM_KEY_EXPANSION);
|
||||
hw_aes_hash_cfg_dma((uint8_t *)input, (uint8_t *)output, 16);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case MBEDTLS_AES_ENCRYPT:
|
||||
hw_aes_hash_encrypt();
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
case MBEDTLS_AES_DECRYPT:
|
||||
hw_aes_hash_decrypt();
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
while (hw_aes_hash_is_active())
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
int retval = 0;
|
||||
mbedtls_aes_context aes;
|
||||
uint8_t input[16] = {0};
|
||||
uint8_t output[16] = {0};
|
||||
uint8_t decrypt[16] = {0};
|
||||
|
||||
strcpy((char *)input, (const char *)"hw_cryptaes_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 */
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 "da15000-mbedtls-config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_AES_ALT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
|
||||
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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -91,7 +91,7 @@
|
||||
|
||||
#define dg_configUSE_HW_TIMER0 (1)
|
||||
|
||||
|
||||
#define dg_configUSE_HW_AES_HASH (1)
|
||||
/*************************************************************************************************\
|
||||
* OS specific config
|
||||
*/
|
||||
|
||||
@@ -81,7 +81,7 @@ extern void SystemCoreClockUpdate (void);
|
||||
* \return physical address (for DMA, AES/HASH etc.) -- can be same or different as addr
|
||||
*
|
||||
*/
|
||||
extern uint32_t black_orca_phy_addr(uint32_t addr);
|
||||
extern uint32_t DA15000_phy_addr(uint32_t addr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,768 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup AES_HASH
|
||||
* \{
|
||||
* \brief AES/Hash Engine
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file hw_cpm.c
|
||||
*
|
||||
* @brief Clock and Power Manager Driver
|
||||
*
|
||||
* Copyright (c) 2016, Dialog Semiconductor
|
||||
* 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 HW_AES_HASH_H_
|
||||
#define HW_AES_HASH_H_
|
||||
|
||||
#if dg_configUSE_HW_AES_HASH
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sdk_defs.h>
|
||||
|
||||
/**
|
||||
* \brief AES/Hash callback
|
||||
*
|
||||
* This function is called by the AES/Hash driver when the interrupt is fired.
|
||||
*
|
||||
*/
|
||||
typedef void (*hw_aes_hash_cb)(void);
|
||||
|
||||
/**
|
||||
* \brief AES key sizes. Possible values: HW_AES_128, HW_AES_192, HW_AES_256.
|
||||
*/
|
||||
typedef enum {
|
||||
HW_AES_128 = 0,
|
||||
HW_AES_192 = 1,
|
||||
HW_AES_256 = 2
|
||||
} hw_aes_key_size;
|
||||
|
||||
/**
|
||||
* \brief AES direction. Possible values: HW_AES_DECRYPT, HW_AES_ENCRYPT.
|
||||
*/
|
||||
typedef enum {
|
||||
HW_AES_DECRYPT = 0,
|
||||
HW_AES_ENCRYPT = 1
|
||||
} hw_aes_direction;
|
||||
|
||||
/**
|
||||
* \brief AES/Hash modes. Possible values: HW_AES_ECB, HW_AES_CBC, HW_AES_CTR, HW_HASH_MD5,
|
||||
* HW_AES_SHA_1, HW_AES_SHA_256_224, HW_AES_SHA_256, HW_AES_SHA_384, HW_AES_SHA_512,
|
||||
* HW_AES_SHA_512_224, HW_AES_SHA_512_256.
|
||||
*/
|
||||
typedef enum {
|
||||
HW_AES_ECB,
|
||||
HW_AES_CBC,
|
||||
HW_AES_CTR,
|
||||
HW_HASH_MD5,
|
||||
HW_HASH_SHA_1,
|
||||
HW_HASH_SHA_256_224,
|
||||
HW_HASH_SHA_256,
|
||||
HW_HASH_SHA_384,
|
||||
HW_HASH_SHA_512,
|
||||
HW_HASH_SHA_512_224,
|
||||
HW_HASH_SHA_512_256
|
||||
} hw_aes_hash_mode;
|
||||
|
||||
/**
|
||||
* \brief Key expansion modes.
|
||||
* Possible values HW_AES_PERFORM_KEY_EXPANSION, HW_AES_DO_NOT_PERFORM_KEY_EXPANSION
|
||||
*/
|
||||
typedef enum {
|
||||
HW_AES_PERFORM_KEY_EXPANSION = 0, /**< Key expansion is performed by the engine */
|
||||
HW_AES_DO_NOT_PERFORM_KEY_EXPANSION /**< Key expansion is performed by the software */
|
||||
} hw_aes_hash_key_exp_t;
|
||||
|
||||
/**
|
||||
\brief AES/Hash setup structure.
|
||||
*/
|
||||
typedef struct {
|
||||
hw_aes_hash_mode mode; /**< AES/Hash mode. */
|
||||
hw_aes_direction aesDirection; /**< AES direction. Only used when the mode is an AES mode.*/
|
||||
hw_aes_key_size aesKeySize; /**< AES key size. Only used when the mode is an AES mode. */
|
||||
bool aesKeyExpand; /**< When true the key expansion process is execute. When false the key
|
||||
expansion process is not executed. The user should write the AES keys in CRYPTO_RAM.
|
||||
Only used when the mode is an AES mode. */
|
||||
uint32 aesKeys; /**< The start address of the buffer containing the AES key. */
|
||||
uint32 aesIvCtrblk_0_31; /**< In CBC mode IV[31:0] and in CTR mode the initial value of the
|
||||
32 bits counter. Only used when the mode is an AES CBC/CTR mode. */
|
||||
uint32 aesIvCtrblk_32_63; /**< In CBC mode IV[63:32] and in CTR[63:32].
|
||||
Only used when the mode is an AES CBC/CTR mode. */
|
||||
uint32 aesIvCtrblk_64_95; /**< In CBC mode IV[95:64] and in CTR[95:64].
|
||||
Only used when the mode is an AES CBC/CTR mode. */
|
||||
uint32 aesIvCtrblk_96_127; /**< In CBC mode IV[127:96] and in CTR[127:96].
|
||||
Only used when the mode is an AES CBC/CTR mode. */
|
||||
bool aesWriteBackAll; /**< When true all the AES resulting data is written to memory.
|
||||
When false only the final block of the AES resulting data is written to memory.
|
||||
Only used when the mode is an AES mode. */
|
||||
uint8 hashOutLength; /**< The number of bytes of the hash result to be saved to memory.
|
||||
Only used when mode is a Hash mode. */
|
||||
bool moreDataToCome; /**< When false this is the last data block. When true more data is to
|
||||
come. */
|
||||
uint32 sourceAddress; /**< The physical address of the input data that needs to be processed. */
|
||||
uint32 destinationAddress; /**< The physical address (RAM only) where the resulting data needs
|
||||
to be written. If NULL the register is not written.*/
|
||||
uint32 dataSize; /**< The number of bytes that need to be processed. If this number is not
|
||||
a multiple of a block size, the data is automatically extended with zeros. */
|
||||
bool enableInterrupt; /**< When true the callback function is called after the operation
|
||||
has ended. */
|
||||
hw_aes_hash_cb callback; /**< The callback function that is called when enable interrupt
|
||||
is true. */
|
||||
} hw_aes_hash_setup;
|
||||
|
||||
/**
|
||||
* \brief Enable AES/HASH engine clock
|
||||
*
|
||||
* This function enables the AES/HASH engine clock.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_enable_clock(void)
|
||||
{
|
||||
GLOBAL_INT_DISABLE();
|
||||
REG_SET_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE);
|
||||
GLOBAL_INT_RESTORE();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable AES/HASH engine clock
|
||||
*
|
||||
* This function disables the AES/HASH engine clock.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_disable_clock(void)
|
||||
{
|
||||
GLOBAL_INT_DISABLE();
|
||||
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE);
|
||||
GLOBAL_INT_RESTORE();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if AES/HASH engine clock is enabled
|
||||
*
|
||||
* \return Non-zero value if enabled, 0 otherwise
|
||||
*/
|
||||
__STATIC_INLINE int hw_aes_hash_clock_is_enabled(void)
|
||||
{
|
||||
return (CRG_TOP->CLK_AMBA_REG) & (CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief AES/Hash enable.
|
||||
*
|
||||
* This function sets up and starts a AES/HASH engine operation. All the
|
||||
* configuration details are included in the setup input structure.
|
||||
*
|
||||
* \param [in] setup The setup structure with setup values.
|
||||
*
|
||||
* \deprecated You can use hw_aes_hash_init with hw_aes_hash_start instead.
|
||||
*
|
||||
* \sa hw_aes_hash_init
|
||||
* \sa hw_aes_hash_start
|
||||
*
|
||||
*/
|
||||
void hw_aes_hash_enable(const hw_aes_hash_setup setup) DEPRECATED;
|
||||
|
||||
/**
|
||||
* \brief AES/Hash initialize.
|
||||
*
|
||||
* This function sets up a AES/HASH engine operation. All the configuration details
|
||||
* are included in the setup input structure. The operation can then start by calling
|
||||
* hw_aes_hash_start
|
||||
*
|
||||
* \param [in] setup The setup structure with setup values.
|
||||
*
|
||||
* \note There are some restrictions in the value of dataSize of the setup structure depending on
|
||||
* the mode. This function will do appropriate checking using assertions. The following
|
||||
* table shows what the value of dataSize should be:
|
||||
*
|
||||
* mode | moreDataToCome = true | moreDataToCome = false
|
||||
* ------------------- | --------------------- | ----------------------
|
||||
* HW_AES_ECB | multiple of 16 | multiple of 16
|
||||
* HW_AES_CBC | multiple of 16 | no restrictions
|
||||
* HW_AES_CTR | multiple of 16 | no restrictions
|
||||
* HW_HASH_MD5 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_1 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_256_224 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_256 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_384 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_512 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_512_224 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_512_256 | multiple of 8 | no restrictions
|
||||
*
|
||||
* \sa hw_aes_hash_start
|
||||
*
|
||||
*/
|
||||
void hw_aes_hash_init(hw_aes_hash_setup *setup);
|
||||
|
||||
/**
|
||||
* \brief AES/Hash restart.
|
||||
*
|
||||
* This function restarts the AES/Hash engine. This function can be used when the engine waits for
|
||||
* more input data.
|
||||
*
|
||||
* \param [in] sourceAddress The start address of the data that needs to be processed.
|
||||
* \param [in] dataSize The number of bytes that need to be processed. If this number is not
|
||||
* a multiple of a block size, the data is automatically extended with zeros.
|
||||
* \param [in] moreDataToCome When false this is the last data block. When true more data is to
|
||||
* come.
|
||||
*
|
||||
*/
|
||||
void hw_aes_hash_restart(const uint32 sourceAddress, const uint32 dataSize,
|
||||
const bool moreDataToCome);
|
||||
|
||||
/**
|
||||
* \brief AES/Hash is active.
|
||||
*
|
||||
* This function tells if the AES/Hash engine is active or not.
|
||||
*
|
||||
* \return True if the AES/Hash engine is active and false when it is inactive.
|
||||
*
|
||||
*/
|
||||
bool hw_aes_hash_is_active();
|
||||
|
||||
/**
|
||||
* \brief AES/Hash is waiting for more data.
|
||||
*
|
||||
* This function tells if the AES/Hash engine is waiting for more data or not.
|
||||
*
|
||||
* \return True if the AES/Hash engine is waiting more data and false when it is not.
|
||||
*
|
||||
*/
|
||||
bool hw_aes_hash_wait_for_in();
|
||||
|
||||
/**
|
||||
* \brief AES/Hash disable.
|
||||
*
|
||||
* This function disables the AES/HASH engine and its interrupt request signal.
|
||||
*
|
||||
* \param [in] waitTillInactive When true the AES/HASH engine is disabled after any pending operation
|
||||
* finishes. When false the AES/Hash is disabled immediately.
|
||||
*
|
||||
*/
|
||||
void hw_aes_hash_disable(const bool waitTillInactive);
|
||||
|
||||
/**
|
||||
* \brief Mark next input block as being last
|
||||
*
|
||||
* This function is used to configure the engine so as to consider the next input block
|
||||
* as the last of the operation. When the operation finishes, the engine's status
|
||||
* becomes "inactive".
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_mark_input_block_as_last(void)
|
||||
{
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark next input block as not being last
|
||||
*
|
||||
* This function is used to configure the engine so as to expect more input blocks
|
||||
* after the operation. When the operation finishes, the engine's status
|
||||
* becomes "waiting for input".
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_mark_input_block_as_not_last(void)
|
||||
{
|
||||
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for AES ECB encryption/decryption
|
||||
*
|
||||
* This function configures the engine for AES ECB encryption/decryption
|
||||
*
|
||||
* \param[in] key_size The size of the key used in the encryption/decryption
|
||||
*
|
||||
* \warning AES ECB is not recommended for use in cryptographic protocols.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_aes_ecb(hw_aes_key_size key_size)
|
||||
{
|
||||
uint32 crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg, key_size);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for AES CTR encryption/decryption
|
||||
*
|
||||
* This function configures the engine for AES CTR encryption/decryption
|
||||
*
|
||||
* \param[in] key_size The size of the key used in the encryption/decryption
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_aes_ctr(hw_aes_key_size key_size)
|
||||
{
|
||||
uint32 crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 2);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg, key_size);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for AES CBC encryption/decryption
|
||||
*
|
||||
* This function configures the engine for AES CBC encryption/decryption
|
||||
*
|
||||
* \param[in] key_size The size of the key used in the encryption/decryption
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_aes_cbc(hw_aes_key_size key_size)
|
||||
{
|
||||
uint32 crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 3);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg, key_size);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for MD5 hash
|
||||
*
|
||||
* This function configures the engine to perform MD5 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 16. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_md5(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 16)? 15: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA1 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA1 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 20. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha1(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 20)? 19: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 1);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA-224 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA-224 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 28. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha_224(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 28)? 27: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 2);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA-256 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA-256 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 32. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha_256(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 32)? 31: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 3);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA-384 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA-384 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 48. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha_384(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 48)? 47: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA-512 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA-512 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 64. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha_512(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 64)? 63: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 1);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA-512/224 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA-512/224 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 28. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha_512_224(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 28)? 27: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 2);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure engine for SHA-512/256 hash
|
||||
*
|
||||
* This function configures the engine to perform SHA-512/256 hashing
|
||||
*
|
||||
* \param[in] result_size The size in bytes of the result that the engine will write
|
||||
* to the output memory. Accepted values are 1 to 32. Out of
|
||||
* range values are adjusted to the closest limit.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_cfg_sha_512_256(unsigned int result_size)
|
||||
{
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(result_size > 32)? 31: (result_size == 0)? 0 : (result_size - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 3);
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Store initialization vector in AES/HASH engine memory
|
||||
*
|
||||
* This function stores the initialization vector (IV) that is necessary for AES CBC
|
||||
* mode.
|
||||
*
|
||||
*
|
||||
* \sa hw_aes_store_ic
|
||||
*
|
||||
* \param[in] iv The address of the buffer containing the initialization vector
|
||||
*/
|
||||
void hw_aes_hash_store_iv(const uint8 *iv);
|
||||
|
||||
/**
|
||||
* \brief Store counter initialization in AES/HASH engine memory
|
||||
*
|
||||
* This function stores the counter initialization that is necessary for AES CTR
|
||||
* mode.
|
||||
*
|
||||
*
|
||||
* \sa hw_aes_store_iv
|
||||
*
|
||||
* \param[in] ic The address of the buffer containing the counter initialization
|
||||
*/
|
||||
void hw_aes_hash_store_ic(const uint8 *ic);
|
||||
|
||||
/**
|
||||
* \brief Store AES keys in AES/HASH engine memory
|
||||
*
|
||||
* This function stores the keys used for AES encryption/decryption in AES/HASH engine memory.
|
||||
* If key expansion is performed by the engine, then aes_keys should contain only the base
|
||||
* key. Otherwise it should contain all the expanded keys.
|
||||
*
|
||||
* \note
|
||||
* After an AES operation with a certain key, further operations using the same key do not
|
||||
* need storing it to the AES/HASH memory again.
|
||||
*
|
||||
* \param[in] key_size The size of the key used in the encryption/decryption
|
||||
* \param[in] aes_keys The address of the buffer containing the keys
|
||||
* \param[in] key_exp Define if key expansion will be performed by hw or sw
|
||||
*/
|
||||
void hw_aes_hash_store_keys(hw_aes_key_size key_size, const uint8 *aes_keys, hw_aes_hash_key_exp_t key_exp);
|
||||
|
||||
/**
|
||||
* \brief Configure DMA for data manipulation
|
||||
*
|
||||
* This function configures the DMA machine with the source and destination buffers.
|
||||
*
|
||||
* \param[in] src The physical address of the buffer containing the input data for the operation
|
||||
* \param[in] dst The physical address (RAM or Cache RAM only) of the buffer where the output of the
|
||||
* operation will be stored. The dst address must be NULL when configuring the DMA
|
||||
* while the engine is waiting for more input data.
|
||||
* \param[in] len The length of the input data
|
||||
*/
|
||||
void hw_aes_hash_cfg_dma(const uint8 *src, uint8 *dst, unsigned int len);
|
||||
|
||||
/**
|
||||
* \brief Start AES/HASH engine operation
|
||||
*
|
||||
* This function starts a AES/HASH operation. The operation depends on the configuration that
|
||||
* has been applied before calling this function
|
||||
*
|
||||
* \sa hw_aes_hash_init
|
||||
*
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_start(void)
|
||||
{
|
||||
AES_HASH->CRYPTO_START_REG = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Start AES encryption
|
||||
*
|
||||
* This function starts an AES encryption. AES mode, key and input/output data should be configured
|
||||
* before calling this function.
|
||||
*
|
||||
* \sa hw_aes_hash_init
|
||||
* \sa hw_aes_hash_cfg_aes_ecb
|
||||
* \sa hw_aes_hash_cfg_aes_ctr
|
||||
* \sa hw_aes_hash_cfg_aes_cbc
|
||||
* \sa hw_aes_hash_store_keys
|
||||
* \sa hw_aes_hash_cfg_dma
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_encrypt(void)
|
||||
{
|
||||
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC);
|
||||
|
||||
AES_HASH->CRYPTO_START_REG = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Start AES decryption
|
||||
*
|
||||
* This function starts an AES decryption. AES mode, key and input/output data should be configured
|
||||
* before calling this function.
|
||||
*
|
||||
* \sa hw_aes_hash_init
|
||||
* \sa hw_aes_hash_cfg_aes_ecb
|
||||
* \sa hw_aes_hash_cfg_aes_ctr
|
||||
* \sa hw_aes_hash_cfg_aes_cbc
|
||||
* \sa hw_aes_hash_store_keys
|
||||
* \sa hw_aes_hash_cfg_dma
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_decrypt(void)
|
||||
{
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC);
|
||||
|
||||
AES_HASH->CRYPTO_START_REG = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable AES/HASH engine interrupt
|
||||
*
|
||||
* This function enables the AES/HASH engine interrupt and sets a callback function
|
||||
* to be called when the interrupt occurs.
|
||||
*
|
||||
* \param[in] cb The callback function for the interrupt
|
||||
*
|
||||
* \deprecated Consider using hw_crypto API along with hw_aes_hash_enable_interrupt_source()
|
||||
*/
|
||||
DEPRECATED_MSG("consider using hw_crypto API along with hw_aes_hash_enable_interrupt_source")
|
||||
void hw_aes_hash_enable_interrupt(hw_aes_hash_cb cb);
|
||||
|
||||
/**
|
||||
* \brief Disable AES/HASH engine interrupt
|
||||
*
|
||||
* This function disables the AES/HASH engine interrupt.
|
||||
*
|
||||
* \deprecated Consider using hw_crypto API along with hw_aes_hash_disable_interrupt_source()
|
||||
*/
|
||||
DEPRECATED_MSG("consider using hw_crypto API along with hw_aes_hash_disable_interrupt_source")
|
||||
void hw_aes_hash_disable_interrupt(void);
|
||||
|
||||
/**
|
||||
* \brief Enable AES/HASH engine interrupt source
|
||||
*
|
||||
* This function enables AES/HASH engine interrupt source.
|
||||
*
|
||||
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
|
||||
* function does not enable the CRYPTO interrupt itself. Use hw_crypto_enable_aes_hash_interrupt()
|
||||
* in addition, in order to enable the CRYPTO interrupt.
|
||||
*/
|
||||
static inline void hw_aes_hash_enable_interrupt_source(void)
|
||||
{
|
||||
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable AES/HASH engine interrupt source
|
||||
*
|
||||
* This function disables AES/HASH engine interrupt source.
|
||||
*
|
||||
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
|
||||
* function does not disable the CRYPTO interrupt itself. Use hw_crypto_disable_aes_hash_interrupt()
|
||||
* in order to disable the CRYPTO interrupt.
|
||||
*/
|
||||
static inline void hw_aes_hash_disable_interrupt_source(void)
|
||||
{
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear AES/HASH engine pending interrupt
|
||||
*
|
||||
* This function clears AES/HASH engine pending interrupt request.
|
||||
*
|
||||
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
|
||||
* function does not clear pending CRYPTO interrupt. Use hw_crypto_clear_pending_interrupt()
|
||||
* in order to clear pending CRYPTO interrupt.
|
||||
*/
|
||||
static inline void hw_aes_hash_clear_interrupt_req(void)
|
||||
{
|
||||
AES_HASH->CRYPTO_CLRIRQ_REG = 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set output mode to write all
|
||||
*
|
||||
* This function configures the AES/HASH engine to write back to memory all the
|
||||
* resulting data.
|
||||
*
|
||||
* \note
|
||||
* Only applicable to AES operations.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_output_mode_write_all(void)
|
||||
{
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set output mode to write final
|
||||
*
|
||||
* This function configures the AES/HASH engine to write back to memory only the
|
||||
* the last block of the resulting data.
|
||||
*
|
||||
* \note
|
||||
* Only applicable to AES operations.
|
||||
*/
|
||||
__STATIC_INLINE void hw_aes_hash_output_mode_write_final(void)
|
||||
{
|
||||
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check input data size restriction
|
||||
*
|
||||
* This function checks the restrictions of input data length. It returns 0 if the restrictions are not
|
||||
* violated, -1 otherwise. It checks the configured values at the time it is called so it should be
|
||||
* used just before starting an operation. The function can be useful for debugging. The following
|
||||
* table summarizes the restrictions for the input data length.
|
||||
*
|
||||
* ALGORITHM | NOT LAST DATA BLOCK | LAST DATA BLOCK
|
||||
* ------------------- | --------------------- | ----------------
|
||||
* HW_AES_ECB | multiple of 16 | multiple of 16
|
||||
* HW_AES_CBC | multiple of 16 | no restrictions
|
||||
* HW_AES_CTR | multiple of 16 | no restrictions
|
||||
* HW_HASH_MD5 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_1 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_256_224 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_256 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_384 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_512 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_512_224 | multiple of 8 | no restrictions
|
||||
* HW_HASH_SHA_512_256 | multiple of 8 | no restrictions
|
||||
*
|
||||
*/
|
||||
int hw_aes_hash_check_restrictions(void);
|
||||
|
||||
#endif /* dg_configUSE_HW_AES_HASH */
|
||||
|
||||
#endif /* HW_AES_HASH_H_ */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup CRYPTO
|
||||
* \{
|
||||
* \brief Interrupt handling for the crypto engines (AES/HASH, ECC)
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file hw_cpm.c
|
||||
*
|
||||
* @brief Clock and Power Manager Driver
|
||||
*
|
||||
* Copyright (c) 2016, Dialog Semiconductor
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC)
|
||||
|
||||
#include <sdk_defs.h>
|
||||
|
||||
/**
|
||||
* \brief Crypto engines callback
|
||||
*
|
||||
* This function type is used for callbacks called when the crypto engines (AES/HASH, ECC)
|
||||
* generate an interrupt.
|
||||
*
|
||||
* \param [in] status The status register (either AES/HASH or ECC) at the time of the interrupt.
|
||||
*
|
||||
*/
|
||||
typedef void (*hw_crypto_cb)(unsigned int status);
|
||||
|
||||
/**
|
||||
* \brief Enable interrupt for AES/HASH crypto engine.
|
||||
*
|
||||
* \param [in] cb A callback to be called when interrupt occurs. It must always be provided.
|
||||
*
|
||||
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
|
||||
* function only enables CRYPTO interrupt itself and registers a callback for AES/HASH
|
||||
* related CRYPTO interrupts. In order to fully enable AES/HASH interrupts
|
||||
* hw_aes_hash_enable_interrupt_source() must also be called
|
||||
*/
|
||||
void hw_crypto_enable_aes_hash_interrupt(hw_crypto_cb cb);
|
||||
|
||||
/**
|
||||
* \brief Enable interrupt for ECC crypto engine.
|
||||
*
|
||||
* \param [in] cb A callback to be called when interrupt occurs. It must always be provided.
|
||||
*/
|
||||
void hw_crypto_enable_ecc_interrupt(hw_crypto_cb cb);
|
||||
|
||||
/**
|
||||
* \brief Disable interrupt for AES/HASH crypto engine.
|
||||
*/
|
||||
void hw_crypto_disable_aes_hash_interrupt(void);
|
||||
|
||||
/**
|
||||
* \brief Disable interrupt for ECC crypto engine.
|
||||
*/
|
||||
void hw_crypto_disable_ecc_interrupt(void);
|
||||
|
||||
/**
|
||||
* \brief Clear pending interrupt from AES/HASH and ECC crypto engines.
|
||||
*
|
||||
* \note This function clears the pending CRYPTO interrupt only on the NVI Controller.
|
||||
* Use hw_aes_hash_clear_interrupt_req() and hw_ecc_clear_interrupt_source() to clear the
|
||||
* source of CRYPTO interrupt on the AES/HASH and ECC engines respectively.
|
||||
*/
|
||||
static inline void hw_crypto_clear_pending_interrupt(void)
|
||||
{
|
||||
NVIC_ClearPendingIRQ(CRYPTO_IRQn);
|
||||
}
|
||||
|
||||
#endif /* (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC) */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup AES_HASH
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file hw_cpm.c
|
||||
*
|
||||
* @brief Clock and Power Manager Driver
|
||||
*
|
||||
* Copyright (c) 2016, Dialog Semiconductor
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if dg_configUSE_HW_AES_HASH
|
||||
|
||||
#include "hw_aes_hash.h"
|
||||
#include "hw_crypto.h"
|
||||
|
||||
#define MODE_IS_AES(m) (m <= HW_AES_CTR)
|
||||
|
||||
static void hw_aes_hash_wait_on_inactive(void)
|
||||
{
|
||||
while (!REG_GETF(AES_HASH, CRYPTO_STATUS_REG, CRYPTO_INACTIVE)) {
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
static void hw_aes_hash_set_mode(const hw_aes_hash_setup* setup)
|
||||
{
|
||||
uint32_t crypt0_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
|
||||
switch (setup->mode) {
|
||||
case HW_AES_ECB:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
|
||||
break;
|
||||
case HW_AES_CBC:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 3);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
|
||||
AES_HASH->CRYPTO_MREG0_REG = setup->aesIvCtrblk_0_31;
|
||||
AES_HASH->CRYPTO_MREG1_REG = setup->aesIvCtrblk_32_63;
|
||||
AES_HASH->CRYPTO_MREG2_REG = setup->aesIvCtrblk_64_95;
|
||||
AES_HASH->CRYPTO_MREG3_REG = setup->aesIvCtrblk_96_127;
|
||||
break;
|
||||
case HW_AES_CTR:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 2);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
|
||||
AES_HASH->CRYPTO_MREG0_REG = setup->aesIvCtrblk_0_31;
|
||||
AES_HASH->CRYPTO_MREG1_REG = setup->aesIvCtrblk_32_63;
|
||||
AES_HASH->CRYPTO_MREG2_REG = setup->aesIvCtrblk_64_95;
|
||||
AES_HASH->CRYPTO_MREG3_REG = setup->aesIvCtrblk_96_127;
|
||||
break;
|
||||
case HW_HASH_MD5:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
|
||||
break;
|
||||
case HW_HASH_SHA_1:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 1);
|
||||
break;
|
||||
case HW_HASH_SHA_256_224:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 2);
|
||||
break;
|
||||
case HW_HASH_SHA_256:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 3);
|
||||
break;
|
||||
case HW_HASH_SHA_384:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
|
||||
break;
|
||||
case HW_HASH_SHA_512:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 1);
|
||||
break;
|
||||
case HW_HASH_SHA_512_224:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 2);
|
||||
break;
|
||||
case HW_HASH_SHA_512_256:
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 3);
|
||||
break;
|
||||
}
|
||||
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypt0_ctrl_reg;
|
||||
}
|
||||
|
||||
static void hw_aes_hash_check_data_size(const hw_aes_hash_setup* setup)
|
||||
{
|
||||
switch (setup->mode) {
|
||||
case HW_AES_ECB:
|
||||
// In ECB mode the dataSize needs to be a multiple of 16.
|
||||
ASSERT_ERROR(setup->dataSize % 0x10 == 0);
|
||||
break;
|
||||
case HW_AES_CBC:
|
||||
case HW_AES_CTR:
|
||||
// If more data is to come in CBC or CTR mode the dataSize needs to be a multiple of 16.
|
||||
if (setup->moreDataToCome) {
|
||||
ASSERT_ERROR(setup->dataSize % 0x10 == 0);
|
||||
}
|
||||
break;
|
||||
case HW_HASH_MD5:
|
||||
case HW_HASH_SHA_1:
|
||||
case HW_HASH_SHA_256_224:
|
||||
case HW_HASH_SHA_256:
|
||||
case HW_HASH_SHA_384:
|
||||
case HW_HASH_SHA_512:
|
||||
case HW_HASH_SHA_512_224:
|
||||
case HW_HASH_SHA_512_256:
|
||||
// If more data is to come in hash mode the dataSize needs to be a multiple of 8.
|
||||
if (setup->moreDataToCome) {
|
||||
ASSERT_ERROR(setup->dataSize % 0x8 == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hw_aes_hash_cb hw_aes_hash_old_style_cb = NULL;
|
||||
|
||||
static void hw_aes_hash_old_cb_style_support(unsigned int status)
|
||||
{
|
||||
if (hw_aes_hash_old_style_cb) {
|
||||
hw_aes_hash_old_style_cb();
|
||||
}
|
||||
}
|
||||
|
||||
void hw_aes_hash_enable_interrupt(hw_aes_hash_cb cb)
|
||||
{
|
||||
hw_aes_hash_old_style_cb = cb;
|
||||
hw_crypto_enable_aes_hash_interrupt(hw_aes_hash_old_cb_style_support);
|
||||
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
|
||||
}
|
||||
|
||||
void hw_aes_hash_disable_interrupt(void)
|
||||
{
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
|
||||
hw_crypto_disable_aes_hash_interrupt();
|
||||
}
|
||||
|
||||
static inline uint32 hw_aes_hash_construct_word(const uint8 *data)
|
||||
{
|
||||
if ((uint32)data & 0x3) {
|
||||
uint32 internal_buf;
|
||||
uint8 *p = (uint8 *)&internal_buf + 3;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
*(p--) = *(data++);
|
||||
}
|
||||
|
||||
return internal_buf;
|
||||
}
|
||||
else {
|
||||
return SWAP32(*(uint32 *)data);
|
||||
}
|
||||
}
|
||||
|
||||
void hw_aes_hash_store_keys(hw_aes_key_size key_size, const uint8 *aes_keys, hw_aes_hash_key_exp_t key_exp)
|
||||
{
|
||||
volatile uint32 *kmem_ptr = &AES_HASH->CRYPTO_KEYS_START;
|
||||
unsigned int key_wrds;
|
||||
|
||||
if (key_exp == HW_AES_DO_NOT_PERFORM_KEY_EXPANSION) {
|
||||
/* Key expansion is provided by the software */
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP);
|
||||
key_wrds = (key_size == HW_AES_256) ? 60 : (key_size == HW_AES_192) ? 52 : 44;
|
||||
}
|
||||
else {
|
||||
/* Key expansion needs to be performed by the engine */
|
||||
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP);
|
||||
key_wrds = (key_size == HW_AES_256) ? 8 : (key_size == HW_AES_192) ? 6 : 4;
|
||||
}
|
||||
|
||||
do {
|
||||
*(kmem_ptr++) = hw_aes_hash_construct_word(aes_keys);
|
||||
aes_keys += 4;
|
||||
key_wrds--;
|
||||
} while (key_wrds > 0);
|
||||
}
|
||||
|
||||
void hw_aes_hash_enable(const hw_aes_hash_setup setup)
|
||||
{
|
||||
hw_aes_hash_check_data_size(&setup);
|
||||
|
||||
hw_aes_hash_enable_clock();
|
||||
|
||||
hw_aes_hash_set_mode(&setup);
|
||||
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN, crypto_ctrl_reg,
|
||||
setup.moreDataToCome);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(setup.hashOutLength - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC, crypto_ctrl_reg,
|
||||
setup.aesDirection);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP, crypto_ctrl_reg,
|
||||
setup.aesKeyExpand);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg,
|
||||
setup.aesKeySize);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD, crypto_ctrl_reg,
|
||||
!setup.aesWriteBackAll);
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
|
||||
if (MODE_IS_AES(setup.mode)) {
|
||||
hw_aes_hash_store_keys(setup.aesKeySize, (uint8 *)setup.aesKeys, !setup.aesKeyExpand);
|
||||
}
|
||||
|
||||
hw_aes_hash_cfg_dma((const uint8 *)setup.sourceAddress, (uint8 *)setup.destinationAddress,
|
||||
(unsigned int)setup.dataSize);
|
||||
|
||||
if (setup.enableInterrupt) {
|
||||
hw_aes_hash_old_style_cb = setup.callback;
|
||||
hw_aes_hash_enable_interrupt_source();
|
||||
hw_crypto_enable_aes_hash_interrupt(hw_aes_hash_old_cb_style_support);
|
||||
}
|
||||
else {
|
||||
hw_aes_hash_disable_interrupt_source();
|
||||
hw_crypto_disable_aes_hash_interrupt();
|
||||
}
|
||||
|
||||
hw_aes_hash_start();
|
||||
}
|
||||
|
||||
void hw_aes_hash_init(hw_aes_hash_setup *setup)
|
||||
{
|
||||
hw_aes_hash_check_data_size(setup);
|
||||
|
||||
hw_aes_hash_enable_clock();
|
||||
|
||||
hw_aes_hash_set_mode(setup);
|
||||
|
||||
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN, crypto_ctrl_reg,
|
||||
setup->moreDataToCome);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
|
||||
(setup->hashOutLength - 1));
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC, crypto_ctrl_reg,
|
||||
setup->aesDirection);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP, crypto_ctrl_reg,
|
||||
setup->aesKeyExpand);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg,
|
||||
setup->aesKeySize);
|
||||
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD, crypto_ctrl_reg,
|
||||
!setup->aesWriteBackAll);
|
||||
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
|
||||
|
||||
if (MODE_IS_AES(setup->mode)) {
|
||||
hw_aes_hash_store_keys(setup->aesKeySize, (uint8 *)setup->aesKeys, !setup->aesKeyExpand);
|
||||
}
|
||||
|
||||
hw_aes_hash_cfg_dma((const uint8 *)setup->sourceAddress, (uint8 *)setup->destinationAddress,
|
||||
(unsigned int)setup->dataSize);
|
||||
|
||||
if (setup->enableInterrupt) {
|
||||
hw_aes_hash_old_style_cb = setup->callback;
|
||||
hw_aes_hash_enable_interrupt_source();
|
||||
hw_crypto_enable_aes_hash_interrupt(hw_aes_hash_old_cb_style_support);
|
||||
}
|
||||
else {
|
||||
hw_aes_hash_disable_interrupt_source();
|
||||
hw_crypto_disable_aes_hash_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void hw_aes_hash_restart(const uint32 sourceAddress, const uint32 dataSize,
|
||||
const bool moreDataToCome)
|
||||
{
|
||||
hw_aes_hash_cfg_dma((const uint8 *)sourceAddress, NULL, (unsigned int)dataSize);
|
||||
REG_SETF(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN, moreDataToCome);
|
||||
hw_aes_hash_start();
|
||||
}
|
||||
|
||||
bool hw_aes_hash_is_active()
|
||||
{
|
||||
return REG_GETF(AES_HASH, CRYPTO_STATUS_REG, CRYPTO_INACTIVE) == 0;
|
||||
}
|
||||
|
||||
bool hw_aes_hash_wait_for_in()
|
||||
{
|
||||
return REG_GETF(AES_HASH, CRYPTO_STATUS_REG, CRYPTO_WAIT_FOR_IN) == 1;
|
||||
}
|
||||
|
||||
void hw_aes_hash_disable(const bool waitOnFinish)
|
||||
{
|
||||
if (waitOnFinish)
|
||||
hw_aes_hash_wait_on_inactive();
|
||||
|
||||
hw_aes_hash_disable_interrupt_source();
|
||||
AES_HASH->CRYPTO_CLRIRQ_REG = 1;
|
||||
GLOBAL_INT_DISABLE();
|
||||
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE);
|
||||
GLOBAL_INT_RESTORE();
|
||||
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN);
|
||||
}
|
||||
|
||||
void hw_aes_hash_cfg_dma(const uint8 *src, uint8 *dst, unsigned int len)
|
||||
{
|
||||
/* Source address setting */
|
||||
AES_HASH->CRYPTO_FETCH_ADDR_REG = DA15000_phy_addr((uint32)src);
|
||||
|
||||
/* Destination address setting */
|
||||
if (dst) {
|
||||
unsigned int remap_type = REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0);
|
||||
|
||||
if (IS_SYSRAM_ADDRESS(dst) ||
|
||||
(IS_REMAPPED_ADDRESS(dst) && (remap_type == 0x3))) {
|
||||
AES_HASH->CRYPTO_DEST_ADDR_REG = DA15000_phy_addr((uint32)dst);
|
||||
#if dg_configEXEC_MODE != MODE_IS_CACHED
|
||||
} else if (IS_CACHERAM_ADDRESS(dst)) {
|
||||
AES_HASH->CRYPTO_DEST_ADDR_REG = DA15000_phy_addr((uint32)dst);
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* Destination address can only reside in RAM or Cache RAM, but in case of remapped
|
||||
* address, REMAP_ADR0 cannot be 0x6 (Cache Data RAM)
|
||||
*/
|
||||
ASSERT_ERROR(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Data length setting */
|
||||
AES_HASH->CRYPTO_LEN_REG = (uint32)len;
|
||||
}
|
||||
|
||||
static void hw_aes_hash_store_in_mode_dependent_regs(const uint8 *buf)
|
||||
{
|
||||
AES_HASH->CRYPTO_MREG0_REG = hw_aes_hash_construct_word(buf + 12);
|
||||
AES_HASH->CRYPTO_MREG1_REG = hw_aes_hash_construct_word(buf + 8);
|
||||
AES_HASH->CRYPTO_MREG2_REG = hw_aes_hash_construct_word(buf + 4);
|
||||
AES_HASH->CRYPTO_MREG3_REG = hw_aes_hash_construct_word(buf + 0);
|
||||
}
|
||||
|
||||
void hw_aes_hash_store_iv(const uint8 *iv)
|
||||
{
|
||||
hw_aes_hash_store_in_mode_dependent_regs(iv);
|
||||
}
|
||||
|
||||
void hw_aes_hash_store_ic(const uint8 *ic)
|
||||
{
|
||||
hw_aes_hash_store_in_mode_dependent_regs(ic);
|
||||
}
|
||||
|
||||
int hw_aes_hash_check_restrictions(void)
|
||||
{
|
||||
unsigned int is_hash = AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk;
|
||||
unsigned int more_in = AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk;
|
||||
|
||||
if (is_hash) {
|
||||
if (more_in && (AES_HASH->CRYPTO_LEN_REG & 0x7)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned int is_ecb = (((AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk) == 0) |
|
||||
((AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk) == 0x0100));
|
||||
|
||||
if ((is_ecb || more_in) && (AES_HASH->CRYPTO_LEN_REG & 0x15)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* dg_configUSE_HW_AES_HASH */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup CRYPTO
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file hw_cpm.c
|
||||
*
|
||||
* @brief Clock and Power Manager Driver
|
||||
*
|
||||
* Copyright (c) 2016, Dialog Semiconductor
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC)
|
||||
|
||||
#include "hw_crypto.h"
|
||||
|
||||
#if (dg_configSYSTEMVIEW)
|
||||
# include "SEGGER_SYSVIEW_FreeRTOS.h"
|
||||
#else
|
||||
# define SEGGER_SYSTEMVIEW_ISR_ENTER()
|
||||
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
|
||||
#endif
|
||||
|
||||
__RETAINED static hw_crypto_cb hw_crypto_aes_hash_cb;
|
||||
__RETAINED static hw_crypto_cb hw_crypto_ecc_cb;
|
||||
|
||||
void hw_crypto_enable_aes_hash_interrupt(hw_crypto_cb cb)
|
||||
{
|
||||
/* A callback for the interrupt must be provided */
|
||||
ASSERT_ERROR(cb);
|
||||
hw_crypto_aes_hash_cb = cb;
|
||||
NVIC_EnableIRQ(CRYPTO_IRQn);
|
||||
}
|
||||
|
||||
void hw_crypto_enable_ecc_interrupt(hw_crypto_cb cb)
|
||||
{
|
||||
/* A callback for the interrupt must be provided */
|
||||
ASSERT_ERROR(cb);
|
||||
hw_crypto_ecc_cb = cb;
|
||||
NVIC_EnableIRQ(CRYPTO_IRQn);
|
||||
}
|
||||
|
||||
void hw_crypto_disable_aes_hash_interrupt(void)
|
||||
{
|
||||
hw_crypto_aes_hash_cb = NULL;
|
||||
if (!hw_crypto_ecc_cb) {
|
||||
NVIC_DisableIRQ(CRYPTO_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
void hw_crypto_disable_ecc_interrupt(void)
|
||||
{
|
||||
hw_crypto_ecc_cb = NULL;
|
||||
if (!hw_crypto_aes_hash_cb) {
|
||||
NVIC_DisableIRQ(CRYPTO_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
void CRYPTO_Handler(void)
|
||||
{
|
||||
SEGGER_SYSTEMVIEW_ISR_ENTER();
|
||||
|
||||
uint32_t status = AES_HASH->CRYPTO_STATUS_REG;
|
||||
|
||||
/* In case both AES/HASH and ECC have triggered an interrupt, first the AES/HASH
|
||||
will be served, and then the ISR will be called again since the ECC interrupt
|
||||
source is only cleared by reading its status register */
|
||||
if (status & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Msk) {
|
||||
/* Clear AES/HASH interrupt source */
|
||||
AES_HASH->CRYPTO_CLRIRQ_REG = 0x1;
|
||||
|
||||
if (hw_crypto_aes_hash_cb != NULL) {
|
||||
hw_crypto_aes_hash_cb(status);
|
||||
}
|
||||
} else {
|
||||
/* Clear ECC interrupt source */
|
||||
status = ECC->ECC_STATUS_REG;
|
||||
|
||||
if (hw_crypto_ecc_cb != NULL) {
|
||||
hw_crypto_ecc_cb(status);
|
||||
}
|
||||
}
|
||||
|
||||
SEGGER_SYSTEMVIEW_ISR_EXIT();
|
||||
}
|
||||
|
||||
|
||||
#endif /* (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC) */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
|
||||
@@ -216,8 +216,8 @@ void hw_dma_channel_initialization(DMA_setup *channel_setup)
|
||||
}
|
||||
|
||||
#endif
|
||||
src_address = black_orca_phy_addr(channel_setup->src_address);
|
||||
dest_address = black_orca_phy_addr(channel_setup->dest_address);
|
||||
src_address = DA15000_phy_addr(channel_setup->src_address);
|
||||
dest_address = DA15000_phy_addr(channel_setup->dest_address);
|
||||
|
||||
// Set source address registers
|
||||
*dma_x_a_start_low_reg = (src_address & 0xffff);
|
||||
@@ -257,7 +257,7 @@ void hw_dma_channel_initialization(DMA_setup *channel_setup)
|
||||
void hw_dma_channel_update_source(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
|
||||
hw_dma_transfer_cb cb)
|
||||
{
|
||||
uint32_t phy_addr = black_orca_phy_addr((uint32_t) addr);
|
||||
uint32_t phy_addr = DA15000_phy_addr((uint32_t) addr);
|
||||
|
||||
dma_callbacks_user_data[channel].callback = cb;
|
||||
|
||||
@@ -286,7 +286,7 @@ void hw_dma_channel_update_source(HW_DMA_CHANNEL channel, void *addr, uint16_t l
|
||||
void hw_dma_channel_update_destination(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
|
||||
hw_dma_transfer_cb cb)
|
||||
{
|
||||
uint32_t phy_addr = black_orca_phy_addr((uint32_t) addr);
|
||||
uint32_t phy_addr = DA15000_phy_addr((uint32_t) addr);
|
||||
|
||||
dma_callbacks_user_data[channel].callback = cb;
|
||||
|
||||
|
||||
@@ -757,12 +757,12 @@ bool hw_otpc_dma_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD
|
||||
if (IS_SYSRAM_ADDRESS(p_data) ||
|
||||
(IS_REMAPPED_ADDRESS(p_data) && (remap_type == 0x3)))
|
||||
{
|
||||
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
|
||||
OTPC->OTPC_AHBADR_REG = DA15000_phy_addr((uint32_t)p_data);
|
||||
#if dg_configEXEC_MODE != MODE_IS_CACHED
|
||||
}
|
||||
else if (IS_CACHERAM_ADDRESS(p_data))
|
||||
{
|
||||
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
|
||||
OTPC->OTPC_AHBADR_REG = DA15000_phy_addr((uint32_t)p_data);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -831,12 +831,12 @@ void hw_otpc_dma_read(uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_
|
||||
if (IS_SYSRAM_ADDRESS(p_data) ||
|
||||
(IS_REMAPPED_ADDRESS(p_data) && (remap_type == 0x3)))
|
||||
{
|
||||
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
|
||||
OTPC->OTPC_AHBADR_REG = DA15000_phy_addr((uint32_t)p_data);
|
||||
#if dg_configEXEC_MODE != MODE_IS_CACHED
|
||||
}
|
||||
else if (IS_CACHERAM_ADDRESS(p_data))
|
||||
{
|
||||
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
|
||||
OTPC->OTPC_AHBADR_REG = DA15000_phy_addr((uint32_t)p_data);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user