diff --git a/Android.mk b/Android.mk index c8fa70964..dbcfc2bd9 100644 --- a/Android.mk +++ b/Android.mk @@ -133,14 +133,11 @@ LOCAL_SRC_FILES := \ src/core/coap/coap_message.cpp \ src/core/coap/coap_secure.cpp \ src/core/common/crc16.cpp \ - src/core/common/entropy.cpp \ src/core/common/instance.cpp \ src/core/common/logging.cpp \ src/core/common/message.cpp \ src/core/common/notifier.cpp \ - src/core/common/random_crypto.cpp \ src/core/common/random_manager.cpp \ - src/core/common/random_noncrypto.cpp \ src/core/common/settings.cpp \ src/core/common/string.cpp \ src/core/common/tasklet.cpp \ diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 78fac37d2..598c1a3aa 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -137,14 +137,11 @@ SOURCES_COMMON = \ coap/coap_message.cpp \ coap/coap_secure.cpp \ common/crc16.cpp \ - common/entropy.cpp \ common/instance.cpp \ common/logging.cpp \ common/message.cpp \ common/notifier.cpp \ - common/random_crypto.cpp \ common/random_manager.cpp \ - common/random_noncrypto.cpp \ common/settings.cpp \ common/string.cpp \ common/tasklet.cpp \ @@ -241,11 +238,9 @@ libopenthread_radio_a_SOURCES = \ api/logging_api.cpp \ api/random_noncrypto_api.cpp \ api/tasklet_api.cpp \ - common/entropy.cpp \ common/instance.cpp \ common/logging.cpp \ common/random_manager.cpp \ - common/random_noncrypto.cpp \ common/string.cpp \ common/tasklet.cpp \ common/timer.cpp \ @@ -302,7 +297,6 @@ HEADERS_COMMON = \ common/crc16.hpp \ common/debug.hpp \ common/encoding.hpp \ - common/entropy.hpp \ common/extension.hpp \ common/instance.hpp \ common/locator.hpp \ diff --git a/src/core/api/entropy_api.cpp b/src/core/api/entropy_api.cpp index 2139c61c0..3c22efb4d 100644 --- a/src/core/api/entropy_api.cpp +++ b/src/core/api/entropy_api.cpp @@ -33,13 +33,11 @@ #include "openthread/entropy.h" -#include - -#include "common/entropy.hpp" +#include "common/random_manager.hpp" using namespace ot; mbedtls_entropy_context *otEntropyMbedTlsContextGet(void) { - return Entropy::MbedTlsContextGet(); + return RandomManager::GetMbedTlsEntropyContext(); } diff --git a/src/core/common/entropy.cpp b/src/core/common/entropy.cpp deleted file mode 100644 index 14a24b6d3..000000000 --- a/src/core/common/entropy.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2019, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file provides an implementation of entropy source. - */ - -#include "entropy.hpp" - -#include -#include - -#include "code_utils.hpp" -#include "debug.hpp" - -#ifndef OPENTHREAD_RADIO - -#include -#include - -#endif // OPENTHREAD_RADIO - -namespace ot { -namespace Entropy { - -static uint32_t sInitCnt = 0; - -#ifndef OPENTHREAD_RADIO -static mbedtls_entropy_context sEntropy; - -static int HandleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen) -{ - OT_UNUSED_VARIABLE(aData); - - otError error; - int rval = 0; - - error = otPlatEntropyGet(reinterpret_cast(aOutput), static_cast(aInLen)); - SuccessOrExit(error); - - if (aOutLen != NULL) - { - *aOutLen = aInLen; - } - -exit: - - if (error != OT_ERROR_NONE) - { - rval = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - - return rval; -} - -#endif // OPENTHREAD_RADIO - -void Init(void) -{ - assert(sInitCnt < 0xffffffff); - -#ifndef OPENTHREAD_RADIO - if (sInitCnt == 0) - { - mbedtls_entropy_init(&sEntropy); - mbedtls_entropy_add_source(&sEntropy, &HandleMbedtlsEntropyPoll, NULL, MBEDTLS_ENTROPY_MIN_HARDWARE, - MBEDTLS_ENTROPY_SOURCE_STRONG); - } -#endif // OPENTHREAD_RADIO - - sInitCnt++; -} - -void Deinit(void) -{ - assert(sInitCnt > 0); - - sInitCnt--; - -#ifndef OPENTHREAD_RADIO - if (sInitCnt == 0) - { - mbedtls_entropy_free(&sEntropy); - } -#endif // OPENTHREAD_RADIO -} - -#ifndef OPENTHREAD_RADIO - -mbedtls_entropy_context *MbedTlsContextGet(void) -{ - assert(sInitCnt > 0); - return &sEntropy; -} - -#endif // OPENTHREAD_RADIO - -otError GetUint32(uint32_t &aVal) -{ - assert(sInitCnt > 0); - return otPlatEntropyGet(reinterpret_cast(&aVal), sizeof(aVal)); -} - -} // namespace Entropy -} // namespace ot diff --git a/src/core/common/entropy.hpp b/src/core/common/entropy.hpp deleted file mode 100644 index a250b7926..000000000 --- a/src/core/common/entropy.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2019, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file includes definitions for OpenThread entropy generation. - */ - -#ifndef ENTROPY_HPP_ -#define ENTROPY_HPP_ - -#include "openthread-core-config.h" - -#include - -#include - -#ifndef OPENTHREAD_RADIO - -#include - -#endif // OPENTHREAD_RADIO - -namespace ot { -namespace Entropy { - -/** - * This function initializes entropy source. - * - */ -void Init(void); - -/** - * This function deinitializes entropy source. - * - */ -void Deinit(void); - -#ifndef OPENTHREAD_RADIO - -/** - * This function returns initialized mbedtls_entropy_context. - * - * @returns A pointer to initialized mbedtls_entropy_context. - */ -mbedtls_entropy_context *MbedTlsContextGet(void); - -#endif // OPENTHREAD_RADIO - -/** - * This function generates and returns a 32 bit entropy. - * - * @param aVal[out] A generated 32 bit entropy value. - * - * @retval OT_ERROR_NONE Successfully generated 32 bit entropy. - * - */ -otError GetUint32(uint32_t &aVal); - -} // namespace Entropy -} // namespace ot - -#endif // ENTROPY_HPP_ diff --git a/src/core/common/random.hpp b/src/core/common/random.hpp index cb67e1476..71c742def 100644 --- a/src/core/common/random.hpp +++ b/src/core/common/random.hpp @@ -39,14 +39,9 @@ #include #include "common/debug.hpp" +#include "common/random_manager.hpp" #include "utils/wrap_stdint.h" -#ifndef OPENTHREAD_RADIO - -#include - -#endif // OPENTHREAD_RADIO - namespace ot { namespace Random { namespace NonCrypto { @@ -57,7 +52,10 @@ namespace NonCrypto { * @returns A random `uint32_t` value. * */ -uint32_t GetUint32(void); +inline uint32_t GetUint32(void) +{ + return ot::RandomManager::NonCryptoGetUint32(); +} /** * This function generates and returns a random byte. @@ -159,32 +157,12 @@ inline uint32_t AddJitter(uint32_t aValue, uint16_t aJitter) return aValue + GetUint32InRange(0, 2 * aJitter + 1) - aJitter; } -/** - * This function seeds a software random generator. - * - * @param[in] aSeed Seed value. - * - */ -void Seed(uint32_t aSeed); - } // namespace NonCrypto #ifndef OPENTHREAD_RADIO namespace Crypto { -/** - * This function initializes cryptographic random number generator. - * - */ -void Init(void); - -/** - * This function deinitializes cryptographic random number generator. - * - */ -void Deinit(void); - /** * This function fills a given buffer with cryptographically secure random bytes. * @@ -194,7 +172,10 @@ void Deinit(void); * @retval OT_ERROR_NONE Successfully filled buffer with random values. * */ -otError FillBuffer(uint8_t *aBuffer, uint16_t aSize); +inline otError FillBuffer(uint8_t *aBuffer, uint16_t aSize) +{ + return RandomManager::CryptoFillBuffer(aBuffer, aSize); +} /** * This function returns initialized mbedtls_ctr_drbg_context. @@ -202,7 +183,10 @@ otError FillBuffer(uint8_t *aBuffer, uint16_t aSize); * @returns A pointer to initialized mbedtls_ctr_drbg_context. * */ -mbedtls_ctr_drbg_context *MbedTlsContextGet(void); +inline mbedtls_ctr_drbg_context *MbedTlsContextGet(void) +{ + return RandomManager::GetMbedTlsCtrDrbgContext(); +} } // namespace Crypto diff --git a/src/core/common/random_crypto.cpp b/src/core/common/random_crypto.cpp deleted file mode 100644 index ccfa0f8b5..000000000 --- a/src/core/common/random_crypto.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2019, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file provides an implementation of cryptographic random number generator. - */ - -#include "random.hpp" - -#include - -#include "entropy.hpp" -#include "crypto/mbedtls.hpp" - -#include - -#include "debug.hpp" - -namespace ot { -namespace Random { -namespace Crypto { - -static uint32_t sInitCnt = 0; -static mbedtls_ctr_drbg_context sCtrDrbg; - -void Init(void) -{ - assert(sInitCnt < 0xffffffff); - - if (sInitCnt == 0) - { - mbedtls_ctr_drbg_init(&sCtrDrbg); - mbedtls_ctr_drbg_seed(&sCtrDrbg, mbedtls_entropy_func, Entropy::MbedTlsContextGet(), NULL, 0); - } - - sInitCnt++; -} - -void Deinit(void) -{ - assert(sInitCnt > 0); - - sInitCnt--; - - if (sInitCnt == 0) - { - mbedtls_ctr_drbg_free(&sCtrDrbg); - } -} - -mbedtls_ctr_drbg_context *MbedTlsContextGet(void) -{ - assert(sInitCnt > 0); - return &sCtrDrbg; -} - -otError FillBuffer(uint8_t *aBuffer, uint16_t aSize) -{ - int rval = 0; - - assert(sInitCnt > 0); - - rval = mbedtls_ctr_drbg_random(&sCtrDrbg, static_cast(aBuffer), static_cast(aSize)); - - return ot::Crypto::MbedTls::MapError(rval); -} - -} // namespace Crypto -} // namespace Random -} // namespace ot diff --git a/src/core/common/random_manager.cpp b/src/core/common/random_manager.cpp index 7c8bf0ed4..d5962cddd 100644 --- a/src/core/common/random_manager.cpp +++ b/src/core/common/random_manager.cpp @@ -33,37 +33,169 @@ #include "random_manager.hpp" -#include +#include -#include "debug.hpp" -#include "entropy.hpp" -#include "random.hpp" +#ifndef OPENTHREAD_RADIO +#include +#endif + +#include "common/code_utils.hpp" +#include "common/debug.hpp" +#include "common/random.hpp" +#include "crypto/mbedtls.hpp" namespace ot { +uint16_t RandomManager::sInitCount = 0; +RandomManager::NonCryptoPrng RandomManager::sPrng; + +#ifndef OPENTHREAD_RADIO +RandomManager::Entropy RandomManager::sEntropy; +RandomManager::CryptoCtrDrbg RandomManager::sCtrDrbg; +#endif + RandomManager::RandomManager(void) { uint32_t seed; otError error; - Entropy::Init(); + assert(sInitCount < 0xffff); - error = Entropy::GetUint32(seed); - assert(error == OT_ERROR_NONE); - - Random::NonCrypto::Seed(seed); + VerifyOrExit(sInitCount == 0); #ifndef OPENTHREAD_RADIO - Random::Crypto::Init(); + sEntropy.Init(); #endif + + error = otPlatEntropyGet(reinterpret_cast(&seed), sizeof(seed)); + assert(error == OT_ERROR_NONE); + + sPrng.Init(seed); + +#ifndef OPENTHREAD_RADIO + sCtrDrbg.Init(); +#endif + +exit: + sInitCount++; } RandomManager::~RandomManager(void) { + assert(sInitCount > 0); + + sInitCount--; + VerifyOrExit(sInitCount == 0); + #ifndef OPENTHREAD_RADIO - Random::Crypto::Deinit(); + sCtrDrbg.Deinit(); + sEntropy.Deinit(); #endif - Entropy::Deinit(); + +exit: + return; } +uint32_t RandomManager::NonCryptoGetUint32(void) +{ + assert(sInitCount > 0); + + return sPrng.GetNext(); +} + +//------------------------------------------------------------------- +// NonCryptoPrng + +void RandomManager::NonCryptoPrng::Init(uint32_t aSeed) +{ + // The PRNG has a cycle of length 1 for the below two initial + // seeds. For all other seed values the cycle is ~2^31 long. + + if ((aSeed == 0) || (aSeed == 0x7fffffff)) + { + aSeed = 0x1; + } + + mState = aSeed; +} + +uint32_t RandomManager::NonCryptoPrng::GetNext(void) +{ + uint32_t mlcg, p, q; + uint64_t tmpstate; + + tmpstate = (uint64_t)33614 * (uint64_t)mState; + q = tmpstate & 0xffffffff; + q = q >> 1; + p = tmpstate >> 32; + mlcg = p + q; + + if (mlcg & 0x80000000) + { + mlcg &= 0x7fffffff; + mlcg++; + } + + mState = mlcg; + + return mlcg; +} + +#ifndef OPENTHREAD_RADIO + +//------------------------------------------------------------------- +// Entropy + +void RandomManager::Entropy::Init(void) +{ + mbedtls_entropy_init(&mEntropyContext); + mbedtls_entropy_add_source(&mEntropyContext, &RandomManager::Entropy::HandleMbedtlsEntropyPoll, NULL, + MBEDTLS_ENTROPY_MIN_HARDWARE, MBEDTLS_ENTROPY_SOURCE_STRONG); +} + +void RandomManager::Entropy::Deinit(void) +{ + mbedtls_entropy_free(&mEntropyContext); +} + +int RandomManager::Entropy::HandleMbedtlsEntropyPoll(void * aData, + unsigned char *aOutput, + size_t aInLen, + size_t * aOutLen) +{ + int rval = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + + SuccessOrExit(otPlatEntropyGet(reinterpret_cast(aOutput), static_cast(aInLen))); + rval = 0; + + VerifyOrExit(aOutLen != NULL); + *aOutLen = aInLen; + +exit: + OT_UNUSED_VARIABLE(aData); + return rval; +} + +//------------------------------------------------------------------- +// CryptoCtrDrbg + +void RandomManager::CryptoCtrDrbg::Init(void) +{ + mbedtls_ctr_drbg_init(&mCtrDrbg); + mbedtls_ctr_drbg_seed(&mCtrDrbg, mbedtls_entropy_func, RandomManager::GetMbedTlsEntropyContext(), NULL, 0); +} + +void RandomManager::CryptoCtrDrbg::Deinit(void) +{ + mbedtls_ctr_drbg_free(&mCtrDrbg); +} + +otError RandomManager::CryptoCtrDrbg::FillBuffer(uint8_t *aBuffer, uint16_t aSize) +{ + return ot::Crypto::MbedTls::MapError( + mbedtls_ctr_drbg_random(&mCtrDrbg, static_cast(aBuffer), static_cast(aSize))); +} + +#endif // #ifndef OPENTHREAD_RADIO + } // namespace ot diff --git a/src/core/common/random_manager.hpp b/src/core/common/random_manager.hpp index c254f3049..c2e78a308 100644 --- a/src/core/common/random_manager.hpp +++ b/src/core/common/random_manager.hpp @@ -34,6 +34,17 @@ #ifndef RANDOM_MANAGER_HPP_ #define RANDOM_MANAGER_HPP_ +#include "openthread-core-config.h" + +#include + +#ifndef OPENTHREAD_RADIO +#include +#include +#endif + +#include "utils/wrap_stdint.h" + namespace ot { /** @@ -54,6 +65,89 @@ public: * */ ~RandomManager(void); + + /** + * This static method generates and returns a random value using a non-crypto Pseudo Random Number Generator. + * + * @returns A random `uint32_t` value. + * + */ + static uint32_t NonCryptoGetUint32(void); + +#ifndef OPENTHREAD_RADIO + /** + * This static method returns the initialized mbedtls_entropy_context. + * + * @returns A pointer to initialized mbedtls_entropy_context. + */ + static mbedtls_entropy_context *GetMbedTlsEntropyContext(void) { return sEntropy.GetContext(); } + + /** + * This static method fills a given buffer with cryptographically secure random bytes. + * + * @param[out] aBuffer A pointer to a buffer to fill with the random bytes. + * @param[in] aSize Size of buffer (number of bytes to fill). + * + * @retval OT_ERROR_NONE Successfully filled buffer with random values. + * + */ + static otError CryptoFillBuffer(uint8_t *aBuffer, uint16_t aSize) { return sCtrDrbg.FillBuffer(aBuffer, aSize); } + + /** + * This static method returns the initialized mbedtls_ctr_drbg_context. + * + * @returns A pointer to the initialized mbedtls_ctr_drbg_context. + * + */ + static mbedtls_ctr_drbg_context *GetMbedTlsCtrDrbgContext(void) { return sCtrDrbg.GetContext(); } +#endif + +private: + class NonCryptoPrng // A non-crypto Pseudo Random Number Generator (PRNG) + { + public: + void Init(uint32_t aSeed); + uint32_t GetNext(void); + + private: + uint32_t mState; + }; + +#ifndef OPENTHREAD_RADIO + class Entropy + { + public: + void Init(void); + void Deinit(void); + + mbedtls_entropy_context *GetContext(void) { return &mEntropyContext; } + + private: + static int HandleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen); + + mbedtls_entropy_context mEntropyContext; + }; + + class CryptoCtrDrbg + { + public: + void Init(void); + void Deinit(void); + otError FillBuffer(uint8_t *aBuffer, uint16_t aSize); + + mbedtls_ctr_drbg_context *GetContext(void) { return &mCtrDrbg; } + + private: + mbedtls_ctr_drbg_context mCtrDrbg; + }; +#endif + + static uint16_t sInitCount; + static NonCryptoPrng sPrng; +#ifndef OPENTHREAD_RADIO + static Entropy sEntropy; + static CryptoCtrDrbg sCtrDrbg; +#endif }; } // namespace ot diff --git a/src/core/common/random_noncrypto.cpp b/src/core/common/random_noncrypto.cpp deleted file mode 100644 index e8a284b73..000000000 --- a/src/core/common/random_noncrypto.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2019, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file provides an implementation of software random number generator. - */ - -#include "random.hpp" - -#include "debug.hpp" -#include "entropy.hpp" - -namespace ot { -namespace Random { -namespace NonCrypto { - -static uint32_t sState; -static bool sSeeded; - -uint32_t GetUint32(void) -{ - uint32_t mlcg, p, q; - uint64_t tmpstate; - - assert(sSeeded); - - tmpstate = (uint64_t)33614 * (uint64_t)sState; - q = tmpstate & 0xffffffff; - q = q >> 1; - p = tmpstate >> 32; - mlcg = p + q; - - if (mlcg & 0x80000000) - { - mlcg &= 0x7fffffff; - mlcg++; - } - - sState = mlcg; - - return mlcg; -} - -void Seed(uint32_t aSeed) -{ - sSeeded = true; - sState = aSeed; -} - -} // namespace NonCrypto -} // namespace Random -} // namespace ot