aboutsummaryrefslogtreecommitdiff
path: root/CpriRNG.c
blob: 95701ae0abbb06b5246cecef883931d87d2b6bc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

//#define __TPM_RNG_FOR_DEBUG__
//
//
//          Introduction
//
//     This file contains the interface to the OpenSSL() random number functions.
//
//          Includes
//
#include "OsslCryptoEngine.h"
int         s_entropyFailure;
//
//
//          Functions
//
//          _cpri__RngStartup()
//
//     This function is called to initialize the random number generator. It collects entropy from the platform to
//     seed the OpenSSL() random number generator.
//
LIB_EXPORT BOOL
_cpri__RngStartup(void)
{
     UINT32           entropySize;
     BYTE             entropy[MAX_RNG_ENTROPY_SIZE];
     INT32            returnedSize = 0;
     // Initialize the entropy source
     s_entropyFailure = FALSE;
     _plat__GetEntropy(NULL, 0);
     // Collect entropy until we have enough
     for(entropySize = 0;
         entropySize < MAX_RNG_ENTROPY_SIZE && returnedSize >= 0;
         entropySize += returnedSize)
     {
         returnedSize = _plat__GetEntropy(&entropy[entropySize],
                                             MAX_RNG_ENTROPY_SIZE - entropySize);
     }
     // Got some entropy on the last call and did not get an error
     if(returnedSize > 0)
     {
         // Seed OpenSSL with entropy
         RAND_seed(entropy, entropySize);
     }
     else
     {
         s_entropyFailure = TRUE;
     }
     return s_entropyFailure == FALSE;
}
//
//
//          _cpri__DrbgGetPutState()
//
//     This function is used to set the state of the RNG (direction == PUT_STATE) or to recover the state of the
//     RNG (direction == GET_STATE).
//
//
//
//     NOTE:           This not currently supported on OpenSSL() version.
//
LIB_EXPORT CRYPT_RESULT
_cpri__DrbgGetPutState(
    GET_PUT              direction,
    int                  bufferSize,
    BYTE                *buffer
    )
{
    UNREFERENCED_PARAMETER(direction);
    UNREFERENCED_PARAMETER(bufferSize);
    UNREFERENCED_PARAMETER(buffer);
    return CRYPT_SUCCESS;                 // Function is not implemented
}
//
//
//          _cpri__StirRandom()
//
//     This function is called to add external entropy to the OpenSSL() random number generator.
//
LIB_EXPORT CRYPT_RESULT
_cpri__StirRandom(
    INT32                entropySize,
    BYTE                *entropy
    )
{
    if (entropySize >= 0)
    {
        RAND_add((const void *)entropy, (int) entropySize, 0.0);
    }
    return CRYPT_SUCCESS;
}
//
//
//          _cpri__GenerateRandom()
//
//     This function is called to get a string of random bytes from the OpenSSL() random number generator. The
//     return value is the number of bytes placed in the buffer. If the number of bytes returned is not equal to the
//     number of bytes requested (randomSize) it is indicative of a failure of the OpenSSL() random number
//     generator and is probably fatal.
//
LIB_EXPORT UINT16
_cpri__GenerateRandom(
    INT32                randomSize,
    BYTE                *buffer
    )
{
    //
    // We don't do negative sizes or ones that are too large
    if (randomSize < 0 || randomSize > UINT16_MAX)
        return 0;
    // RAND_bytes uses 1 for success and we use 0
    if(RAND_bytes(buffer, randomSize) == 1)
        return (UINT16)randomSize;
    else
        return 0;
}
//
//
//
//          _cpri__GenerateSeededRandom()
//
//     This funciton is used to generate a pseudo-random number from some seed values This funciton returns
//     the same result each time it is called with the same parameters
//
LIB_EXPORT UINT16
_cpri__GenerateSeededRandom(
   INT32               randomSize,      //   IN: the size of the request
   BYTE               *random,          //   OUT: receives the data
   TPM_ALG_ID          hashAlg,         //   IN: used by KDF version but not here
   TPM2B              *seed,            //   IN: the seed value
   const char         *label,           //   IN: a label string (optional)
   TPM2B              *partyU,          //   IN: other data (oprtional)
   TPM2B              *partyV           //   IN: still more (optional)
   )
{
   return (_cpri__KDFa(hashAlg, seed, label, partyU, partyV,
                       randomSize * 8, random, NULL, FALSE));
}