Skip to content

Commit 74de388

Browse files
committed
hal_trng_get_entropy: handle unaligned out
1 parent 175d2b3 commit 74de388

1 file changed

Lines changed: 36 additions & 38 deletions

File tree

hal/mcxn.c

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -228,53 +228,51 @@ void hal_trng_fini(void)
228228
/* Don't disable ELS, it might be used by other actors */
229229
}
230230

231-
int hal_trng_get_entropy(unsigned char *out, unsigned int len)
231+
static int els_rnd_req(void *out, uint32_t len)
232232
{
233-
/* Implemented as a RND_REQ command to the ELS */
234-
235-
uint32_t aligned_len = len & ~3U;
236-
uint32_t status;
237-
238-
/* Wait for ELS to be ready */
239233
while (ELS->ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK)
240234
;
235+
ELS->ELS_DMA_RES0 = (uint32_t)(uintptr_t)out;
236+
ELS->ELS_DMA_RES0_LEN = len;
237+
ELS->ELS_CMDCFG0 = 0;
238+
ELS->ELS_CTRL = S50_ELS_CTRL_ELS_EN(1)
239+
| S50_ELS_CTRL_ELS_START(1)
240+
| S50_ELS_CTRL_ELS_CMD(ELS_CMD_RND_REQ);
241+
while (ELS->ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK)
242+
;
243+
return (ELS->ELS_STATUS & S50_ELS_STATUS_ELS_ERR_MASK) ? -1 : 0;
244+
}
241245

242-
/* Handle the word-aligned portion */
243-
if (aligned_len > 0) {
244-
ELS->ELS_DMA_RES0 = (uint32_t)(uintptr_t)out;
245-
ELS->ELS_DMA_RES0_LEN = aligned_len;
246-
ELS->ELS_CMDCFG0 = 0;
247-
ELS->ELS_CTRL = S50_ELS_CTRL_ELS_EN(1)
248-
| S50_ELS_CTRL_ELS_START(1)
249-
| S50_ELS_CTRL_ELS_CMD(ELS_CMD_RND_REQ);
250-
251-
while (ELS->ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK)
252-
;
253-
254-
status = ELS->ELS_STATUS;
255-
if (status & S50_ELS_STATUS_ELS_ERR_MASK)
246+
int hal_trng_get_entropy(unsigned char *out, unsigned int len)
247+
{
248+
uint32_t tmp;
249+
250+
/* Handle unaligned head (up to 3 bytes) via temporary word */
251+
if ((uintptr_t)out & 3U) {
252+
uint32_t head = 4U - ((uintptr_t)out & 3U);
253+
if (head > len)
254+
head = len;
255+
if (els_rnd_req(&tmp, 4) != 0)
256256
return -1;
257+
memcpy(out, &tmp, head);
258+
out += head;
259+
len -= head;
257260
}
258261

259-
/* Handle remaining bytes (1-3) with a temporary word */
260-
if (len > aligned_len) {
261-
uint32_t tmp;
262-
263-
ELS->ELS_DMA_RES0 = (uint32_t)(uintptr_t)&tmp;
264-
ELS->ELS_DMA_RES0_LEN = 4;
265-
ELS->ELS_CMDCFG0 = 0;
266-
ELS->ELS_CTRL = S50_ELS_CTRL_ELS_EN(1)
267-
| S50_ELS_CTRL_ELS_START(1)
268-
| S50_ELS_CTRL_ELS_CMD(ELS_CMD_RND_REQ);
269-
270-
while (ELS->ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK)
271-
;
272-
273-
status = ELS->ELS_STATUS;
274-
if (status & S50_ELS_STATUS_ELS_ERR_MASK)
262+
/* Bulk aligned portion in one request */
263+
if (len >= 4) {
264+
uint32_t aligned_len = len & ~3U;
265+
if (els_rnd_req(out, aligned_len) != 0)
275266
return -1;
267+
out += aligned_len;
268+
len -= aligned_len;
269+
}
276270

277-
memcpy(out + aligned_len, &tmp, len - aligned_len);
271+
/* Handle remaining tail bytes (1-3) via temporary word */
272+
if (len > 0) {
273+
if (els_rnd_req(&tmp, 4) != 0)
274+
return -1;
275+
memcpy(out, &tmp, len);
278276
}
279277

280278
return 0;

0 commit comments

Comments
 (0)