mirror of https://github.com/ARMmbed/mbed-os.git
[NUC472/M487] Refine flow control code between crypto start and crypto ISR
parent
e1fbf0f6a7
commit
0c1098483f
|
@ -176,17 +176,9 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
|||
|
||||
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
|
||||
|
||||
g_AES_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();
|
||||
crypto_aes_prestart();
|
||||
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
||||
while (!g_AES_done);
|
||||
crypto_aes_wait();
|
||||
|
||||
if( pOut != output ) {
|
||||
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);
|
||||
|
||||
g_AES_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();
|
||||
crypto_aes_prestart();
|
||||
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
||||
while (!g_AES_done);
|
||||
crypto_aes_wait();
|
||||
|
||||
if( pOut != output ) {
|
||||
memcpy(output, au8OutputData, dataSize);
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
#include "nu_bitutil.h"
|
||||
#include "crypto-misc.h"
|
||||
|
||||
volatile int g_PRNG_done;
|
||||
volatile int g_AES_done;
|
||||
|
||||
/* Track if AES H/W is available */
|
||||
static uint16_t crypto_aes_avail = 1;
|
||||
/* 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 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:
|
||||
*
|
||||
* 1. Enable crypto clock
|
||||
|
@ -125,6 +130,26 @@ void crypto_sha_release(void)
|
|||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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 */
|
||||
void CRYPTO_IRQHandler()
|
||||
{
|
||||
if (PRNG_GET_INT_FLAG()) {
|
||||
g_PRNG_done = 1;
|
||||
crypto_prng_done = 1;
|
||||
PRNG_CLR_INT_FLAG();
|
||||
} else if (AES_GET_INT_FLAG()) {
|
||||
g_AES_done = 1;
|
||||
crypto_aes_done = 1;
|
||||
AES_CLR_INT_FLAG();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,14 +23,6 @@
|
|||
extern "C" {
|
||||
#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 */
|
||||
void crypto_init(void);
|
||||
void crypto_uninit(void);
|
||||
|
@ -54,6 +46,27 @@ void crypto_des_release(void);
|
|||
bool crypto_sha_acquire(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:
|
||||
* (1) Word-aligned buffer base address
|
||||
* (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;
|
||||
|
||||
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
|
||||
crypto_prng_prestart();
|
||||
PRNG_Start();
|
||||
while (!g_PRNG_done);
|
||||
crypto_prng_wait();
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
#include "nu_bitutil.h"
|
||||
#include "crypto-misc.h"
|
||||
|
||||
volatile int g_PRNG_done;
|
||||
volatile int g_AES_done;
|
||||
|
||||
/* Track if AES H/W is available */
|
||||
static uint16_t crypto_aes_avail = 1;
|
||||
/* 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 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:
|
||||
*
|
||||
* 1. Enable crypto clock
|
||||
|
@ -125,6 +130,26 @@ void crypto_sha_release(void)
|
|||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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 */
|
||||
void CRYPTO_IRQHandler()
|
||||
{
|
||||
if (PRNG_GET_INT_FLAG()) {
|
||||
g_PRNG_done = 1;
|
||||
crypto_prng_done = 1;
|
||||
PRNG_CLR_INT_FLAG();
|
||||
} else if (AES_GET_INT_FLAG()) {
|
||||
g_AES_done = 1;
|
||||
crypto_aes_done = 1;
|
||||
AES_CLR_INT_FLAG();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,14 +23,6 @@
|
|||
extern "C" {
|
||||
#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 */
|
||||
void crypto_init(void);
|
||||
void crypto_uninit(void);
|
||||
|
@ -54,6 +46,27 @@ void crypto_des_release(void);
|
|||
bool crypto_sha_acquire(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:
|
||||
* (1) Word-aligned buffer base address
|
||||
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cmsis.h"
|
||||
#include "NUC472_442.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "trng_api.h"
|
||||
#include "crypto-misc.h"
|
||||
|
@ -41,8 +40,9 @@ static void trng_get(unsigned char *pConversionData)
|
|||
p32ConversionData = (uint32_t *)pConversionData;
|
||||
|
||||
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
|
||||
crypto_prng_prestart();
|
||||
PRNG_Start();
|
||||
while (!g_PRNG_done);
|
||||
crypto_prng_wait();
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue