epid_provision_msg4.cpp 12 KB

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