15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <stdlib.h>
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <stdint.h>
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include <memory.h>
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "TpmBuildSwitches.h"
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          Local values
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This is the last 32-bits of hardware entropy produced. We have to check to see that two consecutive 32-
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     bit values are not the same because (according to FIPS 140-2, annex C
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           “If each call to a RNG produces blocks of n bits (where n > 15), the first n-bit block generated after
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           power-up, initialization, or reset shall not be used, but shall be saved for comparison with the next n-
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           bit block to be generated. Each subsequent generation of an n-bit block shall be compared with the
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           previously generated block. The test shall fail if any two compared n-bit blocks are equal.”
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
235679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyextern uint32_t               lastEntropy;
245679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyextern int                    firstValue;
255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          _plat__GetEntropy()
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function is used to get available hardware entropy. In a hardware implementation of this function,
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     there would be no call to the system to get entropy. If the caller does not ask for any entropy, then this is
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     a startup indication and firstValue should be reset.
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Return Value                       Meaning
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     <0                                 hardware failure of the entropy generator, this is sticky
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     >= 0                               the returned amount of entropy (bytes)
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
385679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT int32_t
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_plat__GetEntropy(
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      unsigned char            *entropy,                  // output buffer
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      uint32_t                  amount                    // amount requested
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury)
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      uint32_t                rndNum;
4561cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      if(amount == 0)
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      {
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          firstValue = 1;
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return 0;
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      }
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      // Only provide entropy 32 bits at a time to test the ability
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      // of the caller to deal with partial results.
5361cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury      rndNum = random();  //TODO(vbendeb): compare to rand_s case
5461cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury      if(firstValue)
5561cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury              firstValue = 0;
5661cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury
5761cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury      lastEntropy = rndNum;
5861cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury      if(amount > sizeof(rndNum))
5961cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury              amount = sizeof(rndNum);
6061cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury      memcpy(entropy, &rndNum, amount);
6161cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury
6261cee3d805a406463fff545c113d02ae0640ddffVadim Bendebury   return (int32_t)amount;
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
64