• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / libtpms / #2022

23 Sep 2025 01:11PM UTC coverage: 77.227% (+0.009%) from 77.218%
#2022

push

travis-ci

web-flow
Merge a45c293de into 4504f47c6

36116 of 46766 relevant lines covered (77.23%)

125180.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/src/tpm2/Entropy.c
1
/********************************************************************************/
2
/*                                                                                */
3
/*                             Entropy                                                */
4
/*                             Written by Ken Goldman                                */
5
/*                       IBM Thomas J. Watson Research Center                        */
6
/*            $Id: Entropy.c 1661 2021-03-18 19:00:58Z 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 - 2019                                */
59
/*                                                                                */
60
/********************************************************************************/
61

62
//** Includes and Local Values
63

64
#define _CRT_RAND_S
65
#include <stdlib.h>
66
#include <memory.h>
67

68
#include <openssl/rand.h>   /* libtpms added */
69

70
#include <time.h>
71
#include "Platform.h"
72

73
#if defined _MSC_VER || defined _MINGW                // libtpms changed
74
#  include <process.h>
75
#else
76
#  include <unistd.h>
77
#endif
78

79
// This is the last 32-bits of hardware entropy produced. We have to check to
80
// see that two consecutive 32-bit values are not the same because
81
// according to FIPS 140-2, annex C:
82
//
83
// "If each call to an RNG produces blocks of n bits (where n > 15), the first
84
// n-bit block generated after power-up, initialization, or reset shall not be
85
// used, but shall be saved for comparison with the next n-bit block to be
86
// generated. Each subsequent generation of an n-bit block shall be compared with
87
// the previously generated block. The test shall fail if any two compared n-bit
88
// blocks are equal."
89
extern uint32_t lastEntropy;
90

91
//** Functions
92

93
//*** rand32()
94
// Local function to get a 32-bit random number
95
static uint32_t rand32(void)
12,492✔
96
{
97
    uint32_t rndNum = rand();
12,492✔
98
#if RAND_MAX < UINT16_MAX
99
    // If the maximum value of the random number is a 15-bit number, then shift it up
100
    // 15 bits, get 15 more bits, shift that up 2 and then XOR in another value to get
101
    // a full 32 bits.
102
    rndNum = (rndNum << 15) ^ rand();
103
    rndNum = (rndNum << 2) ^ rand();
104
#elif RAND_MAX == UINT16_MAX
105
    // If the maximum size is 16-bits, shift it and add another 16 bits
106
    rndNum = (rndNum << 16) ^ rand();
107
#elif RAND_MAX < UINT32_MAX
108
    // If 31 bits, then shift 1 and include another random value to get the extra bit
109
    rndNum = (rndNum << 1) ^ rand();
12,492✔
110
#endif
111
    return rndNum;
12,492✔
112
}
113

114
//*** _plat__GetEntropy()
115
// This function is used to get available hardware entropy. In a hardware
116
// implementation of this function, there would be no call to the system
117
// to get entropy.
118
//  Return Type: int32_t
119
//  < 0        hardware failure of the entropy generator, this is sticky
120
// >= 0        the returned amount of entropy (bytes)
121
//
122
LIB_EXPORT int32_t _plat__GetEntropy(unsigned char* entropy,  // output buffer
20,912✔
123
                                     uint32_t       amount    // amount requested
124
)
125
{
126
    uint32_t rndNum;
20,912✔
127
    int32_t  ret;
20,912✔
128
    //
129
    // libtpms added begin
130
    if (amount > 0 && RAND_bytes(entropy, amount) == 1)
20,912✔
131
        return amount;
132
    // fall back to 'original' method
133
    // libtpms added end
134

135
    if(amount == 0)
12,492✔
136
    {
137
        // Seed the platform entropy source if the entropy source is software. There
138
        // is no reason to put a guard macro (#if or #ifdef) around this code because
139
        // this code would not be here if someone was changing it for a system with
140
        // actual hardware.
141
        //
142
        // NOTE 1: The following command does not provide proper cryptographic
143
        // entropy. Its primary purpose to make sure that different instances of the
144
        // simulator, possibly started by a script on the same machine, are seeded
145
        // differently. Vendors of the actual TPMs need to ensure availability of
146
        // proper entropy using their platform-specific means.
147
        //
148
        // NOTE 2: In debug builds by default the reference implementation will seed
149
        // its RNG deterministically (without using any platform provided randomness).
150
        // See the USE_DEBUG_RNG macro and DRBG_GetEntropy() function.
151
#if defined _MSC_VER || defined _MINGW                // libtpms changed
152
        srand((unsigned)_plat__RealTime() ^ _getpid());
153
#else
154
        srand((unsigned)_plat__RealTime() ^ getpid());
12,492✔
155
#endif
156
        lastEntropy = rand32();
12,492✔
157
        ret         = 0;
12,492✔
158
    }
159
    else
160
    {
161
        rndNum = rand32();
×
162
        if(rndNum == lastEntropy)
×
163
        {
164
            ret = -1;
165
        }
166
        else
167
        {
168
            lastEntropy = rndNum;
×
169
            // Each process will have its random number generator initialized
170
            // according to the process id and the initialization time. This is not a
171
            // lot of entropy so, to add a bit more, XOR the current time value into
172
            // the returned entropy value.
173
            // NOTE: the reason for including the time here rather than have it in
174
            // in the value assigned to lastEntropy is that rand() could be broken and
175
            // using the time would in the lastEntropy value would hide this.
176
            rndNum ^= (uint32_t)_plat__RealTime();
×
177

178
            // Only provide entropy 32 bits at a time to test the ability
179
            // of the caller to deal with partial results.
180
            ret = MIN(amount, sizeof(rndNum));
×
181
            memcpy(entropy, &rndNum, ret);
×
182
        }
183
    }
184
    return ret;
185
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc