1 /*############################################################################
2 # Copyright 2017 Intel Corporation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 ############################################################################*/
16
17 /*!
18 * \file
19 * \brief TPM2_GetRandom command implementation.
20 */
21 #include <limits.h>
22
23 #include "epid/common/src/memory.h"
24 #include "epid/member/tpm2/getrandom.h"
25 #include "epid/member/tpm2/ibm_tss/printtss.h"
26 #include "epid/member/tpm2/ibm_tss/state.h"
27
28 #include "tss2/TPM_Types.h"
29 #include "tss2/tss.h"
30
Tpm2GetRandom(Tpm2Ctx * ctx,int const num_bits,void * random_data)31 EpidStatus Tpm2GetRandom(Tpm2Ctx* ctx, int const num_bits, void* random_data) {
32 EpidStatus sts = kEpidNoErr;
33 TPM_RC rc = TPM_RC_FAILURE;
34 int num_bytes = (num_bits + CHAR_BIT - 1) / CHAR_BIT;
35 BYTE* buf = (BYTE*)random_data;
36
37 if (!ctx || !random_data) {
38 return kEpidBadArgErr;
39 }
40
41 if (num_bits <= 0) {
42 return kEpidBadArgErr;
43 }
44
45 do {
46 GetRandom_In in;
47 GetRandom_Out out;
48 size_t max_digest_size = sizeof(((TPM2B_DIGEST*)0)->t.buffer);
49 UINT16 bytes_to_reqest = ((size_t)num_bytes > max_digest_size)
50 ? (UINT16)max_digest_size
51 : (UINT16)num_bytes;
52 in.bytesRequested = bytes_to_reqest;
53
54 rc = TSS_Execute(ctx->tss, (RESPONSE_PARAMETERS*)&out,
55 (COMMAND_PARAMETERS*)&in, NULL, TPM_CC_GetRandom,
56 TPM_RH_NULL, NULL, 0);
57 if (rc != TPM_RC_SUCCESS) {
58 print_tpm2_response_code("TPM2_GetRandom", rc);
59 sts = kEpidErr;
60 break;
61 }
62 if (!out.randomBytes.t.size || out.randomBytes.t.size > bytes_to_reqest) {
63 sts = kEpidErr;
64 break;
65 }
66
67 if (0 != memcpy_S(buf, (size_t)num_bytes, out.randomBytes.t.buffer,
68 out.randomBytes.t.size)) {
69 sts = kEpidErr;
70 break;
71 }
72
73 num_bytes -= out.randomBytes.t.size;
74 buf += out.randomBytes.t.size;
75 } while (num_bytes > 0);
76
77 return sts;
78 }
79