Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 4: Supporting Routines
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 //#define __TPM_RNG_FOR_DEBUG__
      9 //
     10 //
     11 //          Introduction
     12 //
     13 //     This file contains the interface to the OpenSSL() random number functions.
     14 //
     15 //          Includes
     16 //
     17 #include "OsslCryptoEngine.h"
     18 int         s_entropyFailure;
     19 //
     20 //
     21 //          Functions
     22 //
     23 //          _cpri__RngStartup()
     24 //
     25 //     This function is called to initialize the random number generator. It collects entropy from the platform to
     26 //     seed the OpenSSL() random number generator.
     27 //
     28 LIB_EXPORT BOOL
     29 _cpri__RngStartup(void)
     30 {
     31      UINT32           entropySize;
     32      BYTE             entropy[MAX_RNG_ENTROPY_SIZE];
     33      INT32            returnedSize = 0;
     34      // Initialize the entropy source
     35      s_entropyFailure = FALSE;
     36      _plat__GetEntropy(NULL, 0);
     37      // Collect entropy until we have enough
     38      for(entropySize = 0;
     39          entropySize < MAX_RNG_ENTROPY_SIZE && returnedSize >= 0;
     40          entropySize += returnedSize)
     41      {
     42          returnedSize = _plat__GetEntropy(&entropy[entropySize],
     43                                              MAX_RNG_ENTROPY_SIZE - entropySize);
     44      }
     45      // Got some entropy on the last call and did not get an error
     46      if(returnedSize > 0)
     47      {
     48          // Seed OpenSSL with entropy
     49          RAND_seed(entropy, entropySize);
     50      }
     51      else
     52      {
     53          s_entropyFailure = TRUE;
     54      }
     55      return s_entropyFailure == FALSE;
     56 }
     57 //
     58 //
     59 //          _cpri__DrbgGetPutState()
     60 //
     61 //     This function is used to set the state of the RNG (direction == PUT_STATE) or to recover the state of the
     62 //     RNG (direction == GET_STATE).
     63 //
     64 //
     65 //
     66 //     NOTE:           This not currently supported on OpenSSL() version.
     67 //
     68 LIB_EXPORT CRYPT_RESULT
     69 _cpri__DrbgGetPutState(
     70     GET_PUT              direction,
     71     int                  bufferSize,
     72     BYTE                *buffer
     73     )
     74 {
     75     UNREFERENCED_PARAMETER(direction);
     76     UNREFERENCED_PARAMETER(bufferSize);
     77     UNREFERENCED_PARAMETER(buffer);
     78     return CRYPT_SUCCESS;                 // Function is not implemented
     79 }
     80 //
     81 //
     82 //          _cpri__StirRandom()
     83 //
     84 //     This function is called to add external entropy to the OpenSSL() random number generator.
     85 //
     86 LIB_EXPORT CRYPT_RESULT
     87 _cpri__StirRandom(
     88     INT32                entropySize,
     89     BYTE                *entropy
     90     )
     91 {
     92     if (entropySize >= 0)
     93     {
     94         RAND_add((const void *)entropy, (int) entropySize, 0.0);
     95     }
     96     return CRYPT_SUCCESS;
     97 }
     98 //
     99 //
    100 //          _cpri__GenerateRandom()
    101 //
    102 //     This function is called to get a string of random bytes from the OpenSSL() random number generator. The
    103 //     return value is the number of bytes placed in the buffer. If the number of bytes returned is not equal to the
    104 //     number of bytes requested (randomSize) it is indicative of a failure of the OpenSSL() random number
    105 //     generator and is probably fatal.
    106 //
    107 LIB_EXPORT UINT16
    108 _cpri__GenerateRandom(
    109     INT32                randomSize,
    110     BYTE                *buffer
    111     )
    112 {
    113     //
    114     // We don't do negative sizes or ones that are too large
    115     if (randomSize < 0 || randomSize > UINT16_MAX)
    116         return 0;
    117     // RAND_bytes uses 1 for success and we use 0
    118     if(RAND_bytes(buffer, randomSize) == 1)
    119         return (UINT16)randomSize;
    120     else
    121         return 0;
    122 }
    123 //
    124 //
    125 //
    126 //          _cpri__GenerateSeededRandom()
    127 //
    128 //     This funciton is used to generate a pseudo-random number from some seed values This funciton returns
    129 //     the same result each time it is called with the same parameters
    130 //
    131 LIB_EXPORT UINT16
    132 _cpri__GenerateSeededRandom(
    133    INT32               randomSize,      //   IN: the size of the request
    134    BYTE               *random,          //   OUT: receives the data
    135    TPM_ALG_ID          hashAlg,         //   IN: used by KDF version but not here
    136    TPM2B              *seed,            //   IN: the seed value
    137    const char         *label,           //   IN: a label string (optional)
    138    TPM2B              *partyU,          //   IN: other data (oprtional)
    139    TPM2B              *partyV           //   IN: still more (optional)
    140    )
    141 {
    142    return (_cpri__KDFa(hashAlg, seed, label, partyU, partyV,
    143                        randomSize * 8, random, NULL, FALSE));
    144 }
    145