epid_provision_msg4.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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 <sgx_trts.h>
  34. #include "epid_utility.h"
  35. #include "aeerror.h"
  36. #include "PVEClass.h"
  37. #include "se_wrapper.h"
  38. #include "oal/internal_log.h"
  39. /**
  40. * File: epid_provision_msg4.cpp
  41. * Description: Provide the untrusted implementation of code to process ProvMsg4
  42. *
  43. * Untrusted Code for EPID Provision
  44. */
  45. #define MSG4_TOP_FIELDS_COUNT 3
  46. #define MSG4_TOP_FIELD_NONCE tlvs_msg4[0]
  47. #define MSG4_TOP_FIELD_DATA tlvs_msg4[1]
  48. #define MSG4_TOP_FIELD_MAC tlvs_msg4[2]
  49. #define MSG4_FIELD1_COUNT 6
  50. #define MSG4_FIELD1_DEVICE_ID tlvs_field1[5]
  51. #define MSG4_FIELD1_ENC_TCB tlvs_field1[0]
  52. #define MSG4_FIELD1_MAC_TCB tlvs_field1[1]
  53. #define MSG4_FIELD1_ENC_Axf tlvs_field1[2]
  54. #define MSG4_FIELD1_MAC_Axf tlvs_field1[3]
  55. #define MSG4_FIELD1_GROUP_CERT tlvs_field1[4]
  56. static ae_error_t msg4_integrity_checking(const TLVsMsg& tlvs_msg4)
  57. {
  58. uint32_t tlv_count = tlvs_msg4.get_tlv_count();
  59. if(tlv_count != MSG4_TOP_FIELDS_COUNT)
  60. return PVE_INTEGRITY_CHECK_ERROR;
  61. if(MSG4_TOP_FIELD_NONCE.type != TLV_NONCE || MSG4_TOP_FIELD_NONCE.size != NONCE_SIZE ||
  62. MSG4_TOP_FIELD_NONCE.version != TLV_VERSION_1 || MSG4_TOP_FIELD_NONCE.header_size != SMALL_TLV_HEADER_SIZE)
  63. return PVE_INTEGRITY_CHECK_ERROR;
  64. if(MSG4_TOP_FIELD_DATA.type != TLV_BLOCK_CIPHER_TEXT || MSG4_TOP_FIELD_DATA.version != TLV_VERSION_1)
  65. return PVE_INTEGRITY_CHECK_ERROR;
  66. if(MSG4_TOP_FIELD_MAC.type != TLV_MESSAGE_AUTHENTICATION_CODE || MSG4_TOP_FIELD_MAC.version != TLV_VERSION_1 ||
  67. MSG4_TOP_FIELD_MAC.size != MAC_SIZE || MSG4_TOP_FIELD_MAC.header_size != SMALL_TLV_HEADER_SIZE)
  68. return PVE_INTEGRITY_CHECK_ERROR;
  69. return AE_SUCCESS;
  70. }
  71. static ae_error_t msg4_field1_msg_checking(const TLVsMsg& tlvs_field1)
  72. {
  73. uint32_t tlv_count = tlvs_field1.get_tlv_count();
  74. if(tlv_count!=MSG4_FIELD1_COUNT){
  75. return PVE_MSG_ERROR;
  76. }
  77. uint32_t i;
  78. for(i=0;i<tlv_count;++i)
  79. if(tlvs_field1[i].version != TLV_VERSION_1)
  80. return PVE_MSG_ERROR;
  81. if(MSG4_FIELD1_GROUP_CERT.type != TLV_EPID_GROUP_CERT||
  82. MSG4_FIELD1_GROUP_CERT.size != sizeof(signed_epid_group_cert_t)||
  83. MSG4_FIELD1_GROUP_CERT.header_size != SMALL_TLV_HEADER_SIZE)
  84. return PVE_MSG_ERROR;
  85. if(MSG4_FIELD1_DEVICE_ID.type != TLV_DEVICE_ID ||
  86. MSG4_FIELD1_DEVICE_ID.size != sizeof(device_id_t)||
  87. MSG4_FIELD1_DEVICE_ID.header_size != SMALL_TLV_HEADER_SIZE)
  88. return PVE_MSG_ERROR;
  89. if(MSG4_FIELD1_ENC_TCB.type != TLV_BLOCK_CIPHER_TEXT||
  90. MSG4_FIELD1_ENC_TCB.size != BLOCK_CIPHER_TEXT_TLV_PAYLOAD_SIZE(SK_SIZE))
  91. return PVE_MSG_ERROR;
  92. if(MSG4_FIELD1_MAC_TCB.type != TLV_MESSAGE_AUTHENTICATION_CODE||
  93. MSG4_FIELD1_MAC_TCB.size != MAC_SIZE ||
  94. MSG4_FIELD1_MAC_TCB.header_size != SMALL_TLV_HEADER_SIZE)
  95. return PVE_MSG_ERROR;
  96. if(MSG4_FIELD1_ENC_Axf.type != TLV_BLOCK_CIPHER_TEXT||
  97. MSG4_FIELD1_ENC_Axf.size != BLOCK_CIPHER_TEXT_TLV_PAYLOAD_SIZE(HARD_CODED_EPID_MEMBER_WITH_ESCROW_TLV_SIZE))
  98. return PVE_MSG_ERROR;
  99. if(MSG4_FIELD1_MAC_Axf.type != TLV_MESSAGE_AUTHENTICATION_CODE||
  100. MSG4_FIELD1_MAC_Axf.size != MAC_SIZE||
  101. MSG4_FIELD1_MAC_Axf.header_size != SMALL_TLV_HEADER_SIZE)
  102. return PVE_MSG_ERROR;
  103. return AE_SUCCESS;
  104. }
  105. //Function to check message header of ProvMsg4 to determine whether it is valid
  106. //@msg4_header, input the message header of ProvMsg4
  107. //@return AE_SUCCESS if the message header is valid ProvMsg4 or error code if there're any problems
  108. static ae_error_t check_prov_msg4_header(const provision_response_header_t *msg4_header, uint32_t msg4_size)
  109. {
  110. if(msg4_header->protocol != SE_EPID_PROVISIONING || msg4_header->type != TYPE_PROV_MSG4 ||
  111. msg4_header->version != TLV_VERSION_1){
  112. return PVE_INTEGRITY_CHECK_ERROR;
  113. }
  114. uint32_t size_in_header = lv_ntohl(msg4_header->size);
  115. if(size_in_header + PROVISION_RESPONSE_HEADER_SIZE != msg4_size)
  116. return PVE_INTEGRITY_CHECK_ERROR;
  117. return AE_SUCCESS;
  118. }
  119. //Function to decode ProvMsg4 and generate epid data blob
  120. uint32_t CPVEClass::proc_prov_msg4(
  121. bool use_ek2_in_input,
  122. const uint8_t ek2[SK_SIZE],
  123. const uint8_t* msg4,
  124. uint32_t msg4_size,
  125. uint8_t* data_blob,
  126. uint32_t blob_size)
  127. {
  128. ae_error_t ret = AE_SUCCESS;
  129. uint8_t local_ek2[SK_SIZE];
  130. uint8_t *decoded_msg4 = NULL;
  131. const provision_response_header_t *msg4_header = reinterpret_cast<const provision_response_header_t *>(msg4);
  132. if(msg4_size < PROVISION_RESPONSE_HEADER_SIZE){
  133. AESM_DBG_ERROR("invalid msg4 size");
  134. return PVE_MSG_ERROR;
  135. }
  136. if(blob_size != HARD_CODED_EPID_BLOB_SIZE){
  137. AESM_DBG_FATAL("invalid input epid blob size");
  138. return PVE_PARAMETER_ERROR;
  139. }
  140. ret = check_prov_msg4_header(msg4_header, msg4_size);
  141. if( AE_SUCCESS != ret){
  142. AESM_DBG_ERROR("Invalid ProvMsg4 Header:%d",ret);
  143. return ret;
  144. }
  145. ret = check_epid_pve_pg_status_before_mac_verification(msg4_header);
  146. if( AE_SUCCESS != ret){
  147. AESM_DBG_ERROR("Backend return failure in ProvMsg4 Header:%d",ret);
  148. return ret;
  149. }
  150. do{
  151. TLVsMsg tlvs_msg4;
  152. tlv_status_t tlv_status;
  153. tlv_status = tlvs_msg4.init_from_buffer(msg4+static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE), msg4_size - static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE));
  154. ret = tlv_error_2_pve_error(tlv_status);
  155. if(AE_SUCCESS!=ret){
  156. AESM_DBG_ERROR("fail to decode ProvMsg4:%d",tlv_status);
  157. break;
  158. }
  159. ret = msg4_integrity_checking(tlvs_msg4);
  160. if(AE_SUCCESS != ret){
  161. AESM_DBG_ERROR("ProvMsg4 integrity checking error:%d",ret);
  162. break;
  163. }
  164. AESM_DBG_TRACE("ProvMsg4 decoded");
  165. if(!use_ek2_in_input){ //we need generate ek2
  166. prov_get_ek2_input_t ek2_input;
  167. if(memcpy_s(ek2_input.nonce, NONCE_SIZE, MSG4_TOP_FIELD_NONCE.payload, NONCE_SIZE)!=0){
  168. AESM_DBG_ERROR("fail in memcpy");
  169. ret = PVE_UNEXPECTED_ERROR;
  170. break;
  171. }
  172. if(memcpy_s(ek2_input.xid, XID_SIZE, msg4_header->xid, XID_SIZE)!=0){
  173. AESM_DBG_ERROR("fail in memcpy");
  174. ret = PVE_UNEXPECTED_ERROR;
  175. break;
  176. }
  177. //call PvE to get EK2
  178. se_static_assert(SK_SIZE == sizeof(prov_get_ek2_output_t));
  179. ret = (ae_error_t)get_ek2(&ek2_input, reinterpret_cast<prov_get_ek2_output_t *>(local_ek2));
  180. if(AE_SUCCESS != ret){
  181. AESM_DBG_ERROR("fail to get EK2:%d",ret);
  182. break;
  183. }
  184. }else{//reuse ek2 generated in processing ProvMsg2
  185. if(0!=memcpy_s(local_ek2, sizeof(local_ek2), ek2, SK_SIZE)){
  186. AESM_DBG_ERROR("fail in memcpy");
  187. ret = PVE_UNEXPECTED_ERROR;
  188. break;
  189. }
  190. }
  191. se_static_assert(SK_SIZE==sizeof(sgx_aes_gcm_128bit_key_t));
  192. tlv_msg_t field1 = block_cipher_tlv_get_encrypted_text(MSG4_TOP_FIELD_DATA);
  193. decoded_msg4 = reinterpret_cast<uint8_t *>(malloc(field1.msg_size));
  194. if(NULL == decoded_msg4){
  195. AESM_DBG_ERROR("malloc error");
  196. ret = AE_OUT_OF_MEMORY_ERROR;
  197. break;
  198. }
  199. sgx_status_t sgx_status = sgx_rijndael128GCM_decrypt(reinterpret_cast<const sgx_aes_gcm_128bit_key_t *>(local_ek2),
  200. field1.msg_buf, field1.msg_size, decoded_msg4,
  201. reinterpret_cast<uint8_t *>(block_cipher_tlv_get_iv(MSG4_TOP_FIELD_DATA)), IV_SIZE,
  202. reinterpret_cast<const uint8_t *>(msg4_header), PROVISION_RESPONSE_HEADER_SIZE,
  203. reinterpret_cast<const sgx_aes_gcm_128bit_tag_t *>(MSG4_TOP_FIELD_MAC.payload));
  204. if(SGX_ERROR_MAC_MISMATCH == sgx_status){
  205. AESM_DBG_ERROR("fail to decrypt ProvMsg4 by EK2");
  206. ret = PVE_INTEGRITY_CHECK_ERROR;
  207. break;
  208. }
  209. if( AE_SUCCESS != (ret = sgx_error_to_ae_error(sgx_status))){
  210. AESM_DBG_ERROR("error in decrypting ProvMsg4:%d",sgx_status);
  211. break;
  212. }
  213. AESM_DBG_TRACE("ProvMsg4 decrypted by EK2 successfully");
  214. ret = check_epid_pve_pg_status_after_mac_verification(msg4_header);
  215. if(AE_SUCCESS != ret){
  216. AESM_DBG_ERROR("Backend reported error passed MAC verification:%d",ret);
  217. break;
  218. }
  219. TLVsMsg tlvs_field1;
  220. tlv_status = tlvs_field1.init_from_buffer(decoded_msg4, field1.msg_size);
  221. ret = tlv_error_2_pve_error(tlv_status);
  222. if(AE_SUCCESS != ret){
  223. AESM_DBG_ERROR("ProvMsg4 Field2.1 decoding failed:%d",tlv_status);
  224. break;
  225. }
  226. ret = msg4_field1_msg_checking(tlvs_field1);
  227. if( AE_SUCCESS != ret){
  228. AESM_DBG_ERROR("ProvMsg4 Field2.1 invalid:%d",ret);
  229. break;
  230. }
  231. proc_prov_msg4_input_t msg4_input;
  232. if(sizeof(proc_prov_msg4_output_t)!=SGX_TRUSTED_EPID_BLOB_SIZE){
  233. AESM_DBG_FATAL("Trusted ProvMsg4 output buffer size error");
  234. ret = PVE_UNEXPECTED_ERROR;
  235. break;
  236. }
  237. tlv_msg_t tcb_data = block_cipher_tlv_get_encrypted_text(MSG4_FIELD1_ENC_TCB);
  238. tlv_msg_t Axf_data = block_cipher_tlv_get_encrypted_text(MSG4_FIELD1_ENC_Axf);
  239. if(0!=memcpy_s(&msg4_input.group_cert, sizeof(msg4_input.group_cert), MSG4_FIELD1_GROUP_CERT.payload, MSG4_FIELD1_GROUP_CERT.size)||
  240. 0!=memcpy_s(&msg4_input.equivalent_psvn, sizeof(psvn_t), device_id_tlv_get_psvn(MSG4_FIELD1_DEVICE_ID), sizeof(psvn_t))||
  241. 0!=memcpy_s(&msg4_input.fmsp, sizeof(fmsp_t), device_id_tlv_get_fmsp(MSG4_FIELD1_DEVICE_ID), sizeof(fmsp_t))||
  242. 0!=memcpy_s(&msg4_input.tcb_iv, IV_SIZE, block_cipher_tlv_get_iv(MSG4_FIELD1_ENC_TCB), IV_SIZE)||
  243. 0!=memcpy_s(&msg4_input.encrypted_tcb, SK_SIZE, tcb_data.msg_buf, tcb_data.msg_size)||
  244. 0!=memcpy_s(&msg4_input.tcb_mac, MAC_SIZE, MSG4_FIELD1_MAC_TCB.payload, MSG4_FIELD1_MAC_TCB.size)||
  245. 0!=memcpy_s(&msg4_input.member_credential_iv, IV_SIZE, block_cipher_tlv_get_iv(MSG4_FIELD1_ENC_Axf), IV_SIZE)||
  246. 0!=memcpy_s(&msg4_input.encrypted_member_credential, HARD_CODED_EPID_MEMBER_WITH_ESCROW_TLV_SIZE, Axf_data.msg_buf, Axf_data.msg_size)||
  247. 0!=memcpy_s(&msg4_input.member_credential_mac, MAC_SIZE, MSG4_FIELD1_MAC_Axf.payload, MSG4_FIELD1_MAC_Axf.size)){
  248. AESM_DBG_ERROR("memcpy error");
  249. ret = PVE_UNEXPECTED_ERROR;
  250. break;
  251. }
  252. ret = (ae_error_t)proc_prov_msg4_data(&msg4_input, reinterpret_cast<proc_prov_msg4_output_t *>(data_blob));
  253. AESM_DBG_TRACE("PvE return %d in Process ProvMsg4",ret);
  254. }while(0);
  255. if(decoded_msg4)free(decoded_msg4);
  256. return ret;
  257. }