Skip to content

Commit 6800f29

Browse files
committed
NUVOTON: Re-implement TRNG HAL with TRNG H/W
Targets supporting TRNG H/W: - NU_PFM_M2351_* - NUMAKER_IOT_M263A
1 parent 6ca7056 commit 6800f29

File tree

12 files changed

+328
-195
lines changed

12 files changed

+328
-195
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/PeripheralNames.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,15 @@ typedef enum {
328328

329329
} CANName;
330330

331+
typedef enum {
332+
#if defined(SCU_INIT_PNSSET5_VAL) && (SCU_INIT_PNSSET5_VAL & (1 << 25))
333+
TRNG_0 = (int) NU_MODNAME(TRNG_BASE + NS_OFFSET, 0, 0)
334+
#else
335+
TRNG_0 = (int) NU_MODNAME(TRNG_BASE, 0, 0)
336+
#endif
337+
338+
} TRNGName;
339+
331340
#ifdef __cplusplus
332341
}
333342
#endif

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "platform/SingletonPtr.h"
2828
#include "platform/PlatformMutex.h"
2929

30-
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
30+
#if defined(MBEDTLS_CONFIG_HW_SUPPORT)
3131

3232
/* Consideration for choosing proper synchronization mechanism
3333
*
@@ -345,4 +345,4 @@ extern "C" void CRPT_IRQHandler()
345345
}
346346
}
347347

348-
#endif /* #if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT) */
348+
#endif /* #if defined(MBEDTLS_CONFIG_HW_SUPPORT) */

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,23 @@
2424
*
2525
* There's only one CRYPTO/CRPT module and we have the following policy for configuring its secure attribute:
2626
*
27-
* 1. TRNG or mbedtls H/W support can be enabled on either secure target or non-secure target, but not both.
28-
* 2. TRNG and mbedtls H/W supports cannot be enabled on different targets.
29-
* 3. On secure target, if TRNG or mbedtls H/W support is enabled, CRYPTO/CRPT must configure to secure.
30-
* 4. On non-secure target, if TRNG or mbedtls H/W support is enabled, CRYPTO/CRPT must configure to non-secure.
27+
* 1. mbedtls H/W support can be enabled on either secure target or non-secure target, but not both.
28+
* 2. On secure target, if mbedtls H/W support is enabled, CRYPTO/CRPT must configure to secure.
29+
* 3. On non-secure target, if mbedtls H/W support is enabled, CRYPTO/CRPT must configure to non-secure.
3130
*/
32-
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
31+
#if defined(MBEDTLS_CONFIG_HW_SUPPORT)
3332
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3433
#if defined(SCU_INIT_PNSSET1_VAL) && (SCU_INIT_PNSSET1_VAL & (1 << 18))
35-
#error("CRYPTO/CRPT must configure to secure for secure target which supports TRNG or mbedtls H/W")
34+
#error("CRYPTO/CRPT must configure to secure for secure target which supports mbedtls H/W")
3635
#endif
3736
#else
3837
#if (! defined(SCU_INIT_PNSSET1_VAL)) || (! (SCU_INIT_PNSSET1_VAL & (1 << 18)))
39-
#error("CRYPTO/CRPT must configure to non-secure for non-secure target which supports TRNG or mbedtls H/W")
38+
#error("CRYPTO/CRPT must configure to non-secure for non-secure target which supports mbedtls H/W")
4039
#endif
4140
#endif
4241
#endif
4342

44-
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
43+
#if defined(MBEDTLS_CONFIG_HW_SUPPORT)
4544

4645
#ifdef __cplusplus
4746
extern "C" {
@@ -132,6 +131,6 @@ bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const vo
132131
}
133132
#endif
134133

135-
#endif /* #if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT) */
134+
#endif /* defined(MBEDTLS_CONFIG_HW_SUPPORT) */
136135

137136
#endif

targets/TARGET_NUVOTON/TARGET_M2351/hal_secure.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,30 @@ int64_t rtc_read_s(void);
7272
__NONSECURE_ENTRY
7373
void rtc_write_s(int64_t t);
7474

75+
/* trng_init (secure version)
76+
*
77+
* Its synopsis is the same as normal version except change of return/argument type for
78+
* binary-compatible across compilers.
79+
*/
80+
__NONSECURE_ENTRY
81+
void trng_init_s(void *obj);
82+
83+
/* trng_free (secure version)
84+
*
85+
* Its synopsis is the same as normal version except change of return/argument type for
86+
* binary-compatible across compilers.
87+
*/
88+
__NONSECURE_ENTRY
89+
void trng_free_s(void *obj);
90+
91+
/* trng_get_bytes (secure version)
92+
*
93+
* Its synopsis is the same as normal version except change of return/argument type for
94+
* binary-compatible across compilers.
95+
*/
96+
__NONSECURE_ENTRY
97+
int32_t trng_get_bytes_s(void *obj, uint8_t *output, uint32_t length, uint32_t *output_length);
98+
7599
#ifdef __cplusplus
76100
}
77101
#endif

targets/TARGET_NUVOTON/TARGET_M2351/trng_api.c

Lines changed: 0 additions & 89 deletions
This file was deleted.
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017-2018 Nuvoton
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#if DEVICE_TRNG
18+
19+
#include "cmsis.h"
20+
#include <limits.h>
21+
#include "crypto-misc.h"
22+
#include "hal/trng_api.h"
23+
#include "platform/mbed_toolchain.h"
24+
#include "platform/mbed_critical.h"
25+
#include "platform/mbed_error.h"
26+
#include "platform/SingletonPtr.h"
27+
#include "platform/PlatformMutex.h"
28+
#include "nu_modutil.h"
29+
#include "hal_secure.h"
30+
#include "partition_M2351.h"
31+
32+
#if defined(SCU_INIT_PNSSET5_VAL) && (SCU_INIT_PNSSET5_VAL & (1 << 25))
33+
#error("We just support secure TRNG")
34+
#endif
35+
36+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
37+
38+
/* Module init definition: modname, clkidx, clksrc, clkdiv, rstidx, irqnum, misc */
39+
static const struct nu_modinit_s trng_modinit = {TRNG_0, TRNG_MODULE, 0, 0, TRNG_RST, TRNG_IRQn, NULL};
40+
41+
/* TRNG init counter. TRNG is kept active as it is non-zero. */
42+
static uint16_t trng_init_counter = 0U;
43+
44+
/* Mutex for synchronizing access to TRNG H/W */
45+
static SingletonPtr<PlatformMutex> trng_mutex;
46+
47+
#endif
48+
49+
void trng_init(trng_t *obj)
50+
{
51+
trng_init_s(obj);
52+
}
53+
54+
void trng_free(trng_t *obj)
55+
{
56+
trng_free_s(obj);
57+
}
58+
59+
int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)
60+
{
61+
uint32_t output_length_;
62+
int32_t rc = trng_get_bytes_s(obj, output, (uint32_t) length, &output_length_);
63+
if (output_length) {
64+
*output_length = output_length_;
65+
}
66+
return rc;
67+
}
68+
69+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
70+
71+
__NONSECURE_ENTRY
72+
extern "C"
73+
void trng_init_s(MBED_UNUSED void *obj)
74+
{
75+
core_util_critical_section_enter();
76+
if (trng_init_counter == USHRT_MAX) {
77+
core_util_critical_section_exit();
78+
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_OVERFLOW), \
79+
"TRNG initialization counter would overflow");
80+
}
81+
core_util_atomic_incr_u16(&trng_init_counter, 1);
82+
if (trng_init_counter == 1) {
83+
/* Enable IP clock (secure version) */
84+
CLK_EnableModuleClock_S(trng_modinit.clkidx);
85+
86+
/* Reset IP (secure version) */
87+
SYS_ResetModule_S(trng_modinit.rsetidx);
88+
89+
TRNG_T *trng_base = (TRNG_T *) NU_MODBASE(trng_modinit.modname);
90+
91+
trng_base->ACT |= TRNG_ACT_ACT_Msk;
92+
while (!(trng_base->CTL & TRNG_CTL_READY_Msk));
93+
}
94+
core_util_critical_section_exit();
95+
}
96+
97+
__NONSECURE_ENTRY
98+
extern "C"
99+
void trng_free_s(MBED_UNUSED void *obj)
100+
{
101+
core_util_critical_section_enter();
102+
if (trng_init_counter == 0) {
103+
core_util_critical_section_exit();
104+
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_UNDERFLOW), \
105+
"TRNG initialization counter would underflow");
106+
}
107+
core_util_atomic_decr_u16(&trng_init_counter, 1);
108+
if (trng_init_counter == 0) {
109+
TRNG_T *trng_base = (TRNG_T *) NU_MODBASE(trng_modinit.modname);
110+
111+
trng_base->ACT &= ~TRNG_ACT_ACT_Msk;
112+
113+
/* Disable IP clock (secure version) */
114+
CLK_DisableModuleClock_S(trng_modinit.clkidx);
115+
}
116+
core_util_critical_section_exit();
117+
}
118+
119+
__NONSECURE_ENTRY
120+
extern "C"
121+
int32_t trng_get_bytes_s(MBED_UNUSED void *obj, uint8_t *output, uint32_t length, uint32_t *output_length)
122+
{
123+
/* Check augument validity */
124+
if (!output && length) {
125+
return -1;
126+
}
127+
128+
uint8_t *output_ind = output;
129+
uint8_t *output_end = output + length;
130+
131+
/* Don't check return code of Mutex::lock(void)
132+
*
133+
* This function treats RTOS errors as fatal system errors, so it can only return osOK.
134+
* Use of the return value is deprecated, as the return is expected to become void in
135+
* the future.
136+
*/
137+
trng_mutex->lock();
138+
139+
TRNG_T *trng_base = (TRNG_T *) NU_MODBASE(trng_modinit.modname);
140+
141+
for (; output_ind != output_end; output_ind ++) {
142+
trng_base->CTL |= TRNG_CTL_TRNGEN_Msk;
143+
while (!(trng_base->CTL & TRNG_CTL_DVIF_Msk));
144+
*output_ind = trng_base->DATA & 0xff;
145+
}
146+
147+
trng_mutex->unlock();
148+
149+
if (output_length) {
150+
*output_length = length;
151+
}
152+
153+
return 0;
154+
}
155+
156+
#endif
157+
#endif

targets/TARGET_NUVOTON/TARGET_M261/PeripheralNames.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ typedef enum {
144144

145145
} CANName;
146146

147+
typedef enum {
148+
TRNG_0 = (int) NU_MODNAME(TRNG_BASE, 0, 0)
149+
150+
} TRNGName;
151+
147152
#ifdef __cplusplus
148153
}
149154
#endif

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "platform/SingletonPtr.h"
2828
#include "platform/PlatformMutex.h"
2929

30-
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
30+
#if defined(MBEDTLS_CONFIG_HW_SUPPORT)
3131

3232
/* Consideration for choosing proper synchronization mechanism
3333
*
@@ -342,4 +342,4 @@ extern "C" void CRPT_IRQHandler()
342342
}
343343
}
344344

345-
#endif /* #if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT) */
345+
#endif /* #if defined(MBEDTLS_CONFIG_HW_SUPPORT) */

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <stdbool.h>
2222

2323

24-
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
24+
#if defined(MBEDTLS_CONFIG_HW_SUPPORT)
2525

2626
#ifdef __cplusplus
2727
extern "C" {
@@ -108,6 +108,6 @@ bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const vo
108108
}
109109
#endif
110110

111-
#endif /* #if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT) */
111+
#endif /* #if defined(MBEDTLS_CONFIG_HW_SUPPORT) */
112112

113113
#endif

0 commit comments

Comments
 (0)