mirror of https://github.com/ARMmbed/mbed-os.git
Refine flow control code between crypto start and crypto ISR
parent
9374e43545
commit
274a54eb8b
|
@ -176,17 +176,9 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
|
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
|
||||||
|
|
||||||
g_AES_done = 0;
|
crypto_aes_prestart();
|
||||||
/* Ensure memory accesses above are completed before DMA is started
|
|
||||||
*
|
|
||||||
* Replacing __DSB() with __DMB() is also OK in this case.
|
|
||||||
*
|
|
||||||
* Refer to "multi-master systems" section with DMA in:
|
|
||||||
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
|
|
||||||
*/
|
|
||||||
__DSB();
|
|
||||||
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
||||||
while (!g_AES_done);
|
crypto_aes_wait();
|
||||||
|
|
||||||
if( pOut != output ) {
|
if( pOut != output ) {
|
||||||
memcpy(output, au8OutputData, dataSize);
|
memcpy(output, au8OutputData, dataSize);
|
||||||
|
|
|
@ -176,17 +176,9 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
|
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
|
||||||
|
|
||||||
g_AES_done = 0;
|
crypto_aes_prestart();
|
||||||
/* Ensure memory accesses above are completed before DMA is started
|
|
||||||
*
|
|
||||||
* Replacing __DSB() with __DMB() is also OK in this case.
|
|
||||||
*
|
|
||||||
* Refer to "multi-master systems" section with DMA in:
|
|
||||||
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
|
|
||||||
*/
|
|
||||||
__DSB();
|
|
||||||
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
||||||
while (!g_AES_done);
|
crypto_aes_wait();
|
||||||
|
|
||||||
if( pOut != output ) {
|
if( pOut != output ) {
|
||||||
memcpy(output, au8OutputData, dataSize);
|
memcpy(output, au8OutputData, dataSize);
|
||||||
|
|
|
@ -24,9 +24,6 @@
|
||||||
#include "nu_bitutil.h"
|
#include "nu_bitutil.h"
|
||||||
#include "crypto-misc.h"
|
#include "crypto-misc.h"
|
||||||
|
|
||||||
volatile int g_PRNG_done;
|
|
||||||
volatile int g_AES_done;
|
|
||||||
|
|
||||||
/* Track if AES H/W is available */
|
/* Track if AES H/W is available */
|
||||||
static uint16_t crypto_aes_avail = 1;
|
static uint16_t crypto_aes_avail = 1;
|
||||||
/* Track if DES H/W is available */
|
/* Track if DES H/W is available */
|
||||||
|
@ -40,6 +37,14 @@ static uint16_t crypto_init_counter = 0U;
|
||||||
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
|
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
|
||||||
static void crypto_submodule_release(uint16_t *submodule_avail);
|
static void crypto_submodule_release(uint16_t *submodule_avail);
|
||||||
|
|
||||||
|
/* Track if PRNG H/W operation is done */
|
||||||
|
static volatile uint16_t crypto_prng_done;
|
||||||
|
/* Track if AES H/W operation is done */
|
||||||
|
static volatile uint16_t crypto_aes_done;
|
||||||
|
|
||||||
|
static void crypto_submodule_prestart(volatile uint16_t *submodule_done);
|
||||||
|
static bool crypto_submodule_wait(volatile uint16_t *submodule_done);
|
||||||
|
|
||||||
/* As crypto init counter changes from 0 to 1:
|
/* As crypto init counter changes from 0 to 1:
|
||||||
*
|
*
|
||||||
* 1. Enable crypto clock
|
* 1. Enable crypto clock
|
||||||
|
@ -125,6 +130,26 @@ void crypto_sha_release(void)
|
||||||
crypto_submodule_release(&crypto_sha_avail);
|
crypto_submodule_release(&crypto_sha_avail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void crypto_prng_prestart(void)
|
||||||
|
{
|
||||||
|
crypto_submodule_prestart(&crypto_prng_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool crypto_prng_wait(void)
|
||||||
|
{
|
||||||
|
return crypto_submodule_wait(&crypto_prng_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
void crypto_aes_prestart(void)
|
||||||
|
{
|
||||||
|
crypto_submodule_prestart(&crypto_aes_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool crypto_aes_wait(void)
|
||||||
|
{
|
||||||
|
return crypto_submodule_wait(&crypto_aes_done);
|
||||||
|
}
|
||||||
|
|
||||||
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
|
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
|
||||||
{
|
{
|
||||||
uint32_t buff_ = (uint32_t) buff;
|
uint32_t buff_ = (uint32_t) buff;
|
||||||
|
@ -146,14 +171,35 @@ static void crypto_submodule_release(uint16_t *submodule_avail)
|
||||||
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
|
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void crypto_submodule_prestart(volatile uint16_t *submodule_done)
|
||||||
|
{
|
||||||
|
*submodule_done = 0;
|
||||||
|
|
||||||
|
/* Ensure memory accesses above are completed before DMA is started
|
||||||
|
*
|
||||||
|
* Replacing __DSB() with __DMB() is also OK in this case.
|
||||||
|
*
|
||||||
|
* Refer to "multi-master systems" section with DMA in:
|
||||||
|
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
|
||||||
|
*/
|
||||||
|
__DSB();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool crypto_submodule_wait(volatile uint16_t *submodule_done)
|
||||||
|
{
|
||||||
|
while (! *submodule_done);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Crypto interrupt handler */
|
/* Crypto interrupt handler */
|
||||||
void CRYPTO_IRQHandler()
|
void CRYPTO_IRQHandler()
|
||||||
{
|
{
|
||||||
if (PRNG_GET_INT_FLAG()) {
|
if (PRNG_GET_INT_FLAG()) {
|
||||||
g_PRNG_done = 1;
|
crypto_prng_done = 1;
|
||||||
PRNG_CLR_INT_FLAG();
|
PRNG_CLR_INT_FLAG();
|
||||||
} else if (AES_GET_INT_FLAG()) {
|
} else if (AES_GET_INT_FLAG()) {
|
||||||
g_AES_done = 1;
|
crypto_aes_done = 1;
|
||||||
AES_CLR_INT_FLAG();
|
AES_CLR_INT_FLAG();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Flags to indicate crypto H/W operation has done
|
|
||||||
*
|
|
||||||
* Crypto driver would clear it before trigger and wait for it.
|
|
||||||
* Crypto interrupt handler would set it on done or error.
|
|
||||||
*/
|
|
||||||
extern volatile int g_PRNG_done;
|
|
||||||
extern volatile int g_AES_done;
|
|
||||||
|
|
||||||
/* Init/Uninit crypto module */
|
/* Init/Uninit crypto module */
|
||||||
void crypto_init(void);
|
void crypto_init(void);
|
||||||
void crypto_uninit(void);
|
void crypto_uninit(void);
|
||||||
|
@ -54,6 +46,27 @@ void crypto_des_release(void);
|
||||||
bool crypto_sha_acquire(void);
|
bool crypto_sha_acquire(void);
|
||||||
void crypto_sha_release(void);
|
void crypto_sha_release(void);
|
||||||
|
|
||||||
|
/* Flow control between crypto/xxx start and crypto/xxx ISR
|
||||||
|
*
|
||||||
|
* crypto_xxx_prestart/crypto_xxx_wait encapsulate control flow between crypto/xxx start and crypto/xxx ISR.
|
||||||
|
*
|
||||||
|
* crypto_xxx_prestart will also address synchronization issue with memory barrier instruction.
|
||||||
|
*
|
||||||
|
* On finish, return of crypto_xxx_wait indicates success or not:
|
||||||
|
* true if successful
|
||||||
|
* false if failed
|
||||||
|
*
|
||||||
|
* Example: Start AES H/W and wait for its finish
|
||||||
|
* crypto_aes_prestart();
|
||||||
|
* AES_Start();
|
||||||
|
* crypto_aes_wait();
|
||||||
|
*/
|
||||||
|
void crypto_prng_prestart(void);
|
||||||
|
bool crypto_prng_wait(void);
|
||||||
|
void crypto_aes_prestart(void);
|
||||||
|
bool crypto_aes_wait(void);
|
||||||
|
|
||||||
|
|
||||||
/* Check if buffer can be used for crypto DMA. It has the following requirements:
|
/* Check if buffer can be used for crypto DMA. It has the following requirements:
|
||||||
* (1) Word-aligned buffer base address
|
* (1) Word-aligned buffer base address
|
||||||
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.
|
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.
|
||||||
|
|
|
@ -36,8 +36,9 @@ static void trng_get(unsigned char *pConversionData)
|
||||||
p32ConversionData = (uint32_t *)pConversionData;
|
p32ConversionData = (uint32_t *)pConversionData;
|
||||||
|
|
||||||
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
|
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
|
||||||
|
crypto_prng_prestart();
|
||||||
PRNG_Start();
|
PRNG_Start();
|
||||||
while (!g_PRNG_done);
|
crypto_prng_wait();
|
||||||
|
|
||||||
PRNG_Read(p32ConversionData);
|
PRNG_Read(p32ConversionData);
|
||||||
}
|
}
|
||||||
|
@ -85,4 +86,3 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,6 @@
|
||||||
#include "nu_bitutil.h"
|
#include "nu_bitutil.h"
|
||||||
#include "crypto-misc.h"
|
#include "crypto-misc.h"
|
||||||
|
|
||||||
volatile int g_PRNG_done;
|
|
||||||
volatile int g_AES_done;
|
|
||||||
|
|
||||||
/* Track if AES H/W is available */
|
/* Track if AES H/W is available */
|
||||||
static uint16_t crypto_aes_avail = 1;
|
static uint16_t crypto_aes_avail = 1;
|
||||||
/* Track if DES H/W is available */
|
/* Track if DES H/W is available */
|
||||||
|
@ -40,6 +37,14 @@ static uint16_t crypto_init_counter = 0U;
|
||||||
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
|
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
|
||||||
static void crypto_submodule_release(uint16_t *submodule_avail);
|
static void crypto_submodule_release(uint16_t *submodule_avail);
|
||||||
|
|
||||||
|
/* Track if PRNG H/W operation is done */
|
||||||
|
static volatile uint16_t crypto_prng_done;
|
||||||
|
/* Track if AES H/W operation is done */
|
||||||
|
static volatile uint16_t crypto_aes_done;
|
||||||
|
|
||||||
|
static void crypto_submodule_prestart(volatile uint16_t *submodule_done);
|
||||||
|
static bool crypto_submodule_wait(volatile uint16_t *submodule_done);
|
||||||
|
|
||||||
/* As crypto init counter changes from 0 to 1:
|
/* As crypto init counter changes from 0 to 1:
|
||||||
*
|
*
|
||||||
* 1. Enable crypto clock
|
* 1. Enable crypto clock
|
||||||
|
@ -125,6 +130,26 @@ void crypto_sha_release(void)
|
||||||
crypto_submodule_release(&crypto_sha_avail);
|
crypto_submodule_release(&crypto_sha_avail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void crypto_prng_prestart(void)
|
||||||
|
{
|
||||||
|
crypto_submodule_prestart(&crypto_prng_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool crypto_prng_wait(void)
|
||||||
|
{
|
||||||
|
return crypto_submodule_wait(&crypto_prng_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
void crypto_aes_prestart(void)
|
||||||
|
{
|
||||||
|
crypto_submodule_prestart(&crypto_aes_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool crypto_aes_wait(void)
|
||||||
|
{
|
||||||
|
return crypto_submodule_wait(&crypto_aes_done);
|
||||||
|
}
|
||||||
|
|
||||||
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
|
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
|
||||||
{
|
{
|
||||||
uint32_t buff_ = (uint32_t) buff;
|
uint32_t buff_ = (uint32_t) buff;
|
||||||
|
@ -146,14 +171,35 @@ static void crypto_submodule_release(uint16_t *submodule_avail)
|
||||||
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
|
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void crypto_submodule_prestart(volatile uint16_t *submodule_done)
|
||||||
|
{
|
||||||
|
*submodule_done = 0;
|
||||||
|
|
||||||
|
/* Ensure memory accesses above are completed before DMA is started
|
||||||
|
*
|
||||||
|
* Replacing __DSB() with __DMB() is also OK in this case.
|
||||||
|
*
|
||||||
|
* Refer to "multi-master systems" section with DMA in:
|
||||||
|
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
|
||||||
|
*/
|
||||||
|
__DSB();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool crypto_submodule_wait(volatile uint16_t *submodule_done)
|
||||||
|
{
|
||||||
|
while (! *submodule_done);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Crypto interrupt handler */
|
/* Crypto interrupt handler */
|
||||||
void CRYPTO_IRQHandler()
|
void CRYPTO_IRQHandler()
|
||||||
{
|
{
|
||||||
if (PRNG_GET_INT_FLAG()) {
|
if (PRNG_GET_INT_FLAG()) {
|
||||||
g_PRNG_done = 1;
|
crypto_prng_done = 1;
|
||||||
PRNG_CLR_INT_FLAG();
|
PRNG_CLR_INT_FLAG();
|
||||||
} else if (AES_GET_INT_FLAG()) {
|
} else if (AES_GET_INT_FLAG()) {
|
||||||
g_AES_done = 1;
|
crypto_aes_done = 1;
|
||||||
AES_CLR_INT_FLAG();
|
AES_CLR_INT_FLAG();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Flags to indicate crypto H/W operation has done
|
|
||||||
*
|
|
||||||
* Crypto driver would clear it before trigger and wait for it.
|
|
||||||
* Crypto interrupt handler would set it on done or error.
|
|
||||||
*/
|
|
||||||
extern volatile int g_PRNG_done;
|
|
||||||
extern volatile int g_AES_done;
|
|
||||||
|
|
||||||
/* Init/Uninit crypto module */
|
/* Init/Uninit crypto module */
|
||||||
void crypto_init(void);
|
void crypto_init(void);
|
||||||
void crypto_uninit(void);
|
void crypto_uninit(void);
|
||||||
|
@ -54,6 +46,27 @@ void crypto_des_release(void);
|
||||||
bool crypto_sha_acquire(void);
|
bool crypto_sha_acquire(void);
|
||||||
void crypto_sha_release(void);
|
void crypto_sha_release(void);
|
||||||
|
|
||||||
|
/* Flow control between crypto/xxx start and crypto/xxx ISR
|
||||||
|
*
|
||||||
|
* crypto_xxx_prestart/crypto_xxx_wait encapsulate control flow between crypto/xxx start and crypto/xxx ISR.
|
||||||
|
*
|
||||||
|
* crypto_xxx_prestart will also address synchronization issue with memory barrier instruction.
|
||||||
|
*
|
||||||
|
* On finish, return of crypto_xxx_wait indicates success or not:
|
||||||
|
* true if successful
|
||||||
|
* false if failed
|
||||||
|
*
|
||||||
|
* Example: Start AES H/W and wait for its finish
|
||||||
|
* crypto_aes_prestart();
|
||||||
|
* AES_Start();
|
||||||
|
* crypto_aes_wait();
|
||||||
|
*/
|
||||||
|
void crypto_prng_prestart(void);
|
||||||
|
bool crypto_prng_wait(void);
|
||||||
|
void crypto_aes_prestart(void);
|
||||||
|
bool crypto_aes_wait(void);
|
||||||
|
|
||||||
|
|
||||||
/* Check if buffer can be used for crypto DMA. It has the following requirements:
|
/* Check if buffer can be used for crypto DMA. It has the following requirements:
|
||||||
* (1) Word-aligned buffer base address
|
* (1) Word-aligned buffer base address
|
||||||
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.
|
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "cmsis.h"
|
#include "cmsis.h"
|
||||||
#include "NUC472_442.h"
|
|
||||||
#include "us_ticker_api.h"
|
#include "us_ticker_api.h"
|
||||||
#include "trng_api.h"
|
#include "trng_api.h"
|
||||||
#include "crypto-misc.h"
|
#include "crypto-misc.h"
|
||||||
|
@ -41,8 +40,9 @@ static void trng_get(unsigned char *pConversionData)
|
||||||
p32ConversionData = (uint32_t *)pConversionData;
|
p32ConversionData = (uint32_t *)pConversionData;
|
||||||
|
|
||||||
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
|
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
|
||||||
|
crypto_prng_prestart();
|
||||||
PRNG_Start();
|
PRNG_Start();
|
||||||
while (!g_PRNG_done);
|
crypto_prng_wait();
|
||||||
|
|
||||||
PRNG_Read(p32ConversionData);
|
PRNG_Read(p32ConversionData);
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,5 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l
|
||||||
*output_length = cur_length;
|
*output_length = cur_length;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue