From 115b52e6c49d3da4e05cf74c4b5f9aa59183315e Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 25 Apr 2017 09:22:53 -0700 Subject: [PATCH] Require platform TRNG to provide requested output length or error. (#1650) --- examples/drivers/windows/otLwf/thread.c | 6 ++---- examples/platforms/cc2538/random.c | 17 ++++++---------- examples/platforms/cc2650/random.c | 20 ++++++++++--------- examples/platforms/da15000/random.c | 6 ++---- examples/platforms/efr32/random.c | 8 +++----- examples/platforms/nrf52840/random.c | 10 ++++------ examples/platforms/posix/random.c | 17 +++++----------- include/openthread/platform/random.h | 26 +++++++++++++------------ tests/unit/test_platform.cpp | 8 +++----- third_party/mbedtls/hardware_entropy.c | 7 ++++++- 10 files changed, 56 insertions(+), 69 deletions(-) diff --git a/examples/drivers/windows/otLwf/thread.c b/examples/drivers/windows/otLwf/thread.c index a9e48b984..567bd2699 100644 --- a/examples/drivers/windows/otLwf/thread.c +++ b/examples/drivers/windows/otLwf/thread.c @@ -430,14 +430,14 @@ uint32_t otPlatRandomGet() return (uint32_t)RtlRandomEx(&Counter.LowPart); } -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { // Just use the system-preferred random number generator algorithm NTSTATUS status = BCryptGenRandom( NULL, aOutput, - (ULONG)aInputLength, + (ULONG)aOutputLength, BCRYPT_USE_SYSTEM_PREFERRED_RNG ); NT_ASSERT(NT_SUCCESS(status)); @@ -447,8 +447,6 @@ ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint1 return kThreadError_Failed; } - *aOutputLength = aInputLength; - return kThreadError_None; } diff --git a/examples/platforms/cc2538/random.c b/examples/platforms/cc2538/random.c index d7d8ecab0..b88ea32ff 100644 --- a/examples/platforms/cc2538/random.c +++ b/examples/platforms/cc2538/random.c @@ -39,7 +39,7 @@ #include #include "platform-cc2538.h" -static void generateRandom(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +static void generateRandom(uint8_t *aOutput, uint16_t aOutputLength) { HWREG(SOC_ADC_ADCCON1) &= ~(SOC_ADC_ADCCON1_RCTRL1 | SOC_ADC_ADCCON1_RCTRL0); HWREG(SYS_CTRL_RCGCRFC) = SYS_CTRL_RCGCRFC_RFC0; @@ -51,7 +51,7 @@ static void generateRandom(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aO while (!HWREG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID); - for (uint16_t index = 0; index < aInputLength; index++) + for (uint16_t index = 0; index < aOutputLength; index++) { aOutput[index] = 0; @@ -63,11 +63,6 @@ static void generateRandom(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aO } HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RFOFF; - - if (aOutputLength) - { - *aOutputLength = aInputLength; - } } void cc2538RandomInit(void) @@ -76,7 +71,7 @@ void cc2538RandomInit(void) while (seed == 0x0000 || seed == 0x8003) { - generateRandom(sizeof(seed), (uint8_t *)&seed, 0); + generateRandom((uint8_t *)&seed, sizeof(seed)); } HWREG(SOC_ADC_RNDL) = (seed >> 8) & 0xff; @@ -96,12 +91,12 @@ uint32_t otPlatRandomGet(void) return random; } -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { ThreadError error = kThreadError_None; uint8_t channel = 0; - otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs); + otEXPECT_ACTION(aOutput, error = kThreadError_InvalidArgs); if (otPlatRadioIsEnabled(sInstance)) { @@ -110,7 +105,7 @@ ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint1 otPlatRadioDisable(sInstance); } - generateRandom(aInputLength, aOutput, aOutputLength); + generateRandom(aOutput, aOutputLength); if (channel) { diff --git a/examples/platforms/cc2650/random.c b/examples/platforms/cc2650/random.c index b035cb0d7..6ab612456 100644 --- a/examples/platforms/cc2650/random.c +++ b/examples/platforms/cc2650/random.c @@ -85,7 +85,7 @@ uint32_t otPlatRandomGet(void) * @return indication of error * @retval 0 no error occured */ -static int TRNGPoll(unsigned char *aOutput, size_t aLen, size_t *oLen) +static int TRNGPoll(unsigned char *aOutput, size_t aLen) { size_t length = 0; union @@ -113,7 +113,6 @@ static int TRNGPoll(unsigned char *aOutput, size_t aLen, size_t *oLen) aOutput[length] = buffer.u8[length % 8]; length++; - *oLen = length; } return 0; @@ -123,18 +122,16 @@ static int TRNGPoll(unsigned char *aOutput, size_t aLen, size_t *oLen) /** * Function documented in platform/random.h */ -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { ThreadError error = kThreadError_None; - size_t temp_size; - size_t length = aInputLength; + size_t length = aOutputLength; - otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs); + otEXPECT_ACTION(aOutput, error = kThreadError_InvalidArgs); - otEXPECT_ACTION(TRNGPoll((unsigned char *)aOutput, length, &temp_size) != 0, error = kThreadError_Failed); + otEXPECT_ACTION(TRNGPoll((unsigned char *)aOutput, length) != 0, error = kThreadError_Failed); exit: - *aOutputLength = temp_size; return error; } @@ -145,6 +142,11 @@ exit: */ int mbedtls_hardware_poll(void *data, unsigned char *aOutput, size_t aLen, size_t *oLen) { + ThreadError error; + (void)data; - return TRNGPoll(aOutput, aLen, oLen); + error = TRNGPoll(aOutput, aLen); + *oLen = aLen; + + return error; } diff --git a/examples/platforms/da15000/random.c b/examples/platforms/da15000/random.c index 728025f72..63c65929a 100644 --- a/examples/platforms/da15000/random.c +++ b/examples/platforms/da15000/random.c @@ -93,15 +93,13 @@ uint32_t otPlatRandomGet(void) return mlcg; } -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { - for (uint16_t length = 0; length < aInputLength; length++) + for (uint16_t length = 0; length < aOutputLength; length++) { aOutput[length] = (uint8_t)otPlatRandomGet(); } - *aOutputLength = aInputLength; - return kThreadError_None; } diff --git a/examples/platforms/efr32/random.c b/examples/platforms/efr32/random.c index 205999057..5162e33f0 100644 --- a/examples/platforms/efr32/random.c +++ b/examples/platforms/efr32/random.c @@ -90,19 +90,17 @@ uint32_t otPlatRandomGet(void) return random; } -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t *aOutputLength) { ThreadError error = kThreadError_None; - otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs); + otEXPECT_ACTION(aOutput, error = kThreadError_InvalidArgs); - for (uint16_t length = 0; length < aInputLength; length++) + for (uint16_t length = 0; length < aOutputLength; length++) { aOutput[length] = (uint8_t)otPlatRandomGet(); } - *aOutputLength = aInputLength; - exit: return error; } diff --git a/examples/platforms/nrf52840/random.c b/examples/platforms/nrf52840/random.c index 4e1a805ba..08f6e85bc 100644 --- a/examples/platforms/nrf52840/random.c +++ b/examples/platforms/nrf52840/random.c @@ -150,18 +150,18 @@ uint32_t otPlatRandomGet(void) return (uint32_t)rand(); } -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { ThreadError error = kThreadError_None; - otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs); + otEXPECT_ACTION(aOutput, error = kThreadError_InvalidArgs); otEXPECT_ACTION(!bufferIsEmpty(), error = kThreadError_Failed); uint16_t copyLength = (uint16_t)bufferCount(); - if (copyLength > aInputLength) + if (copyLength > aOutputLength) { - copyLength = aInputLength; + copyLength = aOutputLength; } for (uint32_t i = 0; i < copyLength; i++) @@ -169,8 +169,6 @@ ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint1 aOutput[i] = bufferGet(); } - *aOutputLength = copyLength; - generatorStart(); exit: diff --git a/examples/platforms/posix/random.c b/examples/platforms/posix/random.c index 26ddc0d92..13b27d64a 100644 --- a/examples/platforms/posix/random.c +++ b/examples/platforms/posix/random.c @@ -49,9 +49,8 @@ void platformRandomInit(void) #if __SANITIZE_ADDRESS__ == 0 ThreadError error; - uint16_t length; - error = otPlatRandomSecureGet(sizeof(sState), (uint8_t *)&sState, &length); + error = otPlatRandomGetTrue((uint8_t *)&sState, sizeof(sState)); assert(error == kThreadError_None); #else // __SANITIZE_ADDRESS__ @@ -84,7 +83,7 @@ uint32_t otPlatRandomGet(void) return mlcg; } -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { ThreadError error = kThreadError_None; @@ -93,17 +92,13 @@ ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint1 FILE *file = NULL; size_t readLength; - *aOutputLength = 0; - otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs); file = fopen("/dev/urandom", "rb"); otEXPECT_ACTION(file != NULL, error = kThreadError_Failed); - readLength = fread(aOutput, 1, aInputLength, file); - otEXPECT_ACTION(readLength == aInputLength, error = kThreadError_Failed); - - *aOutputLength = aInputLength; + readLength = fread(aOutput, 1, aOutputLength, file); + otEXPECT_ACTION(readLength == aOutputLength, error = kThreadError_Failed); exit: @@ -124,13 +119,11 @@ exit: */ otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs); - for (uint16_t length = 0; length < aInputLength; length++) + for (uint16_t length = 0; length < aOutputLength; length++) { aOutput[length] = (uint8_t)otPlatRandomGet(); } - *aOutputLength = aInputLength; - exit: #endif // __SANITIZE_ADDRESS__ diff --git a/include/openthread/platform/random.h b/include/openthread/platform/random.h index 62d261fd4..cc8cba4a5 100644 --- a/include/openthread/platform/random.h +++ b/include/openthread/platform/random.h @@ -29,7 +29,7 @@ /** * @file * @brief - * This file includes the platform abstraction for true random number generation. + * This file includes the platform abstraction for random number generation. */ #ifndef RANDOM_H_ @@ -48,7 +48,7 @@ extern "C" { * @ingroup platform * * @brief - * This module includes the platform abstraction to support critical sections. + * This module includes the platform abstraction for random number generation. * * @{ * @@ -57,25 +57,27 @@ extern "C" { /** * Get a 32-bit random value. * + * This function may be implemented using a psuedo-random number generator. + * * @returns A 32-bit random value. * */ uint32_t otPlatRandomGet(void); /** - * Get true random stream. + * Get true random value sequence. * - * @param[in] aInputLength The expected size of random values. - * @param[out] aOutput A pointer to the buffer for the generated random stream. The pointer should never be NULL. - * @param[out] aOutputLength A pointer to the generated size of random stream. - * It is supposed to be the same as aInputLength, but maybe less than aInputLength. - * The pointer should never be NULL. + * This function MUST be implemented using a true random number generator (TRNG). + * + * @param[out] aOutput A pointer to where the true random values are placed. Must not be NULL. + * @param[in] aOutputLength Size of @p aBuffer. + * + * @retval kThreadError_None Successfully filled @p aBuffer with true random values. + * @retval kThreadError_Fail Failed to fill @p aBuffer with true random values. + * @retval kThreadError_InvalidArgs @p aBuffer was set to NULL. * - * @retval kThreadError_None Generate random successfully. - * @retval kThreadError_Fail Generate random fail. - * @retval kThreadError_InvalidArgs Invalid args. */ -ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength); +ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength); /** * @} diff --git a/tests/unit/test_platform.cpp b/tests/unit/test_platform.cpp index 89761878f..22b95dc08 100644 --- a/tests/unit/test_platform.cpp +++ b/tests/unit/test_platform.cpp @@ -338,19 +338,17 @@ extern "C" { #endif } - ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength) + ThreadError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength) { ThreadError error = kThreadError_None; - VerifyOrExit(aOutput && aOutputLength, error = kThreadError_InvalidArgs); + VerifyOrExit(aOutput, error = kThreadError_InvalidArgs); - for (uint16_t length = 0; length < aInputLength; length++) + for (uint16_t length = 0; length < aOutputLength; length++) { aOutput[length] = (uint8_t)otPlatRandomGet(); } - *aOutputLength = aInputLength; - exit: return error; } diff --git a/third_party/mbedtls/hardware_entropy.c b/third_party/mbedtls/hardware_entropy.c index aac174421..102312241 100644 --- a/third_party/mbedtls/hardware_entropy.c +++ b/third_party/mbedtls/hardware_entropy.c @@ -33,12 +33,17 @@ int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t (void)data; - error = otPlatRandomSecureGet((uint16_t)len, (uint8_t *)output, (uint16_t *)olen); + error = otPlatRandomGetTrue((uint8_t *)output, (uint16_t)len); if (error != kThreadError_None) { return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; } + if (olen != NULL) + { + *olen = len; + } + return 0; }