• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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