1 /*############################################################################ 2 # Copyright 2016-2017 Intel Corporation 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 ############################################################################*/ 16 17 /*! 18 * \file 19 * \brief Pseudo random number generator interface. 20 */ 21 #ifndef EPID_COMMON_TESTHELPER_PRNG_TESTHELPER_H_ 22 #define EPID_COMMON_TESTHELPER_PRNG_TESTHELPER_H_ 23 24 #if defined(_WIN32) || defined(_WIN64) 25 #define __STDCALL __stdcall 26 #else 27 #define __STDCALL 28 #endif 29 #include <limits.h> // for CHAR_BIT 30 #include <stdint.h> 31 #include <random> 32 #include <vector> 33 34 extern "C" { 35 #include "epid/common/types.h" 36 } 37 38 /// Return status for Prng Generate function 39 typedef enum { 40 kPrngNoErr = 0, //!< no error 41 kPrngErr = -999, //!< unspecified error 42 kPrngNotImpl, //!< not implemented error 43 kPrngBadArgErr //!< incorrect arg to function 44 } PrngStatus; 45 46 /// Pseudo random number generator (prng) class. 47 class Prng { 48 public: Prng()49 Prng() : seed_(1) { set_seed(seed_); } ~Prng()50 ~Prng() {} 51 /// Retrieve seed get_seed()52 unsigned int get_seed() const { return seed_; } 53 /// Set seed for random number generator set_seed(unsigned int val)54 void set_seed(unsigned int val) { 55 seed_ = val; 56 generator_.seed(seed_); 57 } 58 /// Generates random number Generate(unsigned int * random_data,int num_bits,void * user_data)59 static int __STDCALL Generate(unsigned int* random_data, int num_bits, 60 void* user_data) { 61 unsigned int num_bytes = num_bits / CHAR_BIT; 62 63 unsigned int extra_bits = num_bits % CHAR_BIT; 64 unsigned char* random_bytes = reinterpret_cast<unsigned char*>(random_data); 65 if (!random_data) { 66 return kPrngBadArgErr; 67 } 68 if (num_bits <= 0) { 69 return kPrngBadArgErr; 70 } 71 if (0 != extra_bits) { 72 num_bytes += 1; 73 } 74 75 Prng* myprng = (Prng*)user_data; 76 for (unsigned int n = 0; n < num_bytes; n++) { 77 random_bytes[n] = 78 static_cast<unsigned char>(myprng->generator_() & 0x000000ff); 79 } 80 81 return kPrngNoErr; 82 } 83 84 private: 85 unsigned int seed_; 86 std::mt19937 generator_; 87 }; 88 89 // BitSupplier implementation returns pre-defined bytes. 90 class StaticPrng { 91 public: StaticPrng(ConstOctStr bytes,size_t length)92 StaticPrng(ConstOctStr bytes, size_t length) 93 : bytes_((uint8_t const*)bytes, (uint8_t const*)bytes + length) {} ~StaticPrng()94 ~StaticPrng() {} 95 /// Generates random number Generate(unsigned int * random_data,int num_bits,void * user_data)96 static int __STDCALL Generate(unsigned int* random_data, int num_bits, 97 void* user_data) { 98 unsigned int num_bytes = num_bits / CHAR_BIT; 99 if (!random_data) { 100 return kPrngBadArgErr; 101 } 102 if (num_bits <= 0) { 103 return kPrngBadArgErr; 104 } 105 StaticPrng* myprng = (StaticPrng*)user_data; 106 for (size_t i = 0; i < num_bytes; i++) { 107 random_data[i] = myprng->bytes_[i % myprng->bytes_.size()]; 108 } 109 return kPrngNoErr; 110 } 111 112 private: 113 std::vector<uint8_t> bytes_; 114 }; 115 116 #endif // EPID_COMMON_TESTHELPER_PRNG_TESTHELPER_H_ 117