Coverage Report

Created: 2023-09-25 06:15

/src/ibmswtpm2/src/Entropy.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*           Entropy            */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*            $Id: Entropy.c 1311 2018-08-23 21:39:29Z kgoldman $   */
7
/*                    */
8
/*  Licenses and Notices              */
9
/*                    */
10
/*  1. Copyright Licenses:              */
11
/*                    */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
15
/*    derivative works, distribute, display and perform the Source Code and */
16
/*    derivative works thereof, and to grant others the rights granted herein.  */
17
/*                    */
18
/*  - The TCG grants to the user of the other parts of the specification  */
19
/*    (other than the Source Code) the rights to reproduce, distribute,   */
20
/*    display, and perform the specification solely for the purpose of    */
21
/*    developing products based on such documents.        */
22
/*                    */
23
/*  2. Source Code Distribution Conditions:         */
24
/*                    */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
26
/*    this list of conditions and the following disclaimers.      */
27
/*                    */
28
/*  - Redistributions in binary form must reproduce the above copyright   */
29
/*    licenses, this list of conditions and the following disclaimers in the  */
30
/*    documentation and/or other materials provided with the distribution.  */
31
/*                    */
32
/*  3. Disclaimers:               */
33
/*                    */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
39
/*  information on specification licensing rights available through TCG   */
40
/*  membership agreements.              */
41
/*                    */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
47
/*                    */
48
/*  - Without limitation, TCG and its members and licensors disclaim all  */
49
/*    liability, including liability for infringement of any proprietary  */
50
/*    rights, relating to use of information in this specification and to the */
51
/*    implementation of this specification, and TCG disclaims all liability for */
52
/*    cost of procurement of substitute goods or services, lost profits, loss   */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
55
/*    arising in any way out of use or reliance upon this specification or any  */
56
/*    information herein.             */
57
/*                    */
58
/*  (c) Copyright IBM Corp. and others, 2016 - 2018       */
59
/*                    */
60
/********************************************************************************/
61
62
/* C.4 Entropy.c */
63
/* C.4.1. Includes and Local values*/
64
#define _CRT_RAND_S
65
#include <stdlib.h>
66
#include <memory.h>
67
#include "PlatformData.h"
68
#include "Platform_fp.h"
69
#include <time.h>
70
#ifdef _MSC_VER
71
#include <process.h>
72
#else
73
#include <unistd.h>
74
#endif
75
76
/* This is the last 32-bits of hardware entropy produced. We have to check to see that two
77
   consecutive 32-bit values are not the same because (according to FIPS 140-2, annex C */
78
/* "If each call to a RNG produces blocks of n bits (where n > 15), the first n-bit block generated
79
   after power-up, initialization, or reset shall not be used, but shall be saved for comparison
80
   with the next n-bit block to be generated. Each subsequent generation of an n-bit block shall be
81
   compared with the previously generated block. The test shall fail if any two compared n-bit
82
   blocks are equal." */
83
extern uint32_t        lastEntropy;
84
85
/* C.4.2. Functions */
86
/* C.4.2.1. rand32() */
87
/* Local function to get a 32-bit random number */
88
89
static uint32_t
90
rand32(
91
       void
92
       )
93
4.68k
{
94
4.68k
    uint32_t    rndNum = rand();
95
#if RAND_MAX < UINT16_MAX
96
    // If the maximum value of the random number is a 15-bit number, then shift it up
97
    // 15 bits, get 15 more bits, shift that up 2 and then XOR in another value to get
98
    // a full 32 bits.
99
    rndNum = (rndNum << 15) ^ rand();
100
    rndNum = (rndNum << 2) ^ rand();
101
#elif RAND_MAX == UINT16_MAX
102
    // If the maximum size is 16-bits, shift it and add another 16 bits
103
    rndNum = (rndNum << 16) ^ rand();
104
#elif RAND_MAX < UINT32_MAX
105
    // If 31 bits, then shift 1 and include another random value to get the extra bit
106
4.68k
    rndNum = (rndNum << 1) ^ rand();
107
4.68k
#endif
108
4.68k
    return rndNum;
109
4.68k
}
110
111
/* C.4.2.2 _plat__GetEntropy() */
112
/* This function is used to get available hardware entropy. In a hardware implementation of this
113
   function, there would be no call to the system to get entropy. */
114
/* Return Values Meaning */
115
/* < 0 hardware failure of the entropy generator, this is sticky */
116
/* >= 0 the returned amount of entropy (bytes) */
117
LIB_EXPORT int32_t
118
_plat__GetEntropy(
119
      unsigned char       *entropy,           // output buffer
120
      uint32_t             amount             // amount requested
121
      )
122
4.68k
{
123
4.68k
    uint32_t            rndNum;
124
4.68k
    int32_t             ret;
125
    //
126
4.68k
    if(amount == 0)
127
361
  {
128
      // Seed the platform entropy source if the entropy source is software. There is
129
      // no reason to put a guard macro (#if or #ifdef) around this code because this
130
      // code would not be here if someone was changing it for a system with actual
131
      // hardware.
132
      //
133
      // NOTE 1: The following command does not provide proper cryptographic entropy.
134
      // Its primary purpose to make sure that different instances of the simulator,
135
      // possibly started by a script on the same machine, are seeded differently.
136
      // But vendors of the actual TPMs need to ensure availability of proper entropy
137
      // using their platform specific means.
138
      //
139
      // NOTE 2: In debug builds by default the reference implementation will seed
140
      // its RNG deterministically (without using any platform provided randomness).
141
      // See the USE_DEBUG_RNG macro and DRBG_GetEntropy() function.
142
#ifdef _MSC_VER
143
      srand((unsigned)_plat__RealTime() ^ _getpid());
144
#else
145
361
      srand((unsigned)_plat__RealTime() ^ getpid());
146
361
#endif
147
361
      lastEntropy = rand32();
148
361
      ret = 0;
149
361
  }
150
4.32k
    else
151
4.32k
  {
152
4.32k
      rndNum = rand32();
153
4.32k
      if(rndNum == lastEntropy)
154
0
    {
155
0
        ret = -1;
156
0
    }
157
4.32k
      else
158
4.32k
    {
159
4.32k
        lastEntropy = rndNum;
160
        // Each process will have its random number generator initialized according
161
        // to the process id and the initialization time. This is not a lot of
162
        // entropy so, to add a bit more, XOR the current time value into the
163
        // returned entropy value.
164
        // NOTE: the reason for including the time here rather than have it in
165
        // in the value assigned to lastEntropy is that rand() could be broken and
166
        // using the time would in the lastEntropy value would hide this.
167
4.32k
        rndNum ^= (uint32_t)_plat__RealTime();
168
        // Only provide entropy 32 bits at a time to test the ability
169
        // of the caller to deal with partial results.
170
4.32k
        ret = MIN(amount, sizeof(rndNum));
171
4.32k
        memcpy(entropy, &rndNum, ret);
172
4.32k
    }
173
4.32k
  }
174
4.68k
    return ret;
175
4.68k
}
176