provision_msg2.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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 "msg3_parm.h"
  32. #include "se_sig_rl.h"
  33. #include "cipher.h"
  34. #include "helper.h"
  35. #include "pve_qe_common.h"
  36. #include "pek_pub_key.h"
  37. #include "byte_order.h"
  38. #include "sgx_lfence.h"
  39. #include <string.h>
  40. #include <stdlib.h>
  41. /**
  42. * File: provision_msg2.cpp
  43. * Description: Provide the implementation of code to decrypt TIK from decoded ProvMsg2
  44. *
  45. * Core Code of Provision Encla
  46. * sigrl will be processed in ProvMsg3 generation
  47. */
  48. ///Function to verify that EPID cert type and version is correct for sigrl
  49. static pve_status_t verify_sigrl_cert_type_version(const se_sig_rl_t *sigrl_cert)
  50. {
  51. if(SE_EPID_SIG_RL_ID!=sigrl_cert->epid_identifier||
  52. SE_EPID_SIG_RL_VERSION!=sigrl_cert->protocol_version)
  53. return PVEC_SIGRL_INTEGRITY_CHECK_ERROR;
  54. return PVEC_SUCCESS;
  55. }
  56. //The function assumed that the SigRL is available in the ProvMsg2
  57. //It will copy the SigRL Header to EPC memory: msg3_parm->sigrl_header
  58. //The function will partially update the SHA256 hash value (only SigRL Header) for piece-meal ECDSA signature generation
  59. //And it also calculates number of sigRL entries and verifies the size of the SigRL matches it exactly
  60. //The format of SigRL is assumed to be
  61. // (SigRLCertHeader:SigRlEntry1:SigRlEntry2:...:SigRlEntryn:ECDSASig)
  62. //Where SigRLCertHeader including EPIDVersion,CertType and SigRLHeader
  63. static pve_status_t prov_msg2_proc_sigrl_header(const external_memory_byte_t* emp_sigrl,
  64. uint32_t sigrl_size,
  65. prov_msg3_parm_t *msg3_parm)
  66. {
  67. sgx_status_t sgx_status = SGX_SUCCESS;
  68. pve_status_t pve_status = PVEC_SUCCESS;
  69. const uint32_t sigrl_header_size = static_cast<uint32_t>(sizeof(se_sig_rl_t) - sizeof(SigRlEntry));
  70. if(sigrl_size<sigrl_header_size+2*SE_ECDSA_SIGN_SIZE){
  71. //sigrl with too small size, it should contains at least sigrl header and the ECDSA Signature
  72. return PVEC_SIGRL_INTEGRITY_CHECK_ERROR;//signature not checked so integrity error
  73. }
  74. //
  75. // if we mispredict above, we might overflow
  76. // when we access SigRL header
  77. //
  78. sgx_lfence();
  79. pve_memcpy_in(&msg3_parm->sigrl_header, emp_sigrl, sigrl_header_size);//copy in sigrl header
  80. msg3_parm->emp_sigrl_sig_entries = emp_sigrl+sigrl_header_size;
  81. pve_status = verify_sigrl_cert_type_version(&msg3_parm->sigrl_header);
  82. if( PVEC_SUCCESS!=pve_status )
  83. return pve_status;
  84. sgx_status = sgx_sha256_init(&msg3_parm->sha_state);//init sigrl hash
  85. if(SGX_SUCCESS!=sgx_status)
  86. return sgx_error_to_pve_error(sgx_status);
  87. //update hash for SigRL header saved in EPC memory previously
  88. sgx_status = sgx_sha256_update(reinterpret_cast<const uint8_t *>(&msg3_parm->sigrl_header), sigrl_header_size, msg3_parm->sha_state);
  89. if(SGX_SUCCESS!=sgx_status)
  90. return sgx_error_to_pve_error(sgx_status);
  91. uint32_t entry_count = msg3_parm->sigrl_count = lv_ntohl(msg3_parm->sigrl_header.sig_rl.n2);//get the sigrl_count safely
  92. //now check whether the sigrl count matches the total size of the sigrl inside the msg
  93. uint32_t safe_sigrl_size = sigrl_header_size + 2*ECDSA_SIGN_SIZE;//constant size which will not overflow
  94. if( (UINT32_MAX-safe_sigrl_size)/sizeof(SigRlEntry)<entry_count){//check for integer overflow
  95. return PVEC_INTEGER_OVERFLOW_ERROR;
  96. }
  97. safe_sigrl_size += entry_count * static_cast<uint32_t>(sizeof(SigRlEntry));//calculate size safely now
  98. if(safe_sigrl_size != sigrl_size){//SigRL size must exactly match the expectation
  99. return PVEC_SIGRL_INTEGRITY_CHECK_ERROR;
  100. }
  101. return PVEC_SUCCESS;
  102. }
  103. //Function to unseal old epid blob, verify it and use it to prepare epid library state
  104. // so that later we could use it to generate EPID Signature
  105. //It will be used only when PreviousPSVN is avaiable in ProvMsg2
  106. static pve_status_t prepare_epid_member(const proc_prov_msg2_blob_input_t *msg2_blob_input, prov_msg3_parm_t *msg3_parm)
  107. {
  108. pve_status_t ret_status = PVEC_SUCCESS;
  109. sgx_status_t sgx_status = SGX_SUCCESS;
  110. if(!msg2_blob_input->is_previous_pi_provided)
  111. return PVEC_UNEXPECTED_ERROR;
  112. const sgx_sealed_data_t *old_epid_data_blob = reinterpret_cast<const sgx_sealed_data_t *>(msg2_blob_input->old_epid_data_blob);
  113. //try to unseal the old epid blob
  114. if(sgx_get_encrypt_txt_len(old_epid_data_blob)!=sizeof(se_secret_epid_data_sdk_t)||
  115. sgx_get_add_mac_txt_len(old_epid_data_blob)!=sizeof(se_plaintext_epid_data_sdk_t))
  116. return PVEC_EPID_BLOB_ERROR; //return PVEC_EPID_BLOB_ERROR to tell AESM to backup retrial of old epid blob
  117. se_plaintext_epid_data_sdk_t epid_cert;
  118. se_secret_epid_data_sdk_t epid_data;
  119. uint32_t epid_data_len = sizeof(epid_data);
  120. uint32_t epid_cert_len = sizeof(epid_cert);
  121. BitSupplier epid_prng = (BitSupplier)epid_random_func;
  122. EpidStatus epid_ret = kEpidNoErr;
  123. memset(&epid_cert, 0 ,sizeof(epid_cert));
  124. memset(&epid_data, 0, sizeof(epid_data)); //now start unseal epid blob
  125. if((sgx_status=sgx_unseal_data(const_cast<sgx_sealed_data_t *>(old_epid_data_blob),
  126. reinterpret_cast<uint8_t *>(&epid_cert), &epid_cert_len,
  127. reinterpret_cast<uint8_t *>(&epid_data),&epid_data_len)) != SGX_SUCCESS){
  128. if(sgx_status == SGX_ERROR_MAC_MISMATCH){
  129. ret_status = PVEC_EPID_BLOB_ERROR;//return PVEC_EPID_BLOB_ERROR to tell AESM to backup retrial of old epid blob
  130. }else{
  131. ret_status = sgx_error_to_pve_error(sgx_status);
  132. if(ret_status == PVEC_INVALID_CPU_ISV_SVN){
  133. ret_status = PVEC_PARAMETER_ERROR;//The input epid blob is too new so that it is not supported
  134. }
  135. }
  136. goto ret_point;
  137. }
  138. //check whether sigrl previous psvn matches psvn in secret part of old epid blob
  139. if(0!=memcmp(&msg2_blob_input->previous_pi.cpu_svn, &epid_cert.equiv_cpu_svn,sizeof(sgx_cpu_svn_t))||
  140. 0 != memcmp(&msg2_blob_input->previous_pi.pve_svn, &epid_cert.equiv_pve_isv_svn, sizeof(sgx_isv_svn_t))||
  141. epid_cert.xeid != msg3_parm->local_xegb.xeid){
  142. ret_status = PVEC_EPID_BLOB_ERROR;//return PVEC_EPID_BLOB_ERROR to tell AESM to backup retrial of old epid blob
  143. goto ret_point;
  144. }
  145. if(epid_cert.seal_blob_type != PVE_SEAL_EPID_KEY_BLOB||
  146. epid_cert.epid_key_version != EPID_KEY_BLOB_VERSION_SDK){
  147. ret_status = PVEC_EPID_BLOB_ERROR;//if the epid blob version does not match, which means the data is not an epid blob sealed by current version of PvE/QE
  148. goto ret_point;
  149. }
  150. //Previous gid is provided since this function assumes that Previous PSVN is provided
  151. //And the previous gid must be same as the gid in old epid blob cert
  152. if(memcmp(&epid_cert.epid_group_cert.gid, &msg2_blob_input->previous_gid, sizeof(GroupId))!=0||
  153. memcmp(&epid_data.epid_private_key.gid, &msg2_blob_input->previous_gid, sizeof(GroupId))!=0){
  154. ret_status = PVEC_EPID_BLOB_ERROR;
  155. goto ret_point;
  156. }
  157. //start preparing epid state for EPID signature generation
  158. epid_ret = epid_member_create(epid_prng, NULL, NULL, &msg3_parm->epid_member);
  159. if(kEpidNoErr != epid_ret){
  160. ret_status = epid_error_to_pve_error(epid_ret);
  161. goto ret_point;
  162. }
  163. epid_ret = EpidProvisionKey(msg3_parm->epid_member,
  164. &epid_cert.epid_group_cert,//group cert from old epid blob
  165. &epid_data.epid_private_key,//group private key from old epid blob
  166. &epid_data.member_precomp_data);
  167. if (kEpidNoErr != epid_ret) {
  168. ret_status = epid_error_to_pve_error(epid_ret);
  169. goto ret_point;
  170. }
  171. // start member
  172. epid_ret = EpidMemberStartup(msg3_parm->epid_member);
  173. if (kEpidNoErr != epid_ret) {
  174. ret_status = epid_error_to_pve_error(epid_ret);
  175. }
  176. ret_point:
  177. (void)memset_s(&epid_data, sizeof(epid_data), 0, sizeof(epid_data));//clear secret data from stack
  178. return ret_status;
  179. }
  180. //Function to process data from ProvMsg2 and generate data for ProvMsg3 on success
  181. //Both emp_sigrl and emp_epid_sig are in external memory where emp_ prefix represents "external memory pointer"
  182. //@msg2_blob_input, input the decoded data of ProvMsg2
  183. //@performance_rekey_used, 1 if performance rekey used, 0 if not
  184. //@emp_sigrl, the optional input sigrl in external memory (where emp_ prefix stands for "external memory pointer")
  185. //@sigrl_size, size in bytes of emp_sigrl
  186. //@msg3_output, output buffer to hold data to create ProvMsg3
  187. //@emp_epid_sig, output the EPID Signature which is in external memory if required
  188. //@epid_sig_buffer_size: input the size of buffer emp_epid_sig
  189. //@return PVEC_SUCCESS on success and error code on failure
  190. // PVEC_EPID_BLOB_ERROR is returned if msg2_blob_input.old_epid_data_blob is required but it is invalid and
  191. // msg2_blob_input.previous_pi should be filled in by a Previous platform information from ProvMsg2
  192. pve_status_t proc_prov_msg2_data(const proc_prov_msg2_blob_input_t *msg2_blob_input, //Input data of the ProvMsg2
  193. uint8_t performance_rekey_used, // if in performance rekey mode
  194. const external_memory_byte_t *emp_sigrl, //optional sigrl inside external memory
  195. uint32_t sigrl_size,
  196. gen_prov_msg3_output_t *msg3_output, //output data for msg3 generation
  197. external_memory_byte_t *emp_epid_sig, //optional buffer to output EPID Signature
  198. uint32_t epid_sig_buffer_size)
  199. {
  200. uint8_t tcb[SK_SIZE];
  201. pve_status_t ret = PVEC_SUCCESS;
  202. uint8_t pek_result = SGX_EC_INVALID_SIGNATURE;
  203. prov_msg3_parm_t msg3_parm;
  204. //initialize buffers to 0 according to coding style
  205. memset(tcb, 0, sizeof(tcb));
  206. memset(&msg3_parm, 0, sizeof(msg3_parm));
  207. sgx_status_t sgx_status = verify_xegb_with_default(msg2_blob_input->xegb, &pek_result, msg3_parm.local_xegb);
  208. if(SGX_SUCCESS != sgx_status){
  209. ret = sgx_error_to_pve_error(sgx_status);
  210. goto ret_point;
  211. }else if(pek_result != SGX_EC_VALID){
  212. ret = PVEC_XEGDSK_SIGN_ERROR;
  213. goto ret_point;
  214. }
  215. sgx_status = check_pek_signature(msg2_blob_input->pek, (sgx_ec256_public_t*)msg3_parm.local_xegb.pek_sk, &pek_result);
  216. if(SGX_SUCCESS != sgx_status){
  217. ret = sgx_error_to_pve_error(sgx_status);
  218. goto ret_point;
  219. }else if(pek_result != SGX_EC_VALID){
  220. ret = PVEC_PEK_SIGN_ERROR; //use a special error code to indicate PEK Signature error
  221. goto ret_point;
  222. }
  223. ret = check_signature_of_group_pub_cert(&msg2_blob_input->group_cert, msg3_parm.local_xegb.epid_sk);
  224. if(PVEC_SUCCESS != ret){
  225. goto ret_point;
  226. }
  227. // we must parse SigRL header to find count of sigrl entries
  228. if( msg2_blob_input->is_previous_pi_provided ){//We need to generate Basic Signature if sigrl_psvn present even if sigrl is not available
  229. //Initialize for EPID library function to prepare for piece meal processing
  230. ret = prepare_epid_member(msg2_blob_input, &msg3_parm);//old epid data blob is required
  231. if( PVEC_SUCCESS!=ret )
  232. goto ret_point;
  233. if(NULL!=emp_sigrl){
  234. //process sigrl_header for hash value generation (used by ECDSA signature)
  235. ret = prov_msg2_proc_sigrl_header( emp_sigrl, sigrl_size, &msg3_parm);
  236. //
  237. // for user_check SigRL input
  238. // based on n2 field in SigRL
  239. //
  240. sgx_lfence();
  241. if( PVEC_SUCCESS!=ret )
  242. goto ret_point;
  243. }
  244. }else if(NULL!=emp_sigrl){//sigrl provided but sigrl_psvn not available
  245. ret = PVEC_MSG_ERROR;
  246. goto ret_point;
  247. }
  248. //Now we could generate the ProvMsg3. SigRL of ProvMsg2 will be parsed in this function too if available
  249. ret = gen_prov_msg3_data(msg2_blob_input, msg3_parm, performance_rekey_used, msg3_output, emp_epid_sig,
  250. epid_sig_buffer_size);
  251. ret_point:
  252. (void)memset_s(tcb, sizeof(tcb), 0, sizeof(tcb));
  253. if(NULL!=msg3_parm.p_msg3_state)
  254. pve_aes_gcm_encrypt_fini(msg3_parm.p_msg3_state, msg3_parm.msg3_state_size);
  255. if(NULL!=msg3_parm.sha_state)
  256. sgx_sha256_close(msg3_parm.sha_state);
  257. if(NULL!=msg3_parm.epid_member){
  258. EpidMemberDelete(&msg3_parm.epid_member);
  259. }
  260. return ret;
  261. }