#include <stdint.h>
#include <stdlib.h>
+#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
-#ifndef ARDUINO
-#include <time.h>
-#else
+#ifdef ARDUINO
// MEGA has 16 input pins whereas Due has only 12 input pins
#define ANALOG_IN (10)
#endif
+ /* Number of bytes in a UUID. */
#define UUID_SIZE (16)
-// The characters are 36 long, 37 for the null-term
-#define UUID_STRING_SIZE (37)
-typedef enum
-{
- RAND_UUID_OK = 0,
- RAND_UUID_INVALID_PARAM = -1,
- RAND_UUID_READ_ERROR = -2,
- RAND_UUID_CONVERT_ERROR = -3
-} OCRandomUuidResult;
-/**
- * Seed the random number generator. Seeding depends on platform.
- * Android and Linux uses current time. Arduino uses Analog reading on pin ANALOG_IN
- * @retval 0 for Success, otherwise some error value
+/*
+ * Size of a UUID string.
+ * IoTivity formats UUIDs as strings following RFC 4122, Section 3.
+ * For example, "f81d4fae-7dec-11d0-a765-00a0c91e6bf6".
+ * This requires 36 characters, plus one for the null terminator.
*/
-int8_t OCSeedRandom();
+#define UUID_STRING_SIZE (37)
/**
- * Generate a uniformly [0,2^32] distributed random number
- * @retval On Success, it returns the random value.
+ * Generate a uniformly distributed 32-bit random number.
+ * @retval On success, it returns the random value.
*/
uint32_t OCGetRandom();
/**
- * Generate a uniformly [0,2^8] distributed random number
- * @retval On Success, it returns the random value, otherwise -1 for error.
- */
-uint8_t OCGetRandomByte(void);
-
-/**
- * Generate a uniformly distributed 8-bit (byte) array random numbers
- * @param[out] location
- * memory location to start filling with random bytes
+ * Generate an array of uniformly distributed random bytes.
+ * @param[out] output
+ * Array to fill with random bytes
* @param[in] len
- * length of array to be filled with random bytes
+ * Length of array
+ * @retval true for success, otherwise false and an error is logged
*/
-void OCFillRandomMem(uint8_t * location, uint16_t len);
+bool OCGetRandomBytes(uint8_t * output, size_t len);
-/*
- * Generate a uniformly distributed number on the defined bounded range
+/**
+ * Generate a uniformly distributed number in a given range.
* @param[in] firstBound
- * the first bound of the range
+ * The output is greater than or equal to firstBound
* @param[in] secondBound
- * the second bound of the range
+ * The output is less than or equal to secondBound
*/
uint32_t OCGetRandomRange(uint32_t firstBound, uint32_t secondBound);
/**
* Generate a Uniformly Unique Identifier based on RFC4122 and
- * provide it as a 16 byte byte-array
+ * provide it as UUID_SIZE bytes.
*
* @param[out] uuid
- * the 16 byte array to fill with the UUID data
- * of a new UUID
+ * UUID_SIZE array to hold the new UUID
*
- * @retval RAND_UUID_OK for success, otherwise an error value
+ * @retval true for success, otherwise false and an error is logged
*/
-OCRandomUuidResult OCGenerateUuid(uint8_t uuid[UUID_SIZE]);
+bool OCGenerateUuid(uint8_t uuid[UUID_SIZE]);
/**
- * Generate a Uniformly Unique Identifier based on RFC4122 and
- * provide it as a C style string.
- *
- * @param[out] uuidString
- * a 37-byte length string to fill with the string
- * representation of a new UUID. Size is 32 chars
- * for the hex data, 4 for '-' characters, and 1
- * for the NULL terminator
- *
- * @retval RAND_UUID_OK for success, otherwise an error value
- */
-OCRandomUuidResult OCGenerateUuidString(char uuidString[UUID_STRING_SIZE]);
-
-/**
- * Convert a UUID generated by OCGenerateUuid to a C style string
- * based on RFC 4122
+ * Convert a UUID generated by OCGenerateUuid to a C string
+ * based on RFC 4122.
*
* @param[in] uuid
- * The 16 byte array filled with UUID data by OCGenerateUuid
+ * Array of length UUID_SIZE bytes with output of OCGenerateUuid
* @param[out] uuidString
- * a 37 byte length string to fill with the string
- * representation of the passed UUID.
- * @retval RAND_UUID_OK for success, otherwise an error value
+ * A UUID_STRING_SIZE length string to hold the string
+ * representation of the input UUID.
+ * @retval true for success, otherwise false and an error is logged
*/
-OCRandomUuidResult OCConvertUuidToString(const uint8_t uuid[UUID_SIZE],
+bool OCConvertUuidToString(const uint8_t uuid[UUID_SIZE],
char uuidString[UUID_STRING_SIZE]);
/**
* representation of the passed UUID.
* @param[out] uuid
* The 16 byte array filled with UUID data
- * @retval RAND_UUID_OK for success, otherwise an error value
+ * @retval true for success, otherwise false and an error is logged
*/
-OCRandomUuidResult OCConvertStringToUuid(const char uuidString[UUID_STRING_SIZE],
+bool OCConvertStringToUuid(const char uuidString[UUID_STRING_SIZE],
uint8_t uuid[UUID_SIZE]);
#ifdef __cplusplus
#endif
#include "iotivity_config.h"
+#include "logger.h"
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#elif defined(HAVE_STRINGS_H)
#include <strings.h>
#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
#if defined(__ANDROID__)
#include <ctype.h>
-#include <linux/time.h>
#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
+
#include "ocrandom.h"
#include <stdio.h>
+#include <stdbool.h>
+#include <assert.h>
-#ifdef HAVE_UUID_UUID_H
-#include <uuid/uuid.h>
-#endif
+#define OC_MIN(A,B) ((A)<(B)?(A):(B))
-#define NANO_SEC 1000000000
+/**
+* @def OCRANDOM_TAG
+* @brief Logging tag for module name
+*/
+#define OCRANDOM_TAG "OIC_OCRANDOM"
#ifdef ARDUINO
#include "Arduino.h"
-// ARM GCC compiler doesnt define srandom function.
-#if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
-#define HAVE_SRANDOM 1
+/*
+ * ARM GCC compiler doesnt define random/srandom functions, fallback to
+ * rand/srand.
+ */
+#if !defined(ARDUINO_ARCH_SAM)
+#define OC_arduino_srandom_function srandom
+#define OC_arduino_random_function random
+#elif
+#define OC_arduino_srandom_function srand
+#define OC_arduino_random_function rand
#endif
uint8_t GetRandomBitRaw()
// For other cases, try again.
}
}
-#endif
-int8_t OCSeedRandom()
+/*
+ * Currently, only the Arduino platform requires seeding. It's done
+ * automatically on the first call to OCGetRandomBytes.
+ */
+uint8_t g_isSeeded = 0;
+static void OCSeedRandom()
{
-#ifndef ARDUINO
- // Get current time to Seed.
- uint64_t currentTime = 0;
-#ifdef __ANDROID__
- struct timespec getTs;
- clock_gettime(CLOCK_MONOTONIC, &getTs);
- currentTime = (getTs.tv_sec * (uint64_t)NANO_SEC + getTs.tv_nsec)/1000;
-#elif _WIN32
- LARGE_INTEGER count;
- if (QueryPerformanceCounter(&count)) {
- currentTime = count.QuadPart;
- }
-#elif _POSIX_TIMERS > 0
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- currentTime = (ts.tv_sec * (uint64_t)NANO_SEC + ts.tv_nsec)/ 1000;
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- currentTime = tv.tv_sec * (uint64_t)1000000 + tv.tv_usec;
-#endif
-#if defined(__unix__) || defined(__APPLE__)
- int32_t fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0)
- {
- uint32_t randomSeed = 0;
- uint32_t totalRead = 0; //how many integers were read
- int32_t currentRead = 0;
- while (totalRead < sizeof(randomSeed))
- {
- currentRead = read(fd, (uint8_t*) &randomSeed + totalRead,
- sizeof(randomSeed) - totalRead);
- if (currentRead > 0)
- {
- totalRead += currentRead;
- }
- }
- close(fd);
- srand(randomSeed | currentTime);
- }
- else
-#endif
+ if (g_isSeeded)
{
- // Do time based seed when problem in accessing "/dev/urandom"
- srand(currentTime);
+ return;
}
-
- return 0;
-#elif defined ARDUINO
+
uint32_t result =0;
uint8_t i;
for (i=32; i--;)
{
result += result + GetRandomBit();
}
-#if HAVE_SRANDOM
- srandom(result);
-#else
- srand(result);
-#endif
- return 0;
-#endif
+ OC_arduino_srandom_function(result);
+ g_isSeeded = 1;
+ return;
}
-void OCFillRandomMem(uint8_t * location, uint16_t len)
+#endif /* ARDUINO */
+
+bool OCGetRandomBytes(uint8_t * output, size_t len)
{
- if (!location)
+ if ( (output == NULL) || (len == 0) )
{
- return;
+ return false;
}
- for (; len--;)
+
+#if defined(__unix__) || defined(__APPLE__)
+ FILE* urandom = fopen("/dev/urandom", "r");
+ if (urandom == NULL)
{
- *location++ = OCGetRandomByte();
+ OIC_LOG(FATAL, OCRANDOM_TAG, "Failed open /dev/urandom!");
+ assert(false);
+ return false;
}
-}
-
-uint32_t OCGetRandom()
-{
- uint32_t result = 0;
- OCFillRandomMem((uint8_t*) &result, 4);
- return result;
-}
-uint8_t OCGetRandomByte(void)
-{
-#ifdef HAVE_SRANDOM
- return random() & 0x00FF;
-#else
- return rand() & 0x00FF;
-#endif
-}
-
-uint32_t OCGetRandomRange(uint32_t firstBound, uint32_t secondBound)
-{
- uint32_t base;
- uint32_t diff;
- uint32_t result;
- if (firstBound > secondBound)
+ if (fread(output, sizeof(uint8_t), len, urandom) != len)
{
- base = secondBound;
- diff = firstBound - secondBound;
+ OIC_LOG(FATAL, OCRANDOM_TAG, "Failed while reading /dev/urandom!");
+ assert(false);
+ fclose(urandom);
+ return false;
}
- else if (firstBound < secondBound)
+ fclose(urandom);
+
+#elif defined(_WIN32)
+ /*
+ * size_t may be 64 bits, but ULONG is always 32.
+ * If len is larger than the maximum for ULONG, just fail.
+ * It's unlikely anything ever will want to ask for this much randomness.
+ */
+ if (len > 0xFFFFFFFFULL)
{
- base = firstBound;
- diff = secondBound - firstBound;
+ OIC_LOG(FATAL, OCRANDOM_TAG, "Requested number of bytes too large for ULONG");
+ assert(false);
+ return false;
}
- else
+
+ NTSTATUS status = BCryptGenRandom(NULL, output, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+ if (!BCRYPT_SUCCESS(status))
{
- return secondBound;
+ OIC_LOG_V(FATAL, OCRANDOM_TAG, "BCryptGenRandom failed (%X)!", status);
+ assert(false);
+ return false;
}
- result = ((float)OCGetRandom()/((float)(0xFFFFFFFF))*(float)diff) + (float) base;
- return result;
-}
-#if defined(__ANDROID__)
-uint8_t parseUuidChar(char c)
-{
- if (isdigit(c))
+#elif defined(ARDUINO)
+ if (!g_isSeeded)
{
- return c - '0';
+ OCSeedRandom();
}
- else
+
+ size_t i;
+ for (i = 0; i < len; i++)
{
- return c - 'a' + 10;
+ output[i] = OC_arduino_random_function() & 0x00ff;
}
-}
-uint8_t parseUuidPart(const char *c)
-{
- return (parseUuidChar(c[0])<<4) + parseUuidChar(c[1]);
-}
+
+#else
+ #error Unrecognized platform
#endif
-OCRandomUuidResult OCGenerateUuid(uint8_t uuid[UUID_SIZE])
+ return true;
+}
+
+uint32_t OCGetRandom()
{
- if (!uuid)
+ uint32_t result = 0;
+ if (!OCGetRandomBytes((uint8_t*)&result, sizeof(result)))
{
- return RAND_UUID_INVALID_PARAM;
+ OIC_LOG(FATAL, OCRANDOM_TAG, "OCGetRandom failed!");
+ assert(false);
}
-#if defined(__ANDROID__)
- char uuidString[UUID_STRING_SIZE];
- int8_t ret = OCGenerateUuidString(uuidString);
+ return result;
+}
- if (ret < 0)
+/* Return the number of leading zeroes in x.
+ * Binary search algorithm from Section 5-3 of:
+ * H.S. Warren Jr. Hacker's Delight. Addison-Wesley. 2003.
+ */
+static int nlz(uint32_t x)
+{
+ if (x == 0)
{
- return ret;
+ return 32;
}
- uuid[ 0] = parseUuidPart(&uuidString[0]);
- uuid[ 1] = parseUuidPart(&uuidString[2]);
- uuid[ 2] = parseUuidPart(&uuidString[4]);
- uuid[ 3] = parseUuidPart(&uuidString[6]);
-
- uuid[ 4] = parseUuidPart(&uuidString[9]);
- uuid[ 5] = parseUuidPart(&uuidString[11]);
-
- uuid[ 6] = parseUuidPart(&uuidString[14]);
- uuid[ 7] = parseUuidPart(&uuidString[16]);
-
- uuid[ 8] = parseUuidPart(&uuidString[19]);
- uuid[ 9] = parseUuidPart(&uuidString[21]);
+ int n = 0;
+ if (x <= 0x0000FFFF) { n = n + 16; x = x << 16;}
+ if (x <= 0x00FFFFFF) { n = n + 8; x = x << 8; }
+ if (x <= 0x0FFFFFFF) { n = n + 4; x = x << 4; }
+ if (x <= 0x3FFFFFFF) { n = n + 2; x = x << 2; }
+ if (x <= 0x7FFFFFFF) { n = n + 1;}
- uuid[10] = parseUuidPart(&uuidString[24]);
- uuid[11] = parseUuidPart(&uuidString[26]);
- uuid[12] = parseUuidPart(&uuidString[28]);
- uuid[13] = parseUuidPart(&uuidString[30]);
- uuid[14] = parseUuidPart(&uuidString[32]);
- uuid[15] = parseUuidPart(&uuidString[34]);
-
- return RAND_UUID_OK;
-#elif defined(HAVE_UUID_UUID_H)
- // note: uuid_t is typedefed as unsigned char[16] on linux/apple
- uuid_generate(uuid);
- return RAND_UUID_OK;
-#else
- // Fallback for all platforms is filling the array with random data
- OCFillRandomMem(uuid, UUID_SIZE);
- return RAND_UUID_OK;
-#endif
+ return n;
}
-OCRandomUuidResult OCGenerateUuidString(char uuidString[UUID_STRING_SIZE])
+uint32_t OCGetRandomRange(uint32_t firstBound, uint32_t secondBound)
{
- if (!uuidString)
+ if (firstBound == secondBound)
{
- return RAND_UUID_INVALID_PARAM;
+ return secondBound;
}
-#if defined(__ANDROID__)
- int32_t fd = open("/proc/sys/kernel/random/uuid", O_RDONLY);
- if (fd > 0)
+
+ uint32_t rangeBase = OC_MIN(firstBound, secondBound);
+ uint32_t rangeWidth = (firstBound > secondBound) ? (firstBound - secondBound) : (secondBound - firstBound);
+
+ /*
+ * Compute a random number between 0 and rangeWidth. Avoid using floating
+ * point types to avoid overflow when rangeWidth is large. The condition
+ * in the while loop will be false with probability at least 1/2.
+ */
+ uint32_t rangeMask = 0xFFFFFFFF >> nlz(rangeWidth);
+ uint32_t offset = 0;
+ do
{
- ssize_t readResult = read(fd, uuidString, UUID_STRING_SIZE - 1);
- close(fd);
- if (readResult < 0)
- {
- return RAND_UUID_READ_ERROR;
- }
- else if (readResult < UUID_STRING_SIZE - 1)
+ if(!OCGetRandomBytes((uint8_t*)&offset, sizeof(offset)))
{
- uuidString[0] = '\0';
- return RAND_UUID_READ_ERROR;
+ OIC_LOG(FATAL, OCRANDOM_TAG, "OCGetRandomBytes failed");
+ assert(false);
+ return rangeBase;
}
+ offset = offset & rangeMask;
+ }
+ while (offset > rangeWidth);
- uuidString[UUID_STRING_SIZE - 1] = '\0';
- for (char* p = uuidString; *p; ++p)
- {
- *p = tolower(*p);
- }
- return RAND_UUID_OK;
- }
- else
- {
- close(fd);
- return RAND_UUID_READ_ERROR;
- }
-#elif defined(HAVE_UUID_UUID_H)
- uint8_t uuid[UUID_SIZE];
- int8_t ret = OCGenerateUuid(uuid);
+ return rangeBase + offset;
+}
- if (ret != 0)
+bool OCGenerateUuid(uint8_t uuid[UUID_SIZE])
+{
+ if (!uuid)
{
- return ret;
+ OIC_LOG(ERROR, OCRANDOM_TAG, "Invalid parameter");
+ return false;
}
- uuid_unparse_lower(uuid, uuidString);
- return RAND_UUID_OK;
-
-#else
- uint8_t uuid[UUID_SIZE];
- OCGenerateUuid(uuid);
-
- return OCConvertUuidToString(uuid, uuidString);
-#endif
+ return OCGetRandomBytes(uuid, UUID_SIZE);
}
-OCRandomUuidResult OCConvertUuidToString(const uint8_t uuid[UUID_SIZE],
+bool OCConvertUuidToString(const uint8_t uuid[UUID_SIZE],
char uuidString[UUID_STRING_SIZE])
{
if (uuid == NULL || uuidString == NULL)
{
- return RAND_UUID_INVALID_PARAM;
+ OIC_LOG(ERROR, OCRANDOM_TAG, "Invalid parameter");
+ return false;
}
if (ret != UUID_STRING_SIZE - 1)
{
- return RAND_UUID_CONVERT_ERROR;
+ OIC_LOG(ERROR, OCRANDOM_TAG, "snprintf failed");
+ return false;
}
- return RAND_UUID_OK;
+ return true;
}
-OCRandomUuidResult OCConvertStringToUuid(const char uuidString[UUID_STRING_SIZE],
+bool OCConvertStringToUuid(const char uuidString[UUID_STRING_SIZE],
uint8_t uuid[UUID_SIZE])
{
if(NULL == uuidString || NULL == uuid)
{
- return RAND_UUID_INVALID_PARAM;
+ OIC_LOG(ERROR, OCRANDOM_TAG, "Invalid parameter");
+ return false;
}
size_t urnIdx = 0;
}
else
{
- return RAND_UUID_CONVERT_ERROR;
+ OIC_LOG(ERROR, OCRANDOM_TAG, "unexpected string length");
+ return false;
}
memcpy(uuid, convertedUuid, UUID_SIZE);
- return RAND_UUID_OK;
+ return true;
}
######################################################################
# Build flags
######################################################################
+
+randomtest_env.PrependUnique(CPPPATH = [
+ '../include',
+ '../../logger/include',
+ '../../../oc_logger/include',
+ ])
+
+randomtest_env.AppendUnique(LIBPATH = [randomtest_env.get('BUILD_DIR')])
+randomtest_env.PrependUnique(LIBS = ['octbstack',
+ 'connectivity_abstraction',
+ 'uuid'])
+
randomtest_env.PrependUnique(CPPPATH = ['../include'])
-randomtest_env.AppendUnique(LIBPATH = [os.path.join(randomtest_env.get('BUILD_DIR'), 'resource', 'c_common')])
randomtest_env.PrependUnique(LIBS = ['c_common'])
if target_os in ['linux']:
--- /dev/null
+
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+extern "C" {
+ #include "ocrandom.h"
+}
+
+#include "gtest/gtest.h"
+#include "math.h"
+
+
+TEST(RandomGeneration,OCGetRandom) {
+ uint32_t value = OCGetRandom();
+ EXPECT_LE((uint8_t )0, value);
+ EXPECT_GT(pow(2, 32), value);
+}
+
+TEST(RandomGeneration,OCGetRandomBytes) {
+ uint16_t ARR_SIZE = 20;
+ uint8_t array[ARR_SIZE]={};
+ EXPECT_TRUE(OCGetRandomBytes(array + 1, ARR_SIZE - 2));
+
+ for (int i = 1; i < ARR_SIZE - 2; i++) {
+ uint8_t value = array[i];
+ EXPECT_LE((uint8_t )0, value);
+ EXPECT_GT(pow(2, 8), value);
+ }
+ EXPECT_EQ((uint8_t )0, array[0]);
+ EXPECT_EQ((uint8_t )0, array[ARR_SIZE - 1]);
+}
+
+TEST(RandomGeneration, OCGenerateUuid)
+{
+ EXPECT_EQ(RAND_UUID_INVALID_PARAM, OCGenerateUuid(NULL));
+
+ uint8_t uuid[UUID_SIZE] = {};
+
+ EXPECT_TRUE(OCGenerateUuid(uuid));
+
+ EXPECT_FALSE(uuid[0] == '0' && uuid[1] == '0' &&
+ uuid[2] == '0' && uuid[3] == '0' &&
+ uuid[4] == '0' && uuid[5] == '0' &&
+ uuid[6] == '0' && uuid[7] == '0' &&
+ uuid[8] == '0' && uuid[9] == '0' &&
+ uuid[10] == '0' && uuid[11] == '0' &&
+ uuid[12] == '0' && uuid[13] == '0' &&
+ uuid[14] == '0' && uuid[15] == '0');
+}
+
+TEST(RandomGeneration, OCGenerateUuidString)
+{
+ char uuidString[UUID_STRING_SIZE] ={};
+ uint8_t uuid[UUID_SIZE] = {};
+
+ EXPECT_TRUE(OCGenerateUuid(uuid));
+ EXPECT_TRUE(OCConvertUuidToString(uuid, uuidString));
+ EXPECT_EQ(0, uuidString[36]);
+ EXPECT_EQ('-', uuidString[8]);
+ EXPECT_EQ('-', uuidString[13]);
+ EXPECT_EQ('-', uuidString[18]);
+ EXPECT_EQ('-', uuidString[23]);
+
+ for(int i = 0; i < 36; ++i)
+ {
+ EXPECT_TRUE(
+ i == 8 || i == 13 || i == 18 || i == 23 ||
+ (uuidString[i] >= 'a' && uuidString[i] <= 'f') ||
+ (uuidString[i] >= '0' && uuidString[i] <= '9'))
+ << "UUID Character out of range: "<< uuidString[i];
+ }
+}
Serial.begin(115200);
Serial.println("Testing Random Number generator for Arduino");
- Serial.print("Testing OCSeedRandom ... ");
- if (OCSeedRandom() == 0) {
- Serial.println("[Success]");
- } else {
- Serial.println("[Fail]");
- }
-
- Serial.print("Testing OCGetRandomByte ... ");
- uint8_t value8 = OCGetRandomByte();
- if (value8 >= 0 && value8 < pow(2, 8)) {
- Serial.println("[Success]");
- } else {
- Serial.println("[Fail]");
- }
-
Serial.print("Testing OCGetRandom ... ");
uint32_t value32 = OCGetRandom();
if (value32 >= 0 && value32 < pow(2, 32)) {
Serial.println("[Fail]");
}
- Serial.print("Testing OCFillRandomMem ... ");
+ Serial.print("Testing OCGetRandomBytes ... ");
uint8_t array[ARR_SIZE] = {};
- OCFillRandomMem(array + 1, ARR_SIZE - 2);
+ if (!OCGetRandomBytes(array + 1, ARR_SIZE - 2)) {
+ Serial.println("[Fail]");
+ }
uint8_t overall = 0;
uint8_t value82 = 0;
for (int i = 1; i <= ARR_SIZE - 2; i++) {
}
#include "gtest/gtest.h"
+#include "math.h"
#define ARR_SIZE (20)
-TEST(RandomGeneration,OCSeedRandom) {
- EXPECT_EQ(0, OCSeedRandom());
-}
-
-TEST(RandomGeneration,OCGetRandomByte) {
- EXPECT_NO_THROW(OCGetRandomByte());
-}
-
TEST(RandomGeneration,OCGetRandom) {
- EXPECT_NO_THROW(OCGetRandom());
+ uint32_t value = OCGetRandom();
+ EXPECT_LE((uint8_t )0, value);
+ EXPECT_GT(pow(2, 32), value);
}
-TEST(RandomGeneration,OCFillRandomMem_BoundsCheck) {
+TEST(RandomGeneration,OCGetRandomBytes) {
uint8_t array[ARR_SIZE] = {};
+ EXPECT_TRUE(OCGetRandomBytes(array + 1, ARR_SIZE - 2));
- // Ignore the first and last bytes of the array
- OCFillRandomMem(array + 1, ARR_SIZE - 2);
-
+ for (int i = 1; i <= ARR_SIZE - 2; i++) {
+ uint8_t value = array[i];
+ EXPECT_LE((uint8_t )0, value);
+ EXPECT_GT(pow(2, 8), value);
+ }
EXPECT_EQ((uint8_t )0, array[0]);
EXPECT_EQ((uint8_t )0, array[ARR_SIZE - 1]);
}
TEST(RandomGeneration, OCGenerateUuid)
{
- EXPECT_EQ(RAND_UUID_INVALID_PARAM, OCGenerateUuid(NULL));
+ EXPECT_FALSE(OCGenerateUuid(NULL));
- uint8_t uuid[16] = {};
+ uint8_t uuid[UUID_SIZE] = {};
- EXPECT_EQ(RAND_UUID_OK, OCGenerateUuid(uuid));
+ EXPECT_TRUE(OCGenerateUuid(uuid));
EXPECT_FALSE(uuid[0] == '0' && uuid[1] == '0' &&
uuid[2] == '0' && uuid[3] == '0' &&
TEST(RandomGeneration, OCGenerateUuidString)
{
- EXPECT_EQ(RAND_UUID_INVALID_PARAM, OCGenerateUuidString(NULL));
-
- char uuidString[37] = {};
+ char uuidString[UUID_STRING_SIZE] = {};
+ uint8_t uuid[UUID_SIZE] = {};
- EXPECT_EQ(RAND_UUID_OK, OCGenerateUuidString(uuidString));
+ EXPECT_TRUE(OCGenerateUuid(uuid));
+ EXPECT_TRUE(OCConvertUuidToString(uuid, uuidString));
EXPECT_EQ('\0', uuidString[36]);
EXPECT_EQ('-', uuidString[8]);
EXPECT_EQ('-', uuidString[13]);
win_helper_env.UserInstallTargetHeader('include/pthread_create.h', 'c_common/windows/include', 'pthread_create.h')
win_helper_env.UserInstallTargetHeader('include/vs12_snprintf.h', 'c_common/windows/include', 'vs12_snprintf.h')
-env.AppendUnique(LIBS = ['win_helper'])
+env.AppendUnique(LIBS = ['win_helper', 'bcrypt'])
{
memcpy(uuid, (char*) uuidPos + sizeof(UUID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "certificate uuid string: %s" , uuid);
- ret = OCConvertStringToUuid(uuid, peer->sep.identity.id);
+ ret = (OCConvertStringToUuid(uuid, peer->sep.identity.id)) ? 0 : -1;
SSL_CHECK_FAIL(peer, ret, "Failed to convert subject", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
}
if (NULL != userIdPos)
{
memcpy(uuid, (char*) userIdPos + sizeof(USERID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
- ret = OCConvertStringToUuid(uuid, peer->sep.userId.id);
+ ret = (OCConvertStringToUuid(uuid, peer->sep.userId.id)) ? 0 : -1;
SSL_CHECK_FAIL(peer, ret, "Failed to convert subject alt name", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
}
if (!g_isInitialized)
{
- if (0 != OCSeedRandom())
- {
- OIC_LOG(ERROR, TAG, "Seed Random Failed");
- }
-
CAResult_t res = CAInitializeMessageHandler();
if (res != CA_STATUS_OK)
{
return CA_MEMORY_ALLOC_FAILED;
}
- OCFillRandomMem((uint8_t *)temp, tokenLength);
+ if (!OCGetRandomBytes((uint8_t *)temp, tokenLength))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate random token");
+ return CA_STATUS_FAILED;
+ }
// save token
*token = temp;
*/
static uint64_t CAGetTimeoutValue()
{
- return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * OCGetRandomByte()) >> 8)) *
+ uint8_t randomValue = 0;
+ if (!OCGetRandomBytes(&randomValue, sizeof(randomValue)))
+ {
+ OIC_LOG(ERROR, TAG, "OCGetRandomBytes failed");
+ }
+
+ return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * randomValue) >> 8)) *
(uint64_t) 1000;
}
*/
void RMSendDeleteToNeighbourNodes();
-void RMGenerateGatewayID(uint8_t *id, size_t idLen)
+OCStackResult RMGenerateGatewayID(uint8_t *id, size_t idLen)
{
OIC_LOG(DEBUG, TAG, "RMGenerateGatewayID IN");
- OCFillRandomMem(id, idLen);
+
+ if (!OCGetRandomBytes(id, idLen))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate random gateway ID");
+ return OC_STACK_ERROR;
+ }
+
OIC_LOG(DEBUG, TAG, "RMGenerateGatewayID OUT");
+
+ return OC_STACK_OK;
}
OCStackResult RMInitialize()
{
}
// Generates a 4 byte Gateway ID.
- RMGenerateGatewayID((uint8_t *)&g_GatewayID, sizeof(g_GatewayID));
+ result = RMGenerateGatewayID((uint8_t *)&g_GatewayID, sizeof(g_GatewayID));
+ if (OC_STACK_OK != result)
+ {
+ OIC_LOG_V(ERROR, TAG, "RMGenerateGatewayID failed[%d]", result);
+ return result;
+ }
OIC_LOG_V(INFO, RM_TAG, "Gateway ID: %u", g_GatewayID);
OIC_LOG(INFO, TAG, "Invalid params");
return OC_STACK_INVALID_PARAM;
}
- if(!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
+ if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
{
OIC_LOG(INFO, TAG, "Invalid key size");
return OC_STACK_INVALID_PARAM;
VERIFY_NON_NULL(TAG, privData, ERROR);
OicSecKey_t privKey = {privData, keySize};
- OCFillRandomMem(privData, privDataKeySize);
+ if (!OCGetRandomBytes(privData, privDataKeySize))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate private key");
+ res = OC_STACK_ERROR;
+ goto exit;
+ }
// TODO: currently owner array is 1. only provisioning tool's id.
tempFirstCred = GenerateCredential(secondDeviceId, type, NULL, &privKey, ptDeviceId, NULL);
OICClearMemory(privData, privDataKeySize);
OICFree(privData);
- if(res != OC_STACK_OK)
+ if (res != OC_STACK_OK)
{
OICFree(tempFirstCred);
OICFree(tempSecondCred);
}
else
{
- OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
- VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
+ VERIFY_SUCCESS(TAG, OCGenerateUuid(ownerId.id), FATAL);
}
memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
if (!validId)
{
- if (OCGenerateUuid(gDoxm->deviceID.id) != RAND_UUID_OK)
+ if (!OCGenerateUuid(gDoxm->deviceID.id))
{
OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
- return ret;
+ return OC_STACK_ERROR;
}
ret = OC_STACK_OK;
* At this point, The server generate random hint and
* provide it to client through server key exchange message.
*/
- OCFillRandomMem(result, result_length);
+ if (!OCGetRandomBytes(result, result_length))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate random PSK hint");
+ ret = -1;
+ break;
+ }
ret = result_length;
OIC_LOG(DEBUG, TAG, "PSK HINT : ");
* At this point, The server generate random hint and
* provide it to client through server key exchange message.
*/
- OCFillRandomMem(result, result_length);
+ if (!OCGetRandomBytes(result, result_length))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate random PSK hint");
+ ret = -1;
+ break;
+ }
ret = result_length;
OIC_LOG(DEBUG, TAG, "PSK HINT : ");
OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid)
{
- OCRandomUuidResult result = OCConvertStringToUuid(strUuid, uuid->id);
- return (result == RAND_UUID_OK) ? OC_STACK_OK : OC_STACK_INVALID_PARAM;
+ bool result = OCConvertStringToUuid(strUuid, uuid->id);
+ return (result) ? OC_STACK_OK : OC_STACK_INVALID_PARAM;
}
do
{
- *observationId = OCGetRandomByte();
+ if (!OCGetRandomBytes((uint8_t*)observationId, sizeof(OCObservationId)))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to generate random observationId");
+ goto exit;
+ }
+
// Check if observation Id already exists
resObs = GetObserverUsingId (*observationId);
} while (NULL != resObs);
* into one PAL API.
*/
uint8_t uuid[UUID_SIZE];
- if (OCConvertStringToUuid(info.platformID, uuid) != RAND_UUID_OK)
+ if (!OCConvertStringToUuid(info.platformID, uuid))
{
OIC_LOG(ERROR, TAG, "Platform ID is not a UUID.");
goto exit;
handle = (OCDoHandle) OICMalloc(sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
if (handle)
{
- OCFillRandomMem((uint8_t*)handle, sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
+ if (!OCGetRandomBytes((uint8_t*)handle, sizeof(uint8_t[CA_MAX_TOKEN_LEN])))
+ {
+ OICFree(handle);
+ return NULL;
+ }
}
return handle;
}
const OicUuid_t *sid = OCGetServerInstanceID();
- if (sid && OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
+ if(sid && !OCConvertUuidToString(sid->id, sidStr))
{
OIC_LOG(FATAL, TAG, "Generate UUID String for Server Instance failed!");
return NULL;
{
uint8_t uuid[UUID_SIZE] = { 0, };
- if (RAND_UUID_OK == OCGenerateUuid(uuid))
+ if (OCGenerateUuid(uuid))
{
- if (RAND_UUID_OK == OCConvertUuidToString(uuid, uuidStr))
+ if (OCConvertUuidToString(uuid, uuidStr))
{
return NS_OK;
}
{
uint8_t uuid[UUID_SIZE] = { 0, };
char uuidStr[UUID_STRING_SIZE] = { 0, };
- if (RAND_UUID_OK == OCGenerateUuid(uuid))
+ if (OCGenerateUuid(uuid))
{
- if (RAND_UUID_OK == OCConvertUuidToString(uuid, uuidStr))
+ if (OCConvertUuidToString(uuid, uuidStr))
{
return std::string(uuidStr);
}