getrandom.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. * \file
  18. * \brief TPM2_GetRandom command implementation.
  19. */
  20. #include <limits.h>
  21. #include "epid/common/src/memory.h"
  22. #include "epid/member/tpm2/getrandom.h"
  23. #include "epid/member/tpm2/ibm_tss/printtss.h"
  24. #include "epid/member/tpm2/ibm_tss/state.h"
  25. #include "tss2/TPM_Types.h"
  26. #include "tss2/tss.h"
  27. EpidStatus Tpm2GetRandom(Tpm2Ctx* ctx, int const num_bits, void* random_data) {
  28. EpidStatus sts = kEpidNoErr;
  29. TPM_RC rc = TPM_RC_FAILURE;
  30. int num_bytes = (num_bits + CHAR_BIT - 1) / CHAR_BIT;
  31. BYTE* buf = (BYTE*)random_data;
  32. if (!ctx || !random_data) {
  33. return kEpidBadArgErr;
  34. }
  35. if (num_bits <= 0) {
  36. return kEpidBadArgErr;
  37. }
  38. do {
  39. GetRandom_In in;
  40. GetRandom_Out out;
  41. size_t max_digest_size = sizeof(((TPM2B_DIGEST*)0)->t.buffer);
  42. UINT16 bytes_to_reqest = ((size_t)num_bytes > max_digest_size)
  43. ? (UINT16)max_digest_size
  44. : (UINT16)num_bytes;
  45. in.bytesRequested = bytes_to_reqest;
  46. rc = TSS_Execute(ctx->tss, (RESPONSE_PARAMETERS*)&out,
  47. (COMMAND_PARAMETERS*)&in, NULL, TPM_CC_GetRandom,
  48. TPM_RH_NULL, NULL, 0);
  49. if (rc != TPM_RC_SUCCESS) {
  50. print_tpm2_response_code("TPM2_GetRandom", rc);
  51. sts = kEpidErr;
  52. break;
  53. }
  54. if (!out.randomBytes.t.size || out.randomBytes.t.size > bytes_to_reqest) {
  55. sts = kEpidErr;
  56. break;
  57. }
  58. if (0 != memcpy_S(buf, (size_t)num_bytes, out.randomBytes.t.buffer,
  59. out.randomBytes.t.size)) {
  60. sts = kEpidErr;
  61. break;
  62. }
  63. num_bytes -= out.randomBytes.t.size;
  64. buf += out.randomBytes.t.size;
  65. } while (num_bytes > 0);
  66. return sts;
  67. }