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 manager class.
32  */
33 
34 #ifndef RANDOM_MANAGER_HPP_
35 #define RANDOM_MANAGER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 
41 #if !OPENTHREAD_RADIO
42 #include <mbedtls/ctr_drbg.h>
43 #include <mbedtls/entropy.h>
44 #endif
45 
46 #include "common/error.hpp"
47 #include "common/non_copyable.hpp"
48 
49 #if (!defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \
50      (!defined(MBEDTLS_NO_PLATFORM_ENTROPY) || defined(MBEDTLS_HAVEGE_C) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT)))
51 #define OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
52 #endif
53 
54 namespace ot {
55 
56 /**
57  * This class manages random number generator initialization/deinitialization.
58  *
59  */
60 class RandomManager : private NonCopyable
61 {
62 public:
63     /**
64      * This constructor initializes the object.
65      *
66      */
67     RandomManager(void);
68 
69     /**
70      * This destructor deinitializes the object.
71      *
72      */
73     ~RandomManager(void);
74 
75     /**
76      * This static method generates and returns a random value using a non-crypto Pseudo Random Number Generator.
77      *
78      * @returns    A random `uint32_t` value.
79      *
80      */
81     static uint32_t NonCryptoGetUint32(void);
82 
83 #if !OPENTHREAD_RADIO
84     /**
85      * This static method returns the initialized mbedtls_entropy_context.
86      *
87      * @returns  A pointer to initialized mbedtls_entropy_context.
88      */
GetMbedTlsEntropyContext(void)89     static mbedtls_entropy_context *GetMbedTlsEntropyContext(void) { return sEntropy.GetContext(); }
90 
91     /**
92      * This static method fills a given buffer with cryptographically secure random bytes.
93      *
94      * @param[out] aBuffer  A pointer to a buffer to fill with the random bytes.
95      * @param[in]  aSize    Size of buffer (number of bytes to fill).
96      *
97      * @retval kErrorNone    Successfully filled buffer with random values.
98      *
99      */
CryptoFillBuffer(uint8_t * aBuffer,uint16_t aSize)100     static Error CryptoFillBuffer(uint8_t *aBuffer, uint16_t aSize) { return sCtrDrbg.FillBuffer(aBuffer, aSize); }
101 
102     /**
103      * This static method returns the initialized mbedtls_ctr_drbg_context.
104      *
105      * @returns  A pointer to the initialized mbedtls_ctr_drbg_context.
106      *
107      */
GetMbedTlsCtrDrbgContext(void)108     static mbedtls_ctr_drbg_context *GetMbedTlsCtrDrbgContext(void) { return sCtrDrbg.GetContext(); }
109 #endif
110 
111 private:
112     class NonCryptoPrng // A non-crypto Pseudo Random Number Generator (PRNG)
113     {
114     public:
115         void     Init(uint32_t aSeed);
116         uint32_t GetNext(void);
117 
118     private:
119         uint32_t mState;
120     };
121 
122 #if !OPENTHREAD_RADIO
123     class Entropy
124     {
125     public:
126         void Init(void);
127         void Deinit(void);
128 
GetContext(void)129         mbedtls_entropy_context *GetContext(void) { return &mEntropyContext; }
130 
131     private:
132 #ifndef OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
133         static int HandleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen);
134 #endif // OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
135 
136         mbedtls_entropy_context mEntropyContext;
137     };
138 
139     class CryptoCtrDrbg
140     {
141     public:
142         void  Init(void);
143         void  Deinit(void);
144         Error FillBuffer(uint8_t *aBuffer, uint16_t aSize);
145 
GetContext(void)146         mbedtls_ctr_drbg_context *GetContext(void) { return &mCtrDrbg; }
147 
148     private:
149         mbedtls_ctr_drbg_context mCtrDrbg;
150     };
151 #endif
152 
153     static uint16_t      sInitCount;
154     static NonCryptoPrng sPrng;
155 #if !OPENTHREAD_RADIO
156     static Entropy       sEntropy;
157     static CryptoCtrDrbg sCtrDrbg;
158 #endif
159 };
160 
161 } // namespace ot
162 
163 #endif // RANDOM_MANAGER_HPP_
164