mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			[Silicon Labs] Add TRNG support
Adding support for the TRNG peripheral present on Series 1 Configuration 2 devices.pull/4497/head
							parent
							
								
									8d6bc1d47d
								
							
						
					
					
						commit
						466d4eab22
					
				| 
						 | 
					@ -148,6 +148,12 @@ typedef enum {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DEVICE_TRNG
 | 
				
			||||||
 | 
					struct trng_s {
 | 
				
			||||||
 | 
					    TRNG_TypeDef *instance;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,373 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  True Random Number Generator (TRNG) driver for Silicon Labs devices
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Copyright (C) 2016, Silicon Labs, http://www.silabs.com
 | 
				
			||||||
 | 
					 *  SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					 *  not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 *  You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 *  See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 *  limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "sl_trng.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(TRNG_PRESENT)
 | 
				
			||||||
 | 
					#include "em_cmu.h"
 | 
				
			||||||
 | 
					#include "em_common.h"
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FIFO_LEVEL_RETRY   (1000)
 | 
				
			||||||
 | 
					#define TEST_WORDS_MIN      (257)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TEST_VECTOR_CONDITIONING_KEY_SIZE  (4)
 | 
				
			||||||
 | 
					static const uint32_t
 | 
				
			||||||
 | 
					test_vector_conditioning_key[TEST_VECTOR_CONDITIONING_KEY_SIZE] =
 | 
				
			||||||
 | 
					  {0x16157E2B, 0xA6D2AE28, 0x8815F7AB, 0x3C4FCF09};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TEST_VECTOR_CONDITIONING_INPUT_SIZE (16)
 | 
				
			||||||
 | 
					static const uint32_t
 | 
				
			||||||
 | 
					test_vector_conditioning_input[TEST_VECTOR_CONDITIONING_INPUT_SIZE] =
 | 
				
			||||||
 | 
					  {0xE1BCC06B, 0x9199452A, 0x1A7434E1, 0x25199E7F,
 | 
				
			||||||
 | 
					   0x578A2DAE, 0x9CAC031E, 0xAC6FB79E, 0x518EAF45,
 | 
				
			||||||
 | 
					   0x461CC830, 0x11E45CA3, 0x19C1FBE5, 0xEF520A1A,
 | 
				
			||||||
 | 
					   0x45249FF6, 0x179B4FDF, 0x7B412BAD, 0x10376CE6};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TEST_VECTOR_CONDITIONING_OUTPUT_SIZE (4)
 | 
				
			||||||
 | 
					static const uint32_t
 | 
				
			||||||
 | 
					test_vector_conditioning_output[TEST_VECTOR_CONDITIONING_OUTPUT_SIZE] =
 | 
				
			||||||
 | 
					  {0xA1CAF13F, 0x09AC1F68, 0x30CA0E12, 0xA7E18675};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRNG_STARTUP_TEST_WAIT_RETRY  (10000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  TRNG_TypeDef *instance;
 | 
				
			||||||
 | 
					  CMU_Clock_TypeDef clock;
 | 
				
			||||||
 | 
					} sl_trng_device_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const sl_trng_device_t sl_trng_devices[TRNG_COUNT] = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(TRNG0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  TRNG0,
 | 
				
			||||||
 | 
					  cmuClock_TRNG0
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CMU_Clock_TypeDef sl_trng_get_clock( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  for(int i = 0; i < TRNG_COUNT; i++) {
 | 
				
			||||||
 | 
					    if(sl_trng_devices[i].instance == device) {
 | 
				
			||||||
 | 
					      return sl_trng_devices[i].clock;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return cmuClock_TRNG0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sl_trng_init( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Enable the TRNG's clock. */
 | 
				
			||||||
 | 
					    CMU_ClockEnable( sl_trng_get_clock(device), true );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    device->CONTROL =
 | 
				
			||||||
 | 
					        TRNG_CONTROL_ENABLE |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_REPCOUNTIEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_APT64IEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_APT4096IEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_PREIEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_ALMIEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Apply software reset */
 | 
				
			||||||
 | 
					    sl_trng_soft_reset(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Wait for TRNG to complete startup tests and start filling the FIFO. */
 | 
				
			||||||
 | 
					    for (i=0; (device->FIFOLEVEL == 0) && (i<TRNG_STARTUP_TEST_WAIT_RETRY); i++);
 | 
				
			||||||
 | 
					    EFM_ASSERT(i<TRNG_STARTUP_TEST_WAIT_RETRY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sl_trng_free( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Disable TRNG. */
 | 
				
			||||||
 | 
					    device->CONTROL = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Disable the TRNG clock. */
 | 
				
			||||||
 | 
					    CMU_ClockEnable( sl_trng_get_clock(device), false );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sl_trng_soft_reset( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t ctrl = device->CONTROL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctrl |= TRNG_CONTROL_SOFTRESET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    device->CONTROL = ctrl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctrl &= ~TRNG_CONTROL_SOFTRESET;
 | 
				
			||||||
 | 
					    device->CONTROL = ctrl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline
 | 
				
			||||||
 | 
					void sl_trng_write_test_data( TRNG_TypeDef *device, uint32_t data )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Wait for TESTDATA register to become ready for next word. */
 | 
				
			||||||
 | 
					    while (device->STATUS & TRNG_STATUS_TESTDATABUSY);
 | 
				
			||||||
 | 
					    device->TESTDATA = data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sl_trng_clear_fifo( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  volatile uint32_t val32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Empty FIFO */
 | 
				
			||||||
 | 
					  while ( device->FIFOLEVEL )
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					      val32 = device->FIFO;
 | 
				
			||||||
 | 
					      (void)val32;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl_trng_set_key( TRNG_TypeDef *device, const unsigned char *key )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t *_key = (uint32_t*) key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sl_trng_clear_fifo(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Program key in KEY registers of the TRNG. */
 | 
				
			||||||
 | 
					    device->KEY0 = *_key++;
 | 
				
			||||||
 | 
					    device->KEY1 = *_key++;
 | 
				
			||||||
 | 
					    device->KEY2 = *_key++;
 | 
				
			||||||
 | 
					    device->KEY3 = *_key++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl_trng_check_conditioning( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t val32;
 | 
				
			||||||
 | 
					    int i, ret=0;
 | 
				
			||||||
 | 
					    uint32_t ctrl = device->CONTROL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Setup control register */
 | 
				
			||||||
 | 
					    device->CONTROL = TRNG_CONTROL_ENABLE | TRNG_CONTROL_TESTEN |
 | 
				
			||||||
 | 
					                      TRNG_CONTROL_BYPNIST | TRNG_CONTROL_BYPAIS31;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Apply software reset */
 | 
				
			||||||
 | 
					    sl_trng_soft_reset(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Write test vector to the key register. */
 | 
				
			||||||
 | 
					    sl_trng_set_key(device,
 | 
				
			||||||
 | 
					                    (const unsigned char*)test_vector_conditioning_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Write test vector to the TESTDATA register */
 | 
				
			||||||
 | 
					    for (i=0; i<TEST_VECTOR_CONDITIONING_INPUT_SIZE; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      sl_trng_write_test_data(device,
 | 
				
			||||||
 | 
					                              test_vector_conditioning_input[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i=0; i<TEST_VECTOR_CONDITIONING_OUTPUT_SIZE; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Wait for data to become available in the FIFO. */
 | 
				
			||||||
 | 
					        while ( 0 == device->FIFOLEVEL );
 | 
				
			||||||
 | 
					        /* Read output from the conditioning function */
 | 
				
			||||||
 | 
					        val32 = device->FIFO;
 | 
				
			||||||
 | 
					        /* Compare with expected test vector. */
 | 
				
			||||||
 | 
					        if (val32 != test_vector_conditioning_output[i])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /*
 | 
				
			||||||
 | 
					            mbedtls_printf("Conditioning test failed. "
 | 
				
			||||||
 | 
					                           "Test output word %d 0x%lx. Expected 0x%lx\n",
 | 
				
			||||||
 | 
					                           i, val32, test_vector_conditioning_output[i]);
 | 
				
			||||||
 | 
					            */
 | 
				
			||||||
 | 
					            ret = SL_TRNG_ERR_CONDITIONING_TEST_FAILED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Restore initial value of control register */
 | 
				
			||||||
 | 
					    device->CONTROL = ctrl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl_trng_check_status( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t status = device->STATUS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( (status & (TRNG_STATUS_PREIF
 | 
				
			||||||
 | 
					                    | TRNG_STATUS_REPCOUNTIF
 | 
				
			||||||
 | 
					                    | TRNG_STATUS_APT64IF
 | 
				
			||||||
 | 
					                    | TRNG_STATUS_APT4096IF
 | 
				
			||||||
 | 
					                    | TRNG_STATUS_ALMIF)) == 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* No errors */
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( status & TRNG_STATUS_PREIF )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* On a preliminary noise alarm we clear the FIFO and clear
 | 
				
			||||||
 | 
					         * the alarm. The preliminary noise alarm is not critical. */
 | 
				
			||||||
 | 
					        status &= ~TRNG_STATUS_PREIF;
 | 
				
			||||||
 | 
					        device->STATUS = status;
 | 
				
			||||||
 | 
					        sl_trng_clear_fifo(device);
 | 
				
			||||||
 | 
					        return SL_TRNG_ERR_PRELIMINARY_NOISE_ALARM;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Clear alarm conditions by doing a TRNG soft reset. */
 | 
				
			||||||
 | 
					        sl_trng_soft_reset( device );
 | 
				
			||||||
 | 
					        if ( status & TRNG_STATUS_REPCOUNTIF )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return SL_TRNG_ERR_REPETITION_COUNT_TEST_FAILED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ( status & TRNG_STATUS_APT64IF )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return SL_TRNG_ERR_ADAPTIVE_PROPORTION_TEST_64_FAILED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ( status & TRNG_STATUS_APT4096IF )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return SL_TRNG_ERR_ADAPTIVE_PROPORTION_TEST_4096_FAILED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ( status & TRNG_STATUS_ALMIF )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return SL_TRNG_ERR_NOISE_ALARM;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl_trng_check_entropy( TRNG_TypeDef *device )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    volatile uint32_t val32;
 | 
				
			||||||
 | 
					    int i, ret = 0;
 | 
				
			||||||
 | 
					    uint32_t ctrl = device->CONTROL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Setup control register */
 | 
				
			||||||
 | 
					    device->CONTROL =
 | 
				
			||||||
 | 
					        TRNG_CONTROL_ENABLE |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_REPCOUNTIEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_APT64IEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_APT4096IEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_PREIEN |
 | 
				
			||||||
 | 
					        TRNG_CONTROL_ALMIEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Apply software reset */
 | 
				
			||||||
 | 
					    sl_trng_soft_reset(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Check FIFO level is non-zero . */
 | 
				
			||||||
 | 
					    for (i=0; i<FIFO_LEVEL_RETRY; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ( device->FIFOLEVEL )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* Check for no data within timeout (max retry count) */
 | 
				
			||||||
 | 
					    if (i>=FIFO_LEVEL_RETRY)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SL_TRNG_ERR_NO_DATA;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Read at least 4097x2 bits (~257 x 32 bits) in order for the longest
 | 
				
			||||||
 | 
					           test to complete (adaptive proportion test of 4096 samples). */
 | 
				
			||||||
 | 
					        for (i=0; i<TEST_WORDS_MIN; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            val32 = device->FIFO;
 | 
				
			||||||
 | 
					            (void)val32;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Check in status register for errors. */
 | 
				
			||||||
 | 
					        ret = sl_trng_check_status( device );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Restore initial value of control register */
 | 
				
			||||||
 | 
					    device->CONTROL = ctrl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sl_trng_read_chunk( TRNG_TypeDef *device,
 | 
				
			||||||
 | 
					                                unsigned char *output,
 | 
				
			||||||
 | 
					                                size_t len )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t * out32 = (uint32_t *) output;
 | 
				
			||||||
 | 
					    uint32_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Read known good available data. */
 | 
				
			||||||
 | 
					    while ( len >= 4)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *out32++ = device->FIFO;
 | 
				
			||||||
 | 
					        len -= 4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Handle the case where len is not a multiple of 4. */
 | 
				
			||||||
 | 
					    if ( len < 4 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        tmp = device->FIFO;
 | 
				
			||||||
 | 
					        memcpy((uint8_t *)out32, (const uint8_t *) &tmp, len);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl_trng_poll( TRNG_TypeDef *device,
 | 
				
			||||||
 | 
					                  unsigned char *output,
 | 
				
			||||||
 | 
					                  size_t len,
 | 
				
			||||||
 | 
					                  size_t *olen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size_t output_len = 0;
 | 
				
			||||||
 | 
					    size_t count = 0;
 | 
				
			||||||
 | 
					    size_t available;
 | 
				
			||||||
 | 
					    int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (len > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        available = device->FIFOLEVEL * 4;
 | 
				
			||||||
 | 
					        if (available == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(SL_TRNG_IGNORE_ALL_ALARMS)
 | 
				
			||||||
 | 
					        /* Check status for current data in FIFO
 | 
				
			||||||
 | 
					         * and handle any error conditions. */
 | 
				
			||||||
 | 
					        ret = sl_trng_check_status( device );
 | 
				
			||||||
 | 
					#if defined(SL_TRNG_IGNORE_NOISE_ALARMS)
 | 
				
			||||||
 | 
					        /* Ignore noise alarms by returning 0 (OK) if they occur and
 | 
				
			||||||
 | 
					         * keeping the already generated random data. */
 | 
				
			||||||
 | 
					        if ( (ret == SL_TRNG_ERR_PRELIMINARY_NOISE_ALARM) ||
 | 
				
			||||||
 | 
					             (ret == SL_TRNG_ERR_NOISE_ALARM) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ret = 0;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        /* Alarm has been signaled so we throw the generated data away. */
 | 
				
			||||||
 | 
					        if (ret != 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            output_len = 0;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        count = SL_MIN(len, available);
 | 
				
			||||||
 | 
					        sl_trng_read_chunk(device, output, count);
 | 
				
			||||||
 | 
					        output += count;
 | 
				
			||||||
 | 
					        output_len += count;
 | 
				
			||||||
 | 
					        len -= count;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *olen = output_len;
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* TRNG_PRESENT */
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,239 @@
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *  \file sl_trng.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  \brief True Random Number Generator (TRNG) driver for Silicon Labs devices
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Copyright (C) 2016, Silicon Labs, http://www.silabs.com
 | 
				
			||||||
 | 
					 *  SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					 *  not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 *  You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 *  See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 *  limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef SL_TRNG_H
 | 
				
			||||||
 | 
					#define SL_TRNG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************************************************************//**
 | 
				
			||||||
 | 
					 * \addtogroup sl_crypto_trng Silicon Labs True Random Number Generator Plugin
 | 
				
			||||||
 | 
					 * \brief True Random Number Generator (TRNG) driver for Silicon Labs devices.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \details The EFR32xG12 and EFM32xG12 and newer Silicon Labs devices contains
 | 
				
			||||||
 | 
					 * a True Random Number Generator (TRNG) peripheral. The TRNG is a
 | 
				
			||||||
 | 
					 * non-deterministic random number generator based on a full hardware solution.
 | 
				
			||||||
 | 
					 * The TRNG contains a 64 x 32-bit FIFO for reading out random numbers.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The samples from entropy source within the TRNG are monitored permanently by
 | 
				
			||||||
 | 
					 * 4 built in tests that detect issues with the noise source. The tests are
 | 
				
			||||||
 | 
					 * specified in NIST-800-90B and AIS31. The tests that are always checking the
 | 
				
			||||||
 | 
					 * entropy source are "Repetition Count Test", "Adaptive Proportion Test
 | 
				
			||||||
 | 
					 * (64-sample window)", "Adaptive Proportion Test (4096-sample window)" and
 | 
				
			||||||
 | 
					 * the "AIS31 Online Test".
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * In addition the TRNG has options for running startup tests. When these tests
 | 
				
			||||||
 | 
					 * are enabled the TRNG FIFO will not contains any data before all the startup
 | 
				
			||||||
 | 
					 * tests have passed. There are 4 TRNG startup tests, 3 of the tests are
 | 
				
			||||||
 | 
					 * specified in NIST-800-90B. These are the "Repetition Count Test", "Adaptive
 | 
				
			||||||
 | 
					 * Proportion Test (64-sample window)" and "Adaptive Proportion Test
 | 
				
			||||||
 | 
					 * (4096-sample window)". The last startup test is the AIS31 startup test. By
 | 
				
			||||||
 | 
					 * default when using this driver all the startup tests are enabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * The TRNG module implements an entropy source plugin module for mbed TLS that can 
 | 
				
			||||||
 | 
					 * be used in applications needing random numbers or indirectly using mbed TLS 
 | 
				
			||||||
 | 
					 * modules that depend on the random number generation interfaces of mbed TLS. 
 | 
				
			||||||
 | 
					 * The define @ref MBEDTLS_TRNG_C will compile the TRNG module. The TRNG is enabled as 
 | 
				
			||||||
 | 
					 * an mbed TLS entropy source by defining @ref MBEDTLS_ENTROPY_ALT, 
 | 
				
			||||||
 | 
					 * @ref MBEDTLS_ENTROPY_INIT_ALT and @ref MBEDTLS_ENTROPY_FREE_ALT. 
 | 
				
			||||||
 | 
					 * The TRNG functions are declared in the 'mbedtls/sl_crypto/include/trng.h' file.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \{
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "em_device.h"
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TRNG specific error codes: */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_BASE                                 (0xF100E000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Conditioning test failed. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_CONDITIONING_TEST_FAILED             ((int)SL_TRNG_ERR_BASE | 0x00000001)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** No data received in the TRNG FIFO. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_NO_DATA                              ((int)SL_TRNG_ERR_BASE | 0x00000002)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Repetition Count test failed. The repetition count test fails when the
 | 
				
			||||||
 | 
					 *  TRNG detects that the output become "stuck" on a single value for a long
 | 
				
			||||||
 | 
					 *  period of time. The repetition count test is described in NIST-800-90B.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  If an application detects this error then the TRNG should be reset. The
 | 
				
			||||||
 | 
					 *  repetition count test is always enabled. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_REPETITION_COUNT_TEST_FAILED         ((int)SL_TRNG_ERR_BASE | 0x00000003)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Adaptive Proportion test over 64 samples failed. The adaptive proportion
 | 
				
			||||||
 | 
					 *  test is designed to detect a large loss of entropy that might occur as a
 | 
				
			||||||
 | 
					 *  result of some physical failure or environmental change affecting the
 | 
				
			||||||
 | 
					 *  TRNG.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  The test will fail when a 2 bit sample from the TRNG is repeated an
 | 
				
			||||||
 | 
					 *  unusual amount of times within a window of 64 bits. The adaptive
 | 
				
			||||||
 | 
					 *  proportion test is further described in NIST-800-90B.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  If an application detects this error then the TRNG should be reset. The
 | 
				
			||||||
 | 
					 *  adaptive proportion test over 64 samples is always enabled. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_ADAPTIVE_PROPORTION_TEST_64_FAILED   ((int)SL_TRNG_ERR_BASE | 0x00000004)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Adaptive Proportion test over 4096 samples failed. The adaptive proportion
 | 
				
			||||||
 | 
					 *  test is designed to detect a large loss of entropy that might occur as a
 | 
				
			||||||
 | 
					 *  result of some physical failure or environmental change affecting the
 | 
				
			||||||
 | 
					 *  TRNG.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  The test will fail when a 2 bit sample from the TRNG is repeated an
 | 
				
			||||||
 | 
					 *  unusual amount of times within a window of 4096 bits. The adaptive
 | 
				
			||||||
 | 
					 *  proportion test is further described in NIST-800-90B.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  If an application detects this error then the TRNG should be reset. The
 | 
				
			||||||
 | 
					 *  adaptive proportion test over 4096 samples is always enabled. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_ADAPTIVE_PROPORTION_TEST_4096_FAILED ((int)SL_TRNG_ERR_BASE | 0x00000005)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** AIS31 test noise alarm. The AIS31 test is designed to monitor and verify
 | 
				
			||||||
 | 
					 *  the statistical distribution of the random numbers from the TRNG. The test
 | 
				
			||||||
 | 
					 *  performs 512 consecutive 128 bit X^2 calculations with 4 bit words. The
 | 
				
			||||||
 | 
					 *  details of the AIS31 test can be found in the AIS31 specification.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  The test will fail when an unusual statistical distribution of the TRNG
 | 
				
			||||||
 | 
					 *  output is found.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  If an application detects this error then the TRNG should be reset. The
 | 
				
			||||||
 | 
					 *  AIS31 test is always enabled. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_NOISE_ALARM                          ((int)SL_TRNG_ERR_BASE | 0x00000006)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** AIS31 test Preliminary Noise alarm. The preliminary noise alarms generated
 | 
				
			||||||
 | 
					 *  from the same AIS31 test that generates \ref SL_TRNG_ERR_NOISE_ALARM.
 | 
				
			||||||
 | 
					 *  The difference between a preliminary noise alarm and a noise alarm is the
 | 
				
			||||||
 | 
					 *  severity and the expected frequency. A preliminary noise alarm will happen
 | 
				
			||||||
 | 
					 *  more frequently than a noise alarm, and a preliminary noise alarm is not
 | 
				
			||||||
 | 
					 *  considered critical. The preliminary noise alarm is not uncommon and should
 | 
				
			||||||
 | 
					 *  be expected from time to time when reading data from the TRNG.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  If an application detects a preliminary noise alarm then the recommended
 | 
				
			||||||
 | 
					 *  action is to flush the TRNG FIFO, or reset the TRNG. */
 | 
				
			||||||
 | 
					#define SL_TRNG_ERR_PRELIMINARY_NOISE_ALARM              ((int)SL_TRNG_ERR_BASE | 0x00000007)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(TRNG_PRESENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief          Initialize TRNG context
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \details        This function will enable the TRNG device by starting
 | 
				
			||||||
 | 
					 *                 the device's clock, initializing the control register, perform
 | 
				
			||||||
 | 
					 *                 soft reset and wait until data is available in the FIFO.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx      TRNG device to be initialized
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void sl_trng_init( TRNG_TypeDef *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief          Free TRNG context
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \details        This function will disable the TRNG peripheral by stopping
 | 
				
			||||||
 | 
					 *                 the TRNG's clock.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx      TRNG device to be released
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void sl_trng_free( TRNG_TypeDef *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief          Set the TRNG conditioning key
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx      TRNG device
 | 
				
			||||||
 | 
					 * \param key      128-bit AES key
 | 
				
			||||||
 | 
					 *  
 | 
				
			||||||
 | 
					 * \return
 | 
				
			||||||
 | 
					 *   0 if success. Error code if failure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sl_trng_set_key( TRNG_TypeDef *ctx, const unsigned char *key );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief          Check the TRNG conditioning function
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx      TRNG device
 | 
				
			||||||
 | 
					 *  
 | 
				
			||||||
 | 
					 * \return
 | 
				
			||||||
 | 
					 *   0 if success. \ref SL_TRNG_ERR_CONDITIONING_TEST_FAILED on failure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sl_trng_check_conditioning( TRNG_TypeDef *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief          Check the TRNG entropy source is producing random data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx      TRNG device
 | 
				
			||||||
 | 
					 *  
 | 
				
			||||||
 | 
					 * \return
 | 
				
			||||||
 | 
					 *   0 if success. Error code if failure. Note that this function can return
 | 
				
			||||||
 | 
					 *                 a \ref SL_TRNG_ERR_PRELIMINARY_NOISE_ALARM on some occasions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sl_trng_check_entropy( TRNG_TypeDef *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Poll for entropy data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \details         This function will read available random data from the TRNG
 | 
				
			||||||
 | 
					 *                  FIFO and place it into the output buffer. The len parameter
 | 
				
			||||||
 | 
					 *                  tells this function the maximum number of bytes to read.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *                  Note that the number of bytes read from the TRNG might differ
 | 
				
			||||||
 | 
					 *                  from the number of bytes requested. If any alarms are signaled
 | 
				
			||||||
 | 
					 *                  or the TRNG FIFO is empty then this function will return early.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *                  The return value should be used to see if the operation was
 | 
				
			||||||
 | 
					 *                  successful of if an alarm was encountered while reading the
 | 
				
			||||||
 | 
					 *                  FIFO. The content of the olen parameter can be used to check
 | 
				
			||||||
 | 
					 *                  how many bytes were actually read.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       TRNG context
 | 
				
			||||||
 | 
					 * \param output    Buffer to fill with data from the TRNG
 | 
				
			||||||
 | 
					 * \param len       Maximum number of bytes to fill in output buffer.
 | 
				
			||||||
 | 
					 * \param olen      The actual amount of bytes put into the buffer (Can be 0)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          \li 0 if no critical failures occurred,
 | 
				
			||||||
 | 
					 *                  \li SL_TRNG_ERR_PRELIMINARY_NOISE_ALARM if a AIS31
 | 
				
			||||||
 | 
					 *                  preliminary noise alarm was detected while reading the FIFO,
 | 
				
			||||||
 | 
					 *                  \li SL_TRNG_ERR_NOISE_ALARM if an AIS31 noise alarm
 | 
				
			||||||
 | 
					 *                  was detected.
 | 
				
			||||||
 | 
					 *                  \li SL_TRNG_ERR_REPETITION_COUNT_TEST_FAILED if the
 | 
				
			||||||
 | 
					 *                  repetition count test failed while reading the FIFO.
 | 
				
			||||||
 | 
					 *                  \li SL_TRNG_ERR_ADAPTIVE_PROPORTION_TEST_64_FAILED if the
 | 
				
			||||||
 | 
					 *                  adaptive proportion test over 64 samples failed while reading
 | 
				
			||||||
 | 
					 *                  the FIFO.
 | 
				
			||||||
 | 
					 *                  \li SL_TRNG_ERR_ADAPTIVE_PROPORTION_TEST_4096_FAILED if
 | 
				
			||||||
 | 
					 *                  the adaptive proportion test over 4096 samples failed while
 | 
				
			||||||
 | 
					 *                  reading from the FIFO.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sl_trng_poll( TRNG_TypeDef *ctx,
 | 
				
			||||||
 | 
					                  unsigned char *output,
 | 
				
			||||||
 | 
					                  size_t len,
 | 
				
			||||||
 | 
					                  size_t *olen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Execute TRNG soft reset
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \details         This function performs a TRNG soft reset. The TRNG soft
 | 
				
			||||||
 | 
					 *                  reset can be used to clear error conditions such as Noise
 | 
				
			||||||
 | 
					 *                  Alarms, etc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       TRNG device
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void sl_trng_soft_reset( TRNG_TypeDef *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* TRNG_PRESENT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \} (end addtogroup sl_crypto_trng) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* SL_TRNG_H */
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					/***************************************************************************//**
 | 
				
			||||||
 | 
					 * @file trng_api.c
 | 
				
			||||||
 | 
					 *******************************************************************************
 | 
				
			||||||
 | 
					 * @section License
 | 
				
			||||||
 | 
					 * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b>
 | 
				
			||||||
 | 
					 *******************************************************************************
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					 * not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "trng_api.h"
 | 
				
			||||||
 | 
					#include "sl_trng.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(DEVICE_TRNG)
 | 
				
			||||||
 | 
					static bool is_trng_enabled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void trng_init(trng_t *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  /* Use TRNG0 for all HW entropy collection */
 | 
				
			||||||
 | 
					  obj->instance = TRNG0;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if(!is_trng_enabled) {
 | 
				
			||||||
 | 
					    sl_trng_init(obj->instance);
 | 
				
			||||||
 | 
					    is_trng_enabled = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void trng_free(trng_t *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  /* Don't turn off the TRNG to avoid clearing its FIFO */
 | 
				
			||||||
 | 
					  (void) obj;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int ret = sl_trng_poll(obj->instance,
 | 
				
			||||||
 | 
					                         output,
 | 
				
			||||||
 | 
					                         length,
 | 
				
			||||||
 | 
					                         output_length);
 | 
				
			||||||
 | 
					  return (ret == 0) ? 0 : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /* DEVICE_TRNG */
 | 
				
			||||||
| 
						 | 
					@ -2453,7 +2453,7 @@
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "EFM32PG12_STK3402": {
 | 
					    "EFM32PG12_STK3402": {
 | 
				
			||||||
        "inherits": ["EFM32PG12B500F1024GL125"],
 | 
					        "inherits": ["EFM32PG12B500F1024GL125"],
 | 
				
			||||||
        "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
 | 
					        "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
 | 
				
			||||||
        "forced_reset_timeout": 2,
 | 
					        "forced_reset_timeout": 2,
 | 
				
			||||||
        "config": {
 | 
					        "config": {
 | 
				
			||||||
            "hf_clock_src": {
 | 
					            "hf_clock_src": {
 | 
				
			||||||
| 
						 | 
					@ -2504,7 +2504,7 @@
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
	"TB_SENSE_12": {
 | 
						"TB_SENSE_12": {
 | 
				
			||||||
        "inherits": ["EFR32MG12P332F1024GL125"],
 | 
					        "inherits": ["EFR32MG12P332F1024GL125"],
 | 
				
			||||||
        "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
 | 
					        "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
 | 
				
			||||||
        "forced_reset_timeout": 5,
 | 
					        "forced_reset_timeout": 5,
 | 
				
			||||||
        "config": {
 | 
					        "config": {
 | 
				
			||||||
            "hf_clock_src": {
 | 
					            "hf_clock_src": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue