[NUC472/M487] Coordinate crypto init among AES/DES/SHA/PRNG

Add counter to track crypto init among crypto sub-modules. It includes:
1. Enable crypto clock
2. Enable crypto interrupt

As counter gets zero, crypto clock is disabled to save power.
pull/4925/head
ccli8 2017-09-26 14:16:35 +08:00
parent b0eededdaf
commit d66074fecc
12 changed files with 161 additions and 56 deletions

View File

@ -34,8 +34,7 @@
#include "mbed_assert.h"
#include "mbed_error.h"
#include "nu_bitutil.h"
#include "crypto-misc.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
@ -69,15 +68,6 @@ static bool aes_dma_buff_compat(const void *buff, unsigned buff_size)
void mbedtls_aes_init( mbedtls_aes_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
/* Unlock protected registers */
SYS_UnlockReg();
CLK_EnableModuleClock(CRPT_MODULE);
/* Lock protected registers */
SYS_LockReg();
NVIC_EnableIRQ(CRPT_IRQn);
AES_ENABLE_INT();
}
void mbedtls_aes_free( mbedtls_aes_context *ctx )
@ -153,6 +143,11 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
}
/* Init crypto module */
crypto_init();
/* Enable AES interrupt */
AES_ENABLE_INT();
/* We support multiple contexts with context save & restore and so needs just one
* H/W channel. Always use H/W channel #0. */
@ -195,6 +190,11 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
ctx->iv[1] = CRPT->AES_FDBCK[1];
ctx->iv[2] = CRPT->AES_FDBCK[2];
ctx->iv[3] = CRPT->AES_FDBCK[3];
/* Disable AES interrupt */
AES_DISABLE_INT();
/* Uninit crypto module */
crypto_uninit();
}
/*

View File

@ -17,21 +17,62 @@
#include "cmsis.h"
#include "mbed_assert.h"
#include "mbed_critical.h"
#include "mbed_error.h"
#include <limits.h>
#include "nu_modutil.h"
#include "nu_bitutil.h"
#include "crypto-misc.h"
static int crypto_inited = 0;
static int crypto_sha_avail = 1;
/* Crypto (AES, DES, SHA, etc.) init counter. Crypto's keeps active as it is non-zero. */
static uint16_t crypto_init_counter = 0U;
/* As crypto init counter changes from 0 to 1:
*
* 1. Enable crypto clock
* 2. Enable crypto interrupt
*/
void crypto_init(void)
{
if (crypto_inited) {
return;
core_util_critical_section_enter();
if (crypto_init_counter == USHRT_MAX) {
core_util_critical_section_exit();
error("Crypto clock enable counter would overflow (> USHRT_MAX)");
}
crypto_inited = 1;
core_util_atomic_incr_u16(&crypto_init_counter, 1);
if (crypto_init_counter == 1) {
SYS_UnlockReg(); // Unlock protected register
CLK_EnableModuleClock(CRPT_MODULE);
SYS_LockReg(); // Lock protected register
CLK_EnableModuleClock(CRPT_MODULE);
NVIC_EnableIRQ(CRPT_IRQn);
}
core_util_critical_section_exit();
}
/* As crypto init counter changes from 1 to 0:
*
* 1. Disable crypto interrupt
* 2. Disable crypto clock
*/
void crypto_uninit(void)
{
core_util_critical_section_enter();
if (crypto_init_counter == 0) {
core_util_critical_section_exit();
error("Crypto clock enable counter would underflow (< 0)");
}
core_util_atomic_decr_u16(&crypto_init_counter, 1);
if (crypto_init_counter == 0) {
NVIC_DisableIRQ(CRPT_IRQn);
SYS_UnlockReg(); // Unlock protected register
CLK_DisableModuleClock(CRPT_MODULE);
SYS_LockReg(); // Lock protected register
}
core_util_critical_section_exit();
}
/* Implementation that should never be optimized out by the compiler */

View File

@ -22,6 +22,7 @@ extern "C" {
#endif
void crypto_init(void);
void crypto_uninit(void);
void crypto_zeroize(void *v, size_t n);
int crypto_sha_acquire(void);
void crypto_sha_release(void);

View File

@ -49,7 +49,6 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
void mbedtls_des_init(mbedtls_des_context *ctx)
{
crypto_init();
memset(ctx, 0, sizeof(mbedtls_des_context));
}
@ -64,7 +63,6 @@ void mbedtls_des_free( mbedtls_des_context *ctx )
void mbedtls_des3_init( mbedtls_des3_context *ctx )
{
crypto_init();
memset(ctx, 0, sizeof(mbedtls_des3_context));
}
@ -329,6 +327,9 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
error("Buffer for DES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
}
/* Init crypto module */
crypto_init();
// NOTE: Don't call driver function TDES_Open in BSP because it doesn't support TDES_CTL[3KEYS] setting.
CRPT->TDES_CTL = (0 << CRPT_TDES_CTL_CHANNEL_Pos) | (enc << CRPT_TDES_CTL_ENCRPT_Pos) |
tdes_opmode | (TDES_IN_OUT_WHL_SWAP << CRPT_TDES_CTL_BLKSWAP_Pos);
@ -418,6 +419,9 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
}
}
/* Uninit crypto module */
crypto_uninit();
return 0;
}

View File

@ -39,6 +39,7 @@ void crypto_sha_getinternstate(unsigned char output[], size_t olen);
void mbedtls_sha1_hw_init(crypto_sha_context *ctx)
{
/* Init crypto module */
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
@ -49,6 +50,8 @@ void mbedtls_sha1_hw_free(crypto_sha_context *ctx)
return;
}
/* Uninit crypto module */
crypto_uninit();
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
@ -113,6 +116,7 @@ void mbedtls_sha1_hw_process(crypto_sha_context *ctx, const unsigned char data[6
void mbedtls_sha256_hw_init(crypto_sha_context *ctx)
{
/* Init crypto module */
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
@ -123,6 +127,8 @@ void mbedtls_sha256_hw_free(crypto_sha_context *ctx)
return;
}
/* Uninit crypto module */
crypto_uninit();
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
@ -189,6 +195,7 @@ void mbedtls_sha256_hw_process(crypto_sha_context *ctx, const unsigned char data
void mbedtls_sha512_hw_init(crypto_sha_context *ctx)
{
/* Init crypto module */
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
@ -199,6 +206,8 @@ void mbedtls_sha512_hw_free(crypto_sha_context *ctx)
return;
}
/* Uninit crypto module */
crypto_uninit();
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}

View File

@ -34,8 +34,7 @@
#include "mbed_assert.h"
#include "mbed_error.h"
#include "nu_bitutil.h"
#include "crypto-misc.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
@ -69,15 +68,6 @@ static bool aes_dma_buff_compat(const void *buff, unsigned buff_size)
void mbedtls_aes_init( mbedtls_aes_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
/* Unlock protected registers */
SYS_UnlockReg();
CLK_EnableModuleClock(CRPT_MODULE);
/* Lock protected registers */
SYS_LockReg();
NVIC_EnableIRQ(CRPT_IRQn);
AES_ENABLE_INT();
}
void mbedtls_aes_free( mbedtls_aes_context *ctx )
@ -153,6 +143,11 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
}
/* Init crypto module */
crypto_init();
/* Enable AES interrupt */
AES_ENABLE_INT();
/* We support multiple contexts with context save & restore and so needs just one
* H/W channel. Always use H/W channel #0. */
@ -195,6 +190,11 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
ctx->iv[1] = CRPT->AES_FDBCK1;
ctx->iv[2] = CRPT->AES_FDBCK2;
ctx->iv[3] = CRPT->AES_FDBCK3;
/* Disable AES interrupt */
AES_DISABLE_INT();
/* Uninit crypto module */
crypto_uninit();
}
/*

View File

@ -17,21 +17,62 @@
#include "cmsis.h"
#include "mbed_assert.h"
#include "mbed_critical.h"
#include "mbed_error.h"
#include <limits.h>
#include "nu_modutil.h"
#include "nu_bitutil.h"
#include "crypto-misc.h"
static int crypto_inited = 0;
static int crypto_sha_avail = 1;
/* Crypto (AES, DES, SHA, etc.) init counter. Crypto's keeps active as it is non-zero. */
static uint16_t crypto_init_counter = 0U;
/* As crypto init counter changes from 0 to 1:
*
* 1. Enable crypto clock
* 2. Enable crypto interrupt
*/
void crypto_init(void)
{
if (crypto_inited) {
return;
core_util_critical_section_enter();
if (crypto_init_counter == USHRT_MAX) {
core_util_critical_section_exit();
error("Crypto clock enable counter would overflow (> USHRT_MAX)");
}
crypto_inited = 1;
core_util_atomic_incr_u16(&crypto_init_counter, 1);
if (crypto_init_counter == 1) {
SYS_UnlockReg(); // Unlock protected register
CLK_EnableModuleClock(CRPT_MODULE);
SYS_LockReg(); // Lock protected register
CLK_EnableModuleClock(CRPT_MODULE);
NVIC_EnableIRQ(CRPT_IRQn);
}
core_util_critical_section_exit();
}
/* As crypto init counter changes from 1 to 0:
*
* 1. Disable crypto interrupt
* 2. Disable crypto clock
*/
void crypto_uninit(void)
{
core_util_critical_section_enter();
if (crypto_init_counter == 0) {
core_util_critical_section_exit();
error("Crypto clock enable counter would underflow (< 0)");
}
core_util_atomic_decr_u16(&crypto_init_counter, 1);
if (crypto_init_counter == 0) {
NVIC_DisableIRQ(CRPT_IRQn);
SYS_UnlockReg(); // Unlock protected register
CLK_DisableModuleClock(CRPT_MODULE);
SYS_LockReg(); // Lock protected register
}
core_util_critical_section_exit();
}
/* Implementation that should never be optimized out by the compiler */

View File

@ -22,6 +22,7 @@ extern "C" {
#endif
void crypto_init(void);
void crypto_uninit(void);
void crypto_zeroize(void *v, size_t n);
int crypto_sha_acquire(void);
void crypto_sha_release(void);

View File

@ -49,7 +49,6 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
void mbedtls_des_init(mbedtls_des_context *ctx)
{
crypto_init();
memset(ctx, 0, sizeof(mbedtls_des_context));
}
@ -64,7 +63,6 @@ void mbedtls_des_free( mbedtls_des_context *ctx )
void mbedtls_des3_init( mbedtls_des3_context *ctx )
{
crypto_init();
memset(ctx, 0, sizeof(mbedtls_des3_context));
}
@ -329,6 +327,9 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
error("Buffer for DES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
}
/* Init crypto module */
crypto_init();
// NOTE: Don't call driver function TDES_Open in BSP because it doesn't support TDES_CTL[3KEYS] setting.
CRPT->TDES_CTL = (0 << CRPT_TDES_CTL_CHANNEL_Pos) | (enc << CRPT_TDES_CTL_ENCRPT_Pos) |
tdes_opmode | (TDES_IN_OUT_WHL_SWAP << CRPT_TDES_CTL_BLKSWAP_Pos);
@ -418,6 +419,9 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
}
}
/* Uninit crypto module */
crypto_uninit();
return 0;
}

View File

@ -39,6 +39,7 @@ void crypto_sha_getinternstate(unsigned char output[], size_t olen);
void mbedtls_sha1_hw_init(crypto_sha_context *ctx)
{
/* Init crypto module */
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
@ -49,6 +50,8 @@ void mbedtls_sha1_hw_free(crypto_sha_context *ctx)
return;
}
/* Uninit crypto module */
crypto_uninit();
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
@ -113,6 +116,7 @@ void mbedtls_sha1_hw_process(crypto_sha_context *ctx, const unsigned char data[6
void mbedtls_sha256_hw_init(crypto_sha_context *ctx)
{
/* Init crypto module */
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
@ -123,6 +127,8 @@ void mbedtls_sha256_hw_free(crypto_sha_context *ctx)
return;
}
/* Uninit crypto module */
crypto_uninit();
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}

View File

@ -21,6 +21,7 @@
#include "cmsis.h"
#include "us_ticker_api.h"
#include "trng_api.h"
#include "crypto-misc.h"
/*
* Get Random number generator.
@ -63,23 +64,21 @@ static void trng_get(unsigned char *pConversionData)
void trng_init(trng_t *obj)
{
(void)obj;
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable IP clock */
CLK_EnableModuleClock(CRPT_MODULE);
/* Lock protected registers */
SYS_LockReg();
/* Init crypto module */
crypto_init();
NVIC_EnableIRQ(CRPT_IRQn);
PRNG_ENABLE_INT();
}
void trng_free(trng_t *obj)
{
(void)obj;
PRNG_DISABLE_INT();
NVIC_DisableIRQ(CRPT_IRQn);
/* Uninit crypto module */
crypto_uninit();
}
int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)

View File

@ -26,6 +26,7 @@
#include "NUC472_442.h"
#include "us_ticker_api.h"
#include "trng_api.h"
#include "crypto-misc.h"
/*
* Get Random number generator.
@ -68,23 +69,21 @@ static void trng_get(unsigned char *pConversionData)
void trng_init(trng_t *obj)
{
(void)obj;
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable IP clock */
CLK_EnableModuleClock(CRPT_MODULE);
/* Lock protected registers */
SYS_LockReg();
/* Init crypto module */
crypto_init();
NVIC_EnableIRQ(CRPT_IRQn);
PRNG_ENABLE_INT();
}
void trng_free(trng_t *obj)
{
(void)obj;
PRNG_DISABLE_INT();
NVIC_DisableIRQ(CRPT_IRQn);
/* Uninit crypto module */
crypto_uninit();
}
int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)