23
23
#include <stdlib.h>
24
24
#include "cmsis.h"
25
25
#include "trng_api.h"
26
+ #include "mbed_error.h"
27
+ #include "mbed_critical.h"
26
28
27
- /** trng_get_byte
28
- * @brief Get one byte of entropy from the RNG, assuming it is up and running.
29
- * @param obj TRNG obj
30
- * @param pointer to the hardware generated random byte.
31
- */
32
- static void trng_get_byte (trng_t * obj , unsigned char * byte )
33
- {
34
- * byte = (unsigned char )HAL_RNG_GetRandomNumber (& obj -> handle );
35
- }
29
+ static uint8_t users = 0 ;
36
30
37
31
void trng_init (trng_t * obj )
38
32
{
33
+ uint32_t dummy ;
34
+
35
+ /* We're only supporting a single user of RNG */
36
+ if (core_util_atomic_incr_u8 (& users , 1 ) > 1 ) {
37
+ error ("Only 1 RNG instance supported\r\n" );
38
+ }
39
+
39
40
#if defined(TARGET_STM32L4 )
40
41
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct ;
41
42
@@ -50,11 +51,13 @@ void trng_init(trng_t *obj)
50
51
51
52
/* Initialize RNG instance */
52
53
obj -> handle .Instance = RNG ;
54
+ obj -> handle .State = HAL_RNG_STATE_RESET ;
55
+ obj -> handle .Lock = HAL_UNLOCKED ;
56
+
53
57
HAL_RNG_Init (& obj -> handle );
54
58
55
59
/* first random number generated after setting the RNGEN bit should not be used */
56
- HAL_RNG_GetRandomNumber (& obj -> handle );
57
-
60
+ HAL_RNG_GenerateRandomNumber (& obj -> handle , & dummy );
58
61
}
59
62
60
63
void trng_free (trng_t * obj )
@@ -63,23 +66,32 @@ void trng_free(trng_t *obj)
63
66
HAL_RNG_DeInit (& obj -> handle );
64
67
/* RNG Peripheral clock disable - assume we're the only users of RNG */
65
68
__HAL_RCC_RNG_CLK_DISABLE ();
69
+
70
+ users = 0 ;
66
71
}
67
72
68
73
int trng_get_bytes (trng_t * obj , uint8_t * output , size_t length , size_t * output_length )
69
74
{
70
- int ret ;
75
+ int ret = 0 ;
76
+ volatile uint8_t random [4 ];
77
+ * output_length = 0 ;
71
78
72
79
/* Get Random byte */
73
- for ( uint32_t i = 0 ; i < length ; i ++ ){
74
- trng_get_byte (obj , output + i );
80
+ while ((* output_length < length ) && (ret == 0 )) {
81
+ if ( HAL_RNG_GenerateRandomNumber (& obj -> handle , (uint32_t * )random ) != HAL_OK ) {
82
+ ret = -1 ;
83
+ } else {
84
+ for (uint8_t i = 0 ; (i < 4 ) && (* output_length < length ) ; i ++ ) {
85
+ * output ++ = random [i ];
86
+ * output_length += 1 ;
87
+ random [i ] = 0 ;
88
+ }
89
+ }
75
90
}
76
91
77
- * output_length = length ;
78
92
/* Just be extra sure that we didn't do it wrong */
79
93
if ( ( __HAL_RNG_GET_FLAG (& obj -> handle , (RNG_FLAG_CECS | RNG_FLAG_SECS )) ) != 0 ) {
80
94
ret = -1 ;
81
- } else {
82
- ret = 0 ;
83
95
}
84
96
85
97
return ( ret );
0 commit comments