Skip to content

Commit 5a7d5d1

Browse files
yanescasimonbutcher
authored andcommitted
Make use of the K64F hardware entropy source.
1 parent 9127bcc commit 5a7d5d1

File tree

2 files changed

+43
-31
lines changed

2 files changed

+43
-31
lines changed
Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Temporary "entropy" collector for Cortex-M4
2+
* Hardware entropy collector for the K64F, using Freescale's RNGA
33
*
44
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
55
* SPDX-License-Identifier: Apache-2.0
@@ -19,47 +19,64 @@
1919
* This file is part of mbed TLS (https://tls.mbed.org)
2020
*/
2121

22+
#if defined(TARGET_LIKE_K64F)
23+
2224
/*
23-
* WARNING: this is a temporary hack!
24-
* 1. Currently does not provide strong entropy, should be replaced to use the
25-
* on-board hardware RNG (see IOTSSL-303)
26-
* 2. This should be in a separete yotta module which would be a target
27-
* dependency of mbedtls (see IOTSSL-313)
25+
* Reference: "K64 Sub-Family Reference Manual, Rev. 2", chapter 34
2826
*/
2927

30-
#if defined(TARGET_LIKE_CORTEX_M4)
31-
32-
#include "MK64F12.h"
33-
#include "core_cm4.h"
34-
#include <string.h>
28+
#include "fsl_clock_manager.h"
3529

36-
unsigned long hardclock( void )
30+
/*
31+
* Get one byte of entropy from the RNG, assuming it is up and running.
32+
* As recommended (34.1.1), get only one bit of each output.
33+
*/
34+
static void rng_get_byte( unsigned char *byte )
3735
{
38-
static int dwt_started = 0;
36+
size_t bit;
3937

40-
if( dwt_started == 0 )
38+
/* 34.5 Steps 3-4-5: poll SR and read from OR when ready */
39+
for( bit = 0; bit < 8; bit++ )
4140
{
42-
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
43-
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
41+
while( ( RNG->SR & RNG_SR_OREG_LVL_MASK ) == 0 );
42+
*byte |= ( RNG->OR & 1 ) << bit;
4443
}
45-
46-
return( DWT->CYCCNT );
4744
}
4845

46+
/*
47+
* Get len bytes of entropy from the hardware RNG.
48+
*/
4949
int mbedtls_hardware_poll( void *data,
5050
unsigned char *output, size_t len, size_t *olen )
5151
{
52-
unsigned long timer = hardclock();
52+
size_t i;
53+
int ret;
5354
((void) data);
54-
*olen = 0;
5555

56-
if( len < sizeof(unsigned long) )
57-
return( 0 );
56+
CLOCK_SYS_EnableRngaClock( 0 );
57+
58+
/* Set "Interrupt Mask", "High Assurance" and "Go",
59+
* unset "Clear interrupt" and "Sleep" */
60+
RNG->CR = RNG_CR_INTM_MASK | RNG_CR_HA_MASK | RNG_CR_GO_MASK;
61+
62+
for( i = 0; i < len; i++ )
63+
rng_get_byte( output + i );
64+
65+
/* Just be extra sure that we didn't do it wrong */
66+
if( ( RNG->SR & RNG_SR_SECV_MASK ) != 0 )
67+
{
68+
ret = -1;
69+
goto cleanup;
70+
}
71+
72+
*olen = len;
73+
ret = 0;
5874

59-
memcpy( output, &timer, sizeof(unsigned long) );
60-
*olen = sizeof(unsigned long);
75+
cleanup:
76+
/* Disable clock to save power - assume we're the only users of RNG */
77+
CLOCK_SYS_DisableRngaClock( 0 );
6178

62-
return( 0 );
79+
return( ret );
6380
}
6481

6582
#endif

core/mbedtls/targets/TARGET_MCU_K64F/mbedtls/target_config.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@
2525
#undef MBEDTLS_FS_IO
2626
#endif
2727

28-
/*
29-
* WARNING: this is a temporary hack!
30-
* 2. This should be in a separete yotta module which would be a target
31-
* dependency of mbedtls (see IOTSSL-313)
32-
*/
33-
#if defined(TARGET_LIKE_CORTEX_M4)
28+
#if defined(TARGET_LIKE_K64F)
3429
#define MBEDTLS_ENTROPY_HARDWARE_ALT
3530
#endif

0 commit comments

Comments
 (0)