3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004
17
#include "trousers/tss.h"
18
#include "trousers_types.h"
21
#include "tcs_utils.h"
22
#include "tcs_int_literals.h"
23
#include "capabilities.h"
26
#include "tcsd_wrap.h"
31
* Get a random number generated by the TPM. Most (all?) TPMs return a maximum number of random
32
* bytes that's less than the max allowed to be returned at the TSP level, which is 4K bytes.
33
* According to the TPM compliance work posted here: http://www.prosec.rub.de/tpmcompliance.html,
34
* some TPMs return as little as 132 bytes per query, which would require about 30 loops to get 4K.
35
* We'll be extremely conservative here and loop 50 times, since it won't affect performance on
36
* TPMs that return more bytes.
39
TCSP_GetRandom_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
40
UINT32 * bytesRequested, /* in, out */
41
BYTE ** randomBytes) /* out */
45
UINT32 paramSize, totalReturned = 0, bytesReturned, retries = 50;
46
BYTE txBlob[TSS_TPM_TXBLOB_SIZE], *rnd_tmp = NULL;
48
LogDebugFn("%u bytes", *bytesRequested);
50
if ((result = ctx_verify_context(hContext)))
54
if ((result = tpm_rqu_build(TPM_ORD_GetRandom, &offset, txBlob,
55
*bytesRequested - totalReturned, NULL)))
58
if ((result = req_mgr_submit_req(txBlob)))
61
result = UnloadBlob_Header(txBlob, ¶mSize);
65
UnloadBlob_UINT32(&offset, &bytesReturned, txBlob);
67
LogDebugFn("received %u bytes from the TPM", bytesReturned);
69
rnd_tmp = realloc(rnd_tmp, totalReturned + bytesReturned);
70
if (rnd_tmp == NULL) {
71
LogError("malloc of %u bytes failed.", bytesReturned);
72
return TCSERR(TSS_E_OUTOFMEMORY);
74
UnloadBlob(&offset, bytesReturned, txBlob, &rnd_tmp[totalReturned]);
77
if ((result = tpm_rsp_parse(TPM_ORD_GetRandom, txBlob, paramSize,
78
&bytesReturned, &rnd_tmp, NULL, NULL)))
81
*randomBytes = realloc(*randomBytes, totalReturned + bytesReturned);
82
if (*randomBytes == NULL) {
85
LogError("malloc of %u bytes failed.", bytesReturned);
86
result = TCSERR(TSS_E_OUTOFMEMORY);
89
memcpy(*randomBytes, rnd_tmp, bytesReturned);
93
totalReturned += bytesReturned;
98
} while (totalReturned < *bytesRequested && retries--);
100
if (totalReturned != *bytesRequested) {
101
LogDebugFn("Only %u random bytes recieved from TPM.", totalReturned);
103
result = TCSERR(TSS_E_FAIL);
106
*randomBytes = rnd_tmp;
115
TCSP_StirRandom_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
116
UINT32 inDataSize, /* in */
117
BYTE * inData) /* in */
122
BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
124
LogDebug("Entering stir random");
126
if (inDataSize > 255) {
127
LogDebugFn("inData is too large! (%u bytes)", inDataSize);
128
return TCSERR(TSS_E_BAD_PARAMETER);
131
if ((result = ctx_verify_context(hContext)))
134
if ((result = tpm_rqu_build(TPM_ORD_StirRandom, &offset, txBlob, inDataSize, inDataSize,
135
inData, NULL, NULL)))
138
if ((result = req_mgr_submit_req(txBlob)))
141
result = UnloadBlob_Header(txBlob, ¶mSize);
142
LogResult("Stir random", result);