Skip to content

Commit 1712a2b

Browse files
author
Cruz Monrreal
authored
Merge pull request #9656 from OpenNuvoton/nuvoton_m2351_fix-crypto-ac-mgmt
M2351: Fix crypto AC management
2 parents a12d9bb + 99dd189 commit 1712a2b

File tree

4 files changed

+81
-68
lines changed

4 files changed

+81
-68
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/crypto/crypto-misc.c renamed to targets/TARGET_NUVOTON/TARGET_M2351/crypto/crypto-misc.cpp

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,43 @@
2323
#include "nu_modutil.h"
2424
#include "nu_bitutil.h"
2525
#include "crypto-misc.h"
26+
#include "platform/SingletonPtr.h"
27+
#include "platform/PlatformMutex.h"
2628

2729
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
2830

29-
/* NOTE: There's inconsistency in cryptography related naming, Crpt or Crypto. For example, cryptography IRQ
30-
* handler could be CRPT_IRQHandler or CRYPTO_IRQHandler. To override default cryptography IRQ handler, see
31-
* device/startup_{CHIP}.c for its name or call NVIC_SetVector regardless of its name. */
32-
void CRPT_IRQHandler();
31+
/* Consideration for choosing proper synchronization mechanism
32+
*
33+
* 1. We choose mutex to synchronize access to crypto non-SHA AC. We can guarantee:
34+
* (1) No deadlock
35+
* We just lock mutex for a short sequence of operations rather than the whole lifetime
36+
* of crypto context.
37+
* (2) No priority inversion
38+
* Mutex supports priority inheritance and it is enabled.
39+
* 2. We choose atomic flag to synchronize access to crypto SHA AC. We can guarantee:
40+
* (1) No deadlock
41+
* With SHA AC not supporting context save & restore, we provide SHA S/W fallback when
42+
* SHA AC is not available.
43+
* (2) No biting CPU
44+
* Same reason as above.
45+
*/
46+
47+
/* Mutex for crypto AES AC management */
48+
static SingletonPtr<PlatformMutex> crypto_aes_mutex;
49+
50+
/* Mutex for crypto DES AC management */
51+
static SingletonPtr<PlatformMutex> crypto_des_mutex;
52+
53+
/* Mutex for crypto ECC AC management */
54+
static SingletonPtr<PlatformMutex> crypto_ecc_mutex;
55+
56+
/* Atomic flag for crypto SHA AC management */
57+
static core_util_atomic_flag crypto_sha_atomic_flag = CORE_UTIL_ATOMIC_FLAG_INIT;
3358

34-
/* Track if AES H/W is available */
35-
static uint16_t crypto_aes_avail = 1;
36-
/* Track if DES H/W is available */
37-
static uint16_t crypto_des_avail = 1;
38-
/* Track if SHA H/W is available */
39-
static uint16_t crypto_sha_avail = 1;
40-
/* Track if ECC H/W is available */
41-
static uint16_t crypto_ecc_avail = 1;
4259

4360
/* Crypto (AES, DES, SHA, etc.) init counter. Crypto's keeps active as it is non-zero. */
4461
static uint16_t crypto_init_counter = 0U;
4562

46-
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
47-
static void crypto_submodule_release(uint16_t *submodule_avail);
48-
4963
/* Crypto done flags */
5064
#define CRYPTO_DONE_OK BIT0 /* Done with OK */
5165
#define CRYPTO_DONE_ERR BIT1 /* Done with error */
@@ -81,8 +95,7 @@ void crypto_init(void)
8195
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
8296
*/
8397
CLK_EnableModuleClock_S(CRPT_MODULE);
84-
85-
NVIC_SetVector(CRPT_IRQn, (uint32_t) CRPT_IRQHandler);
98+
8699
NVIC_EnableIRQ(CRPT_IRQn);
87100
}
88101
core_util_critical_section_exit();
@@ -131,44 +144,52 @@ void crypto_zeroize32(uint32_t *v, size_t n)
131144
}
132145
}
133146

134-
bool crypto_aes_acquire(void)
147+
void crypto_aes_acquire(void)
135148
{
136-
return crypto_submodule_acquire(&crypto_aes_avail);
149+
/* Don't check return code of Mutex::lock(void)
150+
*
151+
* This function treats RTOS errors as fatal system errors, so it can only return osOK.
152+
* Use of the return value is deprecated, as the return is expected to become void in
153+
* the future.
154+
*/
155+
crypto_aes_mutex->lock();
137156
}
138157

139158
void crypto_aes_release(void)
140159
{
141-
crypto_submodule_release(&crypto_aes_avail);
160+
crypto_aes_mutex->unlock();
142161
}
143162

144-
bool crypto_des_acquire(void)
163+
void crypto_des_acquire(void)
145164
{
146-
return crypto_submodule_acquire(&crypto_des_avail);
165+
/* Don't check return code of Mutex::lock(void) */
166+
crypto_des_mutex->lock();
147167
}
148168

149169
void crypto_des_release(void)
150170
{
151-
crypto_submodule_release(&crypto_des_avail);
171+
crypto_des_mutex->unlock();
152172
}
153173

154-
bool crypto_sha_acquire(void)
174+
void crypto_ecc_acquire(void)
155175
{
156-
return crypto_submodule_acquire(&crypto_sha_avail);
176+
/* Don't check return code of Mutex::lock(void) */
177+
crypto_ecc_mutex->lock();
157178
}
158179

159-
void crypto_sha_release(void)
180+
void crypto_ecc_release(void)
160181
{
161-
crypto_submodule_release(&crypto_sha_avail);
182+
crypto_ecc_mutex->unlock();
162183
}
163184

164-
bool crypto_ecc_acquire(void)
185+
bool crypto_sha_try_acquire(void)
165186
{
166-
return crypto_submodule_acquire(&crypto_ecc_avail);
187+
return !core_util_atomic_flag_test_and_set(&crypto_sha_atomic_flag);
167188
}
168189

169-
void crypto_ecc_release(void)
190+
void crypto_sha_release(void)
170191
{
171-
crypto_submodule_release(&crypto_ecc_avail);
192+
core_util_atomic_flag_clear(&crypto_sha_atomic_flag);
172193
}
173194

174195
void crypto_prng_prestart(void)
@@ -252,18 +273,6 @@ bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const vo
252273
return overlap;
253274
}
254275

255-
static bool crypto_submodule_acquire(uint16_t *submodule_avail)
256-
{
257-
uint16_t expectedCurrentValue = 1;
258-
return core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 0);
259-
}
260-
261-
static void crypto_submodule_release(uint16_t *submodule_avail)
262-
{
263-
uint16_t expectedCurrentValue = 0;
264-
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
265-
}
266-
267276
static void crypto_submodule_prestart(volatile uint16_t *submodule_done)
268277
{
269278
*submodule_done = 0;
@@ -296,8 +305,13 @@ static bool crypto_submodule_wait(volatile uint16_t *submodule_done)
296305
return false;
297306
}
298307

299-
/* Crypto interrupt handler */
300-
void CRPT_IRQHandler()
308+
/* Crypto interrupt handler
309+
*
310+
* There's inconsistency in cryptography related naming, Crpt or Crypto. For example,
311+
* cryptography IRQ handler could be CRPT_IRQHandler or CRYPTO_IRQHandler. To override
312+
* default cryptography IRQ handler, see device/startup_{CHIP}.c for its correct name
313+
* or call NVIC_SetVector() in crypto_init() regardless of its name. */
314+
extern "C" void CRPT_IRQHandler()
301315
{
302316
uint32_t intsts;
303317

targets/TARGET_NUVOTON/TARGET_M2351/crypto/crypto-misc.h

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,33 @@ void crypto_uninit(void);
6666
void crypto_zeroize(void *v, size_t n);
6767
void crypto_zeroize32(uint32_t *v, size_t n);
6868

69-
/* Acquire/release ownership of AES H/W */
70-
/* NOTE: If "acquire" succeeds, "release" must be done to pair it. */
71-
bool crypto_aes_acquire(void);
69+
/* Acquire/release ownership of crypto sub-module
70+
*
71+
* \note "acquire" is blocking until ownership is acquired
72+
*
73+
* \note "acquire"/"release" must be paired.
74+
*
75+
* \note Recursive "acquire" is allowed because the underlying synchronization
76+
* primitive mutex supports it.
77+
*/
78+
void crypto_aes_acquire(void);
7279
void crypto_aes_release(void);
73-
74-
/* Acquire/release ownership of DES H/W */
75-
/* NOTE: If "acquire" succeeds, "release" must be done to pair it. */
76-
bool crypto_des_acquire(void);
80+
void crypto_des_acquire(void);
7781
void crypto_des_release(void);
82+
void crypto_ecc_acquire(void);
83+
void crypto_ecc_release(void);
7884

79-
/* Acquire/release ownership of SHA H/W */
80-
/* NOTE: If "acquire" succeeds, "release" must be done to pair it. */
81-
bool crypto_sha_acquire(void);
85+
/* Acquire/release ownership of crypto sub-module
86+
*
87+
* \return false if crytpo sub-module is held by another thread or
88+
* another mbedtls context.
89+
* true if successful
90+
*
91+
* \note Successful "try_acquire" and "release" must be paired.
92+
*/
93+
bool crypto_sha_try_acquire(void);
8294
void crypto_sha_release(void);
8395

84-
/* Acquire/release ownership of ECC H/W */
85-
/* NOTE: If "acquire" succeeds, "release" must be done to pair it. */
86-
bool crypto_ecc_acquire(void);
87-
void crypto_ecc_release(void);
88-
8996
/* Flow control between crypto/xxx start and crypto/xxx ISR
9097
*
9198
* crypto_xxx_prestart/crypto_xxx_wait encapsulate control flow between crypto/xxx start and crypto/xxx ISR.

targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@
1919
#include "mbed_assert.h"
2020
#include "mbed_critical.h"
2121
#include "mbed_error.h"
22-
#if MBED_CONF_RTOS_PRESENT
23-
#include "cmsis_os2.h"
24-
#endif
25-
#include <string.h>
2622
#include <limits.h>
2723
#include "nu_modutil.h"
2824
#include "nu_bitutil.h"

targets/TARGET_NUVOTON/TARGET_NUC472/crypto/crypto-misc.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@
1919
#include "mbed_assert.h"
2020
#include "mbed_critical.h"
2121
#include "mbed_error.h"
22-
#if MBED_CONF_RTOS_PRESENT
23-
#include "cmsis_os2.h"
24-
#endif
25-
#include <string.h>
2622
#include <limits.h>
2723
#include "nu_modutil.h"
2824
#include "nu_bitutil.h"

0 commit comments

Comments
 (0)