epid_provision_msg1.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "type_length_value.h"
  32. #include "sgx_tcrypto_internal.h"
  33. #include "epid_utility.h"
  34. #include "oal/oal.h"
  35. #include "aeerror.h"
  36. #include "PVEClass.h"
  37. #include "se_wrapper.h"
  38. /**
  39. * File: epid_provision_msg1.cpp
  40. * Description: Provide the untrusted implementation of code to generate ProvMsg1
  41. */
  42. //For each ProvMsg, the first field is msg header (which including XID)
  43. //But in the code here, XID is not counted as a TLV field(since it is part of msg header)
  44. // and the index of TLV field is started from 0.
  45. //Msg1 Top TLVs: TLV_CIPHER_TEXT(rsa_oaep_result),E+MAC(encrypted_and_mac_data)
  46. #define MSG1_TOP_FIELDS_COUNT 3
  47. #define MSG1_TOP_FIELD_RSA_OAEP_DATA msg1_fields[0]
  48. #define MSG1_TOP_FIELD_GCM_DATA msg1_fields[1]
  49. #define MSG1_TOP_FIELD_GCM_MAC msg1_fields[2]
  50. //Function to initialize TLV Header for ProvMsg1 and check whether input buffer for ProvMsg1 is large enough
  51. //field1_data_size[in]: size of field1_data which varies according to whether performance rekey used.
  52. //msg1_buffer_size[in]: size of buffer used to hold generated ProvMsg1, it is used by the function to verify whether size of buffer is large enough
  53. //xid[in]: Transaction ID used in protocol
  54. //msg1_header[out]: request header for ProvMsg1 to fill in
  55. static ae_error_t prov_msg1_gen_header(provision_request_header_t *msg1_header,
  56. uint32_t field1_data_size,
  57. const uint8_t *xid,
  58. uint32_t msg1_buffer_size)
  59. {
  60. uint32_t total_size = 0;
  61. if(sizeof(*msg1_header)>msg1_buffer_size){
  62. AESM_DBG_ERROR("Too small ProvMsg1 buffer size");
  63. return PVE_INSUFFICIENT_MEMORY_ERROR;
  64. }
  65. total_size = CIPHER_TEXT_TLV_SIZE(PVE_RSA_KEY_BYTES) + BLOCK_CIPHER_TEXT_TLV_SIZE(field1_data_size) +MAC_TLV_SIZE(MAC_SIZE);
  66. //initialize field in Msg1 Header
  67. msg1_header->protocol = SE_EPID_PROVISIONING;
  68. msg1_header->type = TYPE_PROV_MSG1;
  69. msg1_header->version = TLV_VERSION_1;
  70. if(0!=memcpy_s(msg1_header->xid, XID_SIZE, xid, XID_SIZE)){
  71. AESM_DBG_FATAL("fail in memcpy");
  72. return PVE_UNEXPECTED_ERROR;
  73. }
  74. uint32_t size_in;
  75. size_in = _htonl(total_size);//big endian size required in msg header
  76. if(0!=memcpy_s(&msg1_header->size, sizeof(msg1_header->size),&size_in, sizeof(size_in))){
  77. AESM_DBG_FATAL("fail in memcpy");
  78. return PVE_UNEXPECTED_ERROR;
  79. }
  80. if(total_size +sizeof(*msg1_header) >msg1_buffer_size){//the input msg body size is not large enough
  81. AESM_DBG_ERROR("Too small ProvMsg1 buffer size");
  82. return PVE_INSUFFICIENT_MEMORY_ERROR;
  83. }
  84. return AE_SUCCESS;
  85. }
  86. //Function to generate ProvMsg1
  87. //Input psvn could be NULL to use the current psvn, or input the previous_psvn from preivous ProvMsg2
  88. //The function will generate a random transaction id which is used by msg header of msg1
  89. //The function return AE_SUCCESS on success and other to indicate error
  90. //Format of ProvMsg1: RSA-OAEP(SK,PSID),E+MAC(DeviceID[:Flags])
  91. //@psvn: the input psvn or NULL
  92. //@pek: the input PEK got from endpoint selection
  93. //@performance_rekey_used: true for performance rekey and false for first provisioning, backup retrieval or TCB upgrade
  94. //@msg1: buffer to receive ProvMsg1 (including both header and body)
  95. //@msg1_size: size of buffer for generating ProvMsg1
  96. //@return AE_SUCCESS on success
  97. uint32_t CPVEClass::gen_prov_msg1(const psvn_t *psvn,
  98. const signed_pek_t& pek,
  99. bool performance_rekey_used,
  100. uint8_t *msg1,
  101. uint32_t msg1_size)
  102. {
  103. uint32_t ret = AE_SUCCESS;
  104. prov_msg1_output_t msg1_output;
  105. //ProvMsg1 header will be in the beginning part of the output msg
  106. provision_request_header_t *msg1_header = reinterpret_cast<provision_request_header_t *>(msg1);
  107. memset(&msg1_output, 0, sizeof(msg1_output));
  108. ret = gen_prov_msg1_data(psvn, &pek, performance_rekey_used, &msg1_output);
  109. if(AE_SUCCESS !=ret ){
  110. AESM_DBG_ERROR("Gen ProvMsg1 in trusted code failed:%d",ret);
  111. return ret;
  112. }
  113. ret = prov_msg1_gen_header(msg1_header, msg1_output.field1_data_size, msg1_output.xid, msg1_size);
  114. if(AE_SUCCESS != ret){
  115. AESM_DBG_ERROR("fail to generate ProvMsg1 Header:%d",ret);
  116. return ret;
  117. }
  118. {
  119. TLVsMsg tlvs_msg1;
  120. tlv_status_t tlv_status;
  121. tlv_status= tlvs_msg1.add_cipher_text(msg1_output.field0, PVE_RSA_KEY_BYTES, PEK_PUB);
  122. ret = tlv_error_2_pve_error(tlv_status);
  123. if(AE_SUCCESS!=ret){
  124. AESM_DBG_ERROR("Fail to generate field0 TLV of ProvMsg1:%d",ret);
  125. return ret;
  126. }
  127. tlv_status = tlvs_msg1.add_block_cipher_text(msg1_output.field1_iv, msg1_output.field1_data, msg1_output.field1_data_size);
  128. ret = tlv_error_2_pve_error(tlv_status);
  129. if(AE_SUCCESS!=ret){
  130. AESM_DBG_ERROR("Fail to generate field1 TLV of ProvMsg1:%d",ret);
  131. return ret;
  132. }
  133. tlv_status = tlvs_msg1.add_mac(msg1_output.field1_mac);
  134. ret = tlv_error_2_pve_error(tlv_status);
  135. if(AE_SUCCESS!=ret){
  136. AESM_DBG_ERROR("Fail to create field2 TLV of ProvMsg1:%d",ret);
  137. return ret;
  138. }
  139. uint32_t size = tlvs_msg1.get_tlv_msg_size();
  140. if(memcpy_s(msg1+PROVISION_REQUEST_HEADER_SIZE, msg1_size - PROVISION_REQUEST_HEADER_SIZE,
  141. tlvs_msg1.get_tlv_msg(), size)!=0){
  142. AESM_DBG_FATAL("memcpy error");
  143. return PVE_UNEXPECTED_ERROR;//The size overflow has been checked in header generation
  144. }
  145. }
  146. return AE_SUCCESS;
  147. }