Implement true random number generator on posix platform. (#1614)

This commit is contained in:
Jonathan Hui
2017-04-19 11:00:45 -07:00
committed by GitHub
parent 0c5850e7ba
commit fb30b178af
+56 -6
View File
@@ -30,10 +30,11 @@
* @file
* This file implements a pseudo-random number generator.
*
* @warning
* This implementation is not a true random number generator and does @em satisfy the Thread requirements.
*/
#include <assert.h>
#include <stdio.h>
#include "platform-posix.h"
#include "openthread/types.h"
@@ -41,12 +42,24 @@
#include <utils/code_utils.h>
static uint32_t s_state = 1;
static uint32_t sState = 1;
void platformRandomInit(void)
{
#if __SANITIZE_ADDRESS__ == 0
ThreadError error;
uint16_t length;
error = otPlatRandomSecureGet(sizeof(sState), (uint8_t *)&sState, &length);
assert(error == kThreadError_None);
#else // __SANITIZE_ADDRESS__
// Multiplying NODE_ID assures that no two nodes gets the same seed within an hour.
s_state = (uint32_t)time(NULL) + (3600 * NODE_ID);
sState = (uint32_t)time(NULL) + (3600 * NODE_ID);
#endif // __SANITIZE_ADDRESS__
}
uint32_t otPlatRandomGet(void)
@@ -54,7 +67,7 @@ uint32_t otPlatRandomGet(void)
uint32_t mlcg, p, q;
uint64_t tmpstate;
tmpstate = (uint64_t)33614 * (uint64_t)s_state;
tmpstate = (uint64_t)33614 * (uint64_t)sState;
q = tmpstate & 0xffffffff;
q = q >> 1;
p = tmpstate >> 32;
@@ -66,7 +79,7 @@ uint32_t otPlatRandomGet(void)
mlcg++;
}
s_state = mlcg;
sState = mlcg;
return mlcg;
}
@@ -75,6 +88,40 @@ ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint1
{
ThreadError error = kThreadError_None;
#if __SANITIZE_ADDRESS__ == 0
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;
exit:
if (file != NULL)
{
fclose(file);
}
#else // __SANITIZE_ADDRESS__
/*
* THE IMPLEMENTATION BELOW IS NOT COMPLIANT WITH THE THREAD SPECIFICATION.
*
* Address Sanitizer triggers test failures when reading random
* values from /dev/urandom. The pseudo-random number generator
* implementation below is only used to enable continuous
* integration checks with Address Sanitizer enabled.
*/
otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs);
for (uint16_t length = 0; length < aInputLength; length++)
@@ -85,5 +132,8 @@ ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint1
*aOutputLength = aInputLength;
exit:
#endif // __SANITIZE_ADDRESS__
return error;
}