nv.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 TSS NV API implementation.
  19. */
  20. #include "epid/member/tpm2/nv.h"
  21. #include <tss2/tss.h>
  22. #include "epid/common/src/memory.h"
  23. #include "epid/member/tpm2/ibm_tss/printtss.h"
  24. #include "epid/member/tpm2/ibm_tss/state.h"
  25. EpidStatus Tpm2NvUndefineSpace(Tpm2Ctx* ctx, uint32_t nv_index) {
  26. TPM_RC rc = 0;
  27. NV_UndefineSpace_In in;
  28. TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
  29. if (!ctx) {
  30. return kEpidBadArgErr;
  31. }
  32. if ((nv_index >> 24) != TPM_HT_NV_INDEX) {
  33. return kEpidBadArgErr;
  34. }
  35. in.authHandle = TPM_RH_OWNER;
  36. // the NV Index to remove from NV space
  37. in.nvIndex = nv_index;
  38. rc = TSS_Execute(ctx->tss, NULL, (COMMAND_PARAMETERS*)&in, NULL,
  39. TPM_CC_NV_UndefineSpace, sessionHandle0, NULL, 0,
  40. TPM_RH_NULL, NULL, 0);
  41. if (rc != TPM_RC_SUCCESS) {
  42. print_tpm2_response_code("TPM2_NV_UndefineSpace", rc);
  43. return kEpidBadArgErr;
  44. }
  45. return kEpidNoErr;
  46. }
  47. EpidStatus Tpm2NvDefineSpace(Tpm2Ctx* ctx, uint32_t nv_index, size_t size) {
  48. TPM_RC rc = 0;
  49. NV_DefineSpace_In in = {0};
  50. TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
  51. if (!ctx || size == 0 || size > MAX_NV_BUFFER_SIZE) {
  52. return kEpidBadArgErr;
  53. }
  54. if ((nv_index >> 24) != TPM_HT_NV_INDEX) {
  55. return kEpidBadArgErr;
  56. }
  57. in.authHandle = TPM_RH_OWNER;
  58. // the handle of the data area
  59. in.publicInfo.nvPublic.nvIndex = nv_index;
  60. // hash algorithm used to compute the name of the Index and used for the
  61. // authPolicy
  62. in.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA256;
  63. in.publicInfo.nvPublic.attributes.val = TPMA_NVA_NO_DA | TPMA_NVA_AUTHWRITE |
  64. TPMA_NVA_AUTHREAD | TPMA_NVA_ORDINARY;
  65. // the size of the data area
  66. in.publicInfo.nvPublic.dataSize = (uint16_t)size;
  67. rc = TSS_Execute(ctx->tss, NULL, (COMMAND_PARAMETERS*)&in, NULL,
  68. TPM_CC_NV_DefineSpace, sessionHandle0, NULL, 0, TPM_RH_NULL,
  69. NULL, 0);
  70. if (rc != TPM_RC_SUCCESS) {
  71. print_tpm2_response_code("TPM2_NV_DefineSpace", rc);
  72. if (rc == TPM_RC_NV_DEFINED) {
  73. return kEpidDuplicateErr;
  74. }
  75. return kEpidBadArgErr;
  76. }
  77. return kEpidNoErr;
  78. }
  79. EpidStatus Tpm2NvRead(Tpm2Ctx* ctx, uint32_t nv_index, size_t size,
  80. uint16_t offset, void* data) {
  81. TPM_RC rc = 0;
  82. NV_Read_In in;
  83. NV_Read_Out out;
  84. TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
  85. int done = FALSE;
  86. // bytes read so far
  87. uint16_t bytes_read_so_far = 0;
  88. if (!ctx || !data || size == 0 || size > MAX_NV_BUFFER_SIZE) {
  89. return kEpidBadArgErr;
  90. }
  91. if ((nv_index >> 24) != TPM_HT_NV_INDEX) {
  92. return kEpidBadArgErr;
  93. }
  94. if ((nv_index >> 24) != TPM_HT_NV_INDEX) {
  95. return kEpidBadArgErr;
  96. }
  97. // Authorization handle
  98. in.authHandle = nv_index;
  99. in.nvIndex = nv_index;
  100. in.offset = offset;
  101. while ((rc == TPM_RC_SUCCESS) && !done) {
  102. in.offset = offset + bytes_read_so_far;
  103. if ((uint32_t)(size - bytes_read_so_far) < MAX_NV_BUFFER_SIZE) {
  104. // last chunk
  105. in.size = (uint16_t)size - bytes_read_so_far;
  106. } else {
  107. // next chunk
  108. in.size = MAX_NV_BUFFER_SIZE;
  109. }
  110. rc = TSS_Execute(ctx->tss, (RESPONSE_PARAMETERS*)&out,
  111. (COMMAND_PARAMETERS*)&in, NULL, TPM_CC_NV_Read,
  112. sessionHandle0, NULL, 0, TPM_RH_NULL, NULL, 0);
  113. if (rc == TPM_RC_SUCCESS) {
  114. // copy the results to the read buffer
  115. memcpy_S((uint8_t*)data + bytes_read_so_far, size - bytes_read_so_far,
  116. out.data.b.buffer, out.data.b.size);
  117. bytes_read_so_far += out.data.b.size;
  118. if (bytes_read_so_far == size) {
  119. done = TRUE;
  120. }
  121. } else {
  122. print_tpm2_response_code("TPM2_NV_Read", rc);
  123. }
  124. }
  125. if (rc != TPM_RC_SUCCESS) {
  126. return kEpidBadArgErr;
  127. }
  128. return kEpidNoErr;
  129. }
  130. EpidStatus Tpm2NvWrite(Tpm2Ctx* ctx, uint32_t nv_index, size_t size,
  131. uint16_t offset, void const* data) {
  132. TPM_RC rc = TPM_RC_SUCCESS;
  133. NV_Write_In in = {0};
  134. TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
  135. if (!ctx || !data || size == 0 || size > MAX_NV_BUFFER_SIZE) {
  136. return kEpidBadArgErr;
  137. }
  138. if ((nv_index >> 24) != TPM_HT_NV_INDEX) {
  139. return kEpidBadArgErr;
  140. }
  141. in.authHandle = nv_index;
  142. in.data.b.size = (uint16_t)size;
  143. memcpy(in.data.b.buffer, data, size);
  144. in.nvIndex = nv_index;
  145. // beginning offset
  146. in.offset = offset;
  147. rc = TSS_Execute(ctx->tss, NULL, (COMMAND_PARAMETERS*)&in, NULL,
  148. TPM_CC_NV_Write, sessionHandle0, NULL, 0, TPM_RH_NULL, NULL,
  149. 0);
  150. if (rc != TPM_RC_SUCCESS) {
  151. print_tpm2_response_code("TPM2_NV_Write", rc);
  152. return kEpidBadArgErr;
  153. }
  154. return kEpidNoErr;
  155. }