• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019, The OpenThread Authors.
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 are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *  This file includes definitions for OpenThread random number generation.
32  */
33 
34 #ifndef RANDOM_HPP_
35 #define RANDOM_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 
41 #include <openthread/platform/crypto.h>
42 
43 #include "common/debug.hpp"
44 #include "common/error.hpp"
45 #include "common/non_copyable.hpp"
46 
47 namespace ot {
48 namespace Random {
49 
50 /**
51  * This class manages random number generator initialization/deinitialization.
52  *
53  */
54 class Manager : private NonCopyable
55 {
56 public:
57     /**
58      * This constructor initializes the object.
59      *
60      */
61     Manager(void);
62 
63     /**
64      * This destructor deinitializes the object.
65      *
66      */
67     ~Manager(void);
68 
69     /**
70      * This static method generates and returns a random value using a non-crypto Pseudo Random Number Generator.
71      *
72      * @returns    A random `uint32_t` value.
73      *
74      */
75     static uint32_t NonCryptoGetUint32(void);
76 
77 #if !OPENTHREAD_RADIO
78     /**
79      * This static method fills a given buffer with cryptographically secure random bytes.
80      *
81      * @param[out] aBuffer  A pointer to a buffer to fill with the random bytes.
82      * @param[in]  aSize    Size of buffer (number of bytes to fill).
83      *
84      * @retval kErrorNone    Successfully filled buffer with random values.
85      *
86      */
CryptoFillBuffer(uint8_t * aBuffer,uint16_t aSize)87     static Error CryptoFillBuffer(uint8_t *aBuffer, uint16_t aSize) { return otPlatCryptoRandomGet(aBuffer, aSize); }
88 #endif
89 
90 private:
91     class NonCryptoPrng // A non-crypto Pseudo Random Number Generator (PRNG)
92     {
93     public:
94         void     Init(uint32_t aSeed);
95         uint32_t GetNext(void);
96 
97     private:
98         uint32_t mState;
99     };
100 
101     static uint16_t      sInitCount;
102     static NonCryptoPrng sPrng;
103 };
104 
105 namespace NonCrypto {
106 
107 /**
108  * This function generates and returns a random `uint32_t` value.
109  *
110  * @returns    A random `uint32_t` value.
111  *
112  */
GetUint32(void)113 inline uint32_t GetUint32(void)
114 {
115     return Manager::NonCryptoGetUint32();
116 }
117 
118 /**
119  * This function generates and returns a random byte.
120  *
121  * @returns A random `uint8_t` value.
122  *
123  */
GetUint8(void)124 inline uint8_t GetUint8(void)
125 {
126     return static_cast<uint8_t>(GetUint32() & 0xff);
127 }
128 
129 /**
130  * This function generates and returns a random `uint16_t` value.
131  *
132  * @returns A random `uint16_t` value.
133  *
134  */
GetUint16(void)135 inline uint16_t GetUint16(void)
136 {
137     return static_cast<uint16_t>(GetUint32() & 0xffff);
138 }
139 
140 /**
141  * This function generates and returns a random `uint8_t` value within a given range `[aMin, aMax)`.
142  *
143  * @param[in]  aMin  A minimum value (this value can be included in returned random result).
144  * @param[in]  aMax  A maximum value (this value is excluded from returned random result).
145  *
146  * @returns    A random `uint8_t` value in the given range (i.e., aMin <= random value < aMax).
147  *
148  */
149 uint8_t GetUint8InRange(uint8_t aMin, uint8_t aMax);
150 
151 /**
152  * This function generates and returns a random `uint16_t` value within a given range `[aMin, aMax)`.
153  *
154  * @note The returned random value can include the @p aMin value but excludes the @p aMax.
155  *
156  * @param[in]  aMin  A minimum value (this value can be included in returned random result).
157  * @param[in]  aMax  A maximum value (this value is excluded from returned random result).
158  *
159  * @returns    A random `uint16_t` value in the given range (i.e., aMin <= random value < aMax).
160  *
161  */
162 uint16_t GetUint16InRange(uint16_t aMin, uint16_t aMax);
163 
164 /**
165  * This function generates and returns a random `uint32_t` value within a given range `[aMin, aMax)`.
166  *
167  * @note The returned random value can include the @p aMin value but excludes the @p aMax.
168  *
169  * @param[in]  aMin  A minimum value (this value can be included in returned random result).
170  * @param[in]  aMax  A maximum value (this value is excluded from returned random result).
171  *
172  * @returns    A random `uint32_t` value in the given range (i.e., aMin <= random value < aMax).
173  *
174  */
175 uint32_t GetUint32InRange(uint32_t aMin, uint32_t aMax);
176 
177 /**
178  * This function fills a given buffer with random bytes.
179  *
180  * @param[out] aBuffer  A pointer to a buffer to fill with the random bytes.
181  * @param[in]  aSize    Size of buffer (number of bytes to fill).
182  *
183  */
184 void FillBuffer(uint8_t *aBuffer, uint16_t aSize);
185 
186 /**
187  * This function adds a random jitter within a given range to a given value.
188  *
189  * @param[in]  aValue     A value to which the random jitter is added.
190  * @param[in]  aJitter    Maximum jitter. Random jitter is selected from the range `[-aJitter, aJitter]`.
191  *
192  * @returns    The given value with an added random jitter.
193  *
194  */
195 uint32_t AddJitter(uint32_t aValue, uint16_t aJitter);
196 
197 } // namespace NonCrypto
198 
199 #if !OPENTHREAD_RADIO
200 
201 namespace Crypto {
202 
203 /**
204  * This function fills a given buffer with cryptographically secure random bytes.
205  *
206  * @param[out] aBuffer  A pointer to a buffer to fill with the random bytes.
207  * @param[in]  aSize    Size of buffer (number of bytes to fill).
208  *
209  * @retval kErrorNone    Successfully filled buffer with random values.
210  *
211  */
FillBuffer(uint8_t * aBuffer,uint16_t aSize)212 inline Error FillBuffer(uint8_t *aBuffer, uint16_t aSize)
213 {
214     return Manager::CryptoFillBuffer(aBuffer, aSize);
215 }
216 
217 } // namespace Crypto
218 
219 #endif // !OPENTHREAD_RADIO
220 
221 } // namespace Random
222 } // namespace ot
223 
224 #endif // RANDOM_HPP_
225