Home | History | Annotate | Download | only in ibm_tss
      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 
     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