1 /* 2 * Copyright (c) 2018-2023, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /** 33 * @file Random.h 34 * 35 * @brief Interface to generate pseudo-random numbers 36 * 37 * @warning The numbers generated by this module are not crpytographically-secure! 38 * Do not use this module to generate keying material or for other 39 * security-related purposes! 40 * 41 * This module generates non-cryptographically-secure random numbers in an 42 * easy to use and fast way. 43 * 44 * There is a single global state that must be initialised by calling 45 * Random_seedAutomatic() or Random_seedManual(). Afterwards, you can call 46 * Random_getNumber() or Random_getBytes() as desired. Both are thread-safe 47 * and protect the internal state. 48 * 49 * The pseudo-random number generator used is the "xorwow" algorithm specified in 50 * Marsaglia's "Xorshift RNGs" paper. It keeps 20 bytes of state that must be 51 * seeded and has a period of 2^160 - 2^32 before a sequence wraps. 52 * 53 * Generating a random number with this algorithm is quite fast. Random_getNumber() 54 * only requires 82 instructions which is 1.7us on a 48MHz Cortex M4. That includes 55 * disabling interrupts. 56 * 57 * @code 58 * 59 * int_fast16_t status; 60 * uint32_t randomNumber; 61 * 62 * status = Random_seedAutomatic(); 63 * 64 * if (status != Random_STATUS_SUCCESS) { 65 * while(1); 66 * } 67 * 68 * randomNumber = Random_getNumber(); 69 * 70 * @endcode 71 * 72 * 73 */ 74 75 #ifndef ti_drivers_utils_Random__include 76 #define ti_drivers_utils_Random__include 77 78 #include <stdint.h> 79 #include <stdbool.h> 80 #include <stddef.h> 81 82 #ifdef __cplusplus 83 extern "C" { 84 #endif 85 86 #define Random_STATUS_SUCCESS (0) 87 #define Random_STATUS_ERROR (-1) 88 89 /*! @brief Length of the seed in bytes */ 90 #define Random_SEED_LENGTH (20) 91 92 /** 93 * @brief Seed internal state automatically 94 * 95 * This function seeds or reseeds the internal state. 96 * The method for generating the seed is device dependent. 97 * 98 * If a TRNG is available, it will be used to generate the seed. 99 * 100 * If a TRNG is not available, information unique to the device running 101 * the code will be used. This may be a unique device identifier or other 102 * information such as a MAC address. 103 * Since the seed is constant per device for devices without a TRNG, the 104 * number sequence will restart after each call to Random_seedAutomatic(). 105 * This will usually occur after rebooting the device. 106 * 107 * For CC23X0, RNG will be used to generate the seed, where the application needs to 108 * perform additional steps for initializing the RNG driver. 109 * 110 * If neither a TRNG nor a unique device identifier is available, 111 * a constant will be used. 112 * 113 * @return Returns a status code 114 * 115 * @sa Random_seedManual() 116 * 117 * @post Random_getNumber() 118 * 119 * @post Random_getBytes() 120 */ 121 extern int_fast16_t Random_seedAutomatic(void); 122 123 /** 124 * @brief Set the internal state to a specified seed 125 * 126 * This function sets the internal state to the seed specified 127 * by the application. 128 * 129 * @param seed Seed to set the internal state to 130 * 131 * @sa Random_seedAutomatic() 132 * 133 * @post Random_getNumber() 134 * 135 * @post Random_getBytes() 136 */ 137 extern void Random_seedManual(uint8_t seed[Random_SEED_LENGTH]); 138 139 /** 140 * @brief Returns a random number 141 * 142 * This function returns a random number and updates the 143 * internal state. 144 * 145 * @return Returns random number 146 * 147 * @pre Random_seedAutomatic() 148 * @pre Random_seedManual() 149 */ 150 extern uint32_t Random_getNumber(void); 151 152 /** 153 * Returns a number of random bytes 154 * 155 * This is a convenience function that fills the specified 156 * array with random bytes by repeatedly calling Random_getNumber(). 157 * 158 * @param buffer Buffer to fill with random bytes 159 * 160 * @param bufferSize Size of buffer. Any value is permitted, including 161 * those that are not multiples of sizeof(uint32_t). 162 * 163 * @pre Random_seedAutomatic() 164 * @pre Random_seedManual() 165 */ 166 extern void Random_getBytes(void *buffer, size_t bufferSize); 167 168 #ifdef __cplusplus 169 } 170 #endif 171 172 #endif /* ti_drivers_utils_Random__include */ 173