quoting_enclave.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  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. #ifndef __linux__
  32. #include "targetver.h"
  33. #endif
  34. #include "ae_ipp.h"
  35. #include "se_types.h"
  36. #include "sgx_quote.h"
  37. #include "aeerror.h"
  38. #include "sgx_tseal.h"
  39. #include "sgx_lfence.h"
  40. #include "epid_pve_type.h"
  41. #include "sgx_utils.h"
  42. #include "ipp_wrapper.h"
  43. #include "quoting_enclave_t.c"
  44. #include "sgx_tcrypto.h"
  45. #include "se_sig_rl.h"
  46. #include "se_ecdsa_verify_internal.h"
  47. #include "se_quote_internal.h"
  48. #include "pve_qe_common.h"
  49. #include "byte_order.h"
  50. #include "util.h"
  51. #include "qsdk_pub.hh"
  52. #include "isk_pub.hh"
  53. #include "epid/member/api.h"
  54. #ifdef __cplusplus
  55. extern "C" {
  56. #endif
  57. #include "epid/member/software_member.h"
  58. #include "epid/member/src/write_precomp.h"
  59. #include "epid/member/src/signbasic.h"
  60. #include "epid/member/src/nrprove.h"
  61. #ifdef __cplusplus
  62. }
  63. #endif
  64. #if !defined(SWAP_4BYTES)
  65. #define SWAP_4BYTES(u32) \
  66. ((uint32_t)(((((unsigned char*)&(u32))[0]) << 24) \
  67. + ((((unsigned char*)&(u32))[1]) << 16) \
  68. + ((((unsigned char*)&(u32))[2]) << 8) \
  69. + (((unsigned char*)&(u32))[3])))
  70. #endif
  71. // Start from 1, and it's little endian.
  72. #define QE_QUOTE_VERSION 2
  73. #define QE_AES_IV_SIZE 12
  74. #define QE_AES_KEY_SIZE 16
  75. #define QE_OAEP_SEED_SIZE 32
  76. /* One field in sgx_quote_t(signature_len) is not part of the quote_body need
  77. to be signed by EPID. So we need to minus sizeof(uint32_t). */
  78. #define QE_QUOTE_BODY_SIZE (sizeof(sgx_quote_t) - sizeof(uint32_t))
  79. /*
  80. * An internal function used to verify EPID Blob, get EPID Group Cert
  81. * and get EPID context, at the same time, you can check whether EPID blob has
  82. * been resealed.
  83. *
  84. * @param p_blob[in, out] Pointer to EPID Blob.
  85. * @param p_is_resealed[out] Whether the EPID Blob has been resealed.
  86. * @param create_context[in] Flag indicates create EPID context or not.
  87. * @param plaintext_epid_data[out] Used to get the plaintext part of epid blob
  88. * @param pp_epid_context[out] Used to get the pointer of the EPID context.
  89. * @return ae_error_t AE_SUCCESS or other error cases.
  90. */
  91. static ae_error_t verify_blob_internal(
  92. uint8_t *p_blob,
  93. uint32_t blob_size,
  94. uint8_t *p_is_resealed,
  95. uint32_t create_context,
  96. se_plaintext_epid_data_sdk_t& plaintext_epid_data,
  97. MemberCtx **pp_epid_context)
  98. {
  99. ae_error_t ret = QE_UNEXPECTED_ERROR;
  100. sgx_status_t se_ret = SGX_SUCCESS;
  101. uint8_t resealed= FALSE;
  102. se_secret_epid_data_sdk_t secret_epid_data;
  103. se_plaintext_epid_data_sik_t plaintext_old_format;
  104. uint32_t plaintext_length;
  105. int is_old_format = 0;
  106. uint32_t decryptedtext_length = sizeof(secret_epid_data);
  107. sgx_sealed_data_t *p_epid_blob = (sgx_sealed_data_t *)p_blob;
  108. uint8_t local_epid_blob[sizeof(*p_epid_blob)
  109. + sizeof(secret_epid_data)
  110. + sizeof(plaintext_epid_data)]
  111. = {0};
  112. do {
  113. // We will use plaintext_old_format as buffer to hold the output of sgx_unseal_data.
  114. // It can be se_plaintext_epid_data_sik_t or se_plaintext_epid_data_sdk_t.
  115. // We use the static assert to reassure plaintext_old_format is big enough.
  116. // If someone changed the definition of these 2 structures and break current assumption,
  117. // it will report error in compile time.
  118. se_static_assert(sizeof(plaintext_old_format) >= sizeof(plaintext_epid_data));
  119. if (sgx_get_encrypt_txt_len(p_epid_blob) != sizeof(se_secret_epid_data_sdk_t) &&
  120. sgx_get_encrypt_txt_len(p_epid_blob) != sizeof(se_secret_epid_data_sik_t)) {
  121. return QE_EPIDBLOB_ERROR;
  122. }
  123. plaintext_length = sgx_get_add_mac_txt_len(p_epid_blob);
  124. if (plaintext_length != sizeof(se_plaintext_epid_data_sik_t) &&
  125. plaintext_length != sizeof(se_plaintext_epid_data_sdk_t))
  126. {
  127. return QE_EPIDBLOB_ERROR;
  128. }
  129. memset(&secret_epid_data, 0, sizeof(secret_epid_data));
  130. memset(&plaintext_epid_data, 0, sizeof(plaintext_epid_data));
  131. memset(&plaintext_old_format, 0, sizeof(plaintext_old_format));
  132. se_ret = sgx_unseal_data(p_epid_blob,
  133. (uint8_t *)&plaintext_old_format, // The unsealed plaintext can be old or new format, the buffer is defined as old format because it is bigger
  134. &plaintext_length,
  135. (uint8_t *)&secret_epid_data,
  136. &decryptedtext_length);
  137. BREAK_IF_TRUE(SGX_SUCCESS != se_ret, ret, QE_EPIDBLOB_ERROR);
  138. //QE will support both epid blob with/without member precomputation
  139. //If the epid blob without member precomputation is used, QE will generate member precomputation and reseal epid blob
  140. //blob_type and key_version are always first two fields of plaintext in both format
  141. BREAK_IF_TRUE((plaintext_old_format.seal_blob_type != PVE_SEAL_EPID_KEY_BLOB)
  142. || (plaintext_old_format.epid_key_version != EPID_KEY_BLOB_VERSION_SDK&&
  143. plaintext_old_format.epid_key_version != EPID_KEY_BLOB_VERSION_SIK),
  144. ret, QE_EPIDBLOB_ERROR);
  145. // Only 2 combinations are legitimate for the tuple epid_key_version|decryptedtext_length|plaintext_length:
  146. // EPID_KEY_BLOB_VERSION_SIK|sizeof(se_secret_epid_data_sik_t)|sizeof(se_plaintext_epid_data_sik_t)
  147. // EPID_KEY_BLOB_VERSION_SDK|sizeof(se_secret_epid_data_sdk_t)|sizeof(se_plaintext_epid_data_sdk_t)
  148. BREAK_IF_TRUE((plaintext_old_format.epid_key_version == EPID_KEY_BLOB_VERSION_SIK &&
  149. (decryptedtext_length != sizeof(se_secret_epid_data_sik_t) || plaintext_length != sizeof(se_plaintext_epid_data_sik_t))) ||
  150. (plaintext_old_format.epid_key_version == EPID_KEY_BLOB_VERSION_SDK &&
  151. (decryptedtext_length != sizeof(se_secret_epid_data_sdk_t) || plaintext_length != sizeof(se_plaintext_epid_data_sdk_t))),
  152. ret, QE_EPIDBLOB_ERROR);
  153. // If the input epid blob is in sik format, we will upgrade it to sdk version
  154. if (plaintext_old_format.epid_key_version == EPID_KEY_BLOB_VERSION_SIK) {
  155. plaintext_epid_data.seal_blob_type = PVE_SEAL_EPID_KEY_BLOB;
  156. plaintext_epid_data.epid_key_version = EPID_KEY_BLOB_VERSION_SDK;
  157. memcpy(&plaintext_epid_data.equiv_cpu_svn, &plaintext_old_format.equiv_cpu_svn, sizeof(plaintext_old_format.equiv_cpu_svn));
  158. memcpy(&plaintext_epid_data.equiv_pve_isv_svn, &plaintext_old_format.equiv_pve_isv_svn, sizeof(plaintext_old_format.equiv_pve_isv_svn));
  159. memcpy(&plaintext_epid_data.epid_group_cert, &plaintext_old_format.epid_group_cert, sizeof(plaintext_old_format.epid_group_cert));
  160. memcpy(&plaintext_epid_data.qsdk_exp, &plaintext_old_format.qsdk_exp, sizeof(plaintext_old_format.qsdk_exp));
  161. memcpy(&plaintext_epid_data.qsdk_mod, &plaintext_old_format.qsdk_mod, sizeof(plaintext_old_format.qsdk_mod));
  162. memcpy(&plaintext_epid_data.epid_sk, &plaintext_old_format.epid_sk, sizeof(plaintext_old_format.epid_sk));
  163. plaintext_epid_data.xeid = plaintext_old_format.xeid;
  164. memset(&secret_epid_data.member_precomp_data, 0, sizeof(secret_epid_data.member_precomp_data));
  165. is_old_format = 1;
  166. //PrivKey of secret_epid_data are both in offset 0 so that we need not move it
  167. }
  168. else {//SDK version format
  169. memcpy(&plaintext_epid_data, &plaintext_old_format, sizeof(plaintext_epid_data));
  170. }
  171. /* Create report to get current cpu_svn and isv_svn. */
  172. sgx_report_t report;
  173. memset(&report, 0, sizeof(report));
  174. se_ret = sgx_create_report(NULL, NULL, &report);
  175. BREAK_IF_TRUE(SGX_SUCCESS != se_ret, ret, QE_UNEXPECTED_ERROR);
  176. /* Get the random function pointer. */
  177. BitSupplier rand_func = epid_random_func;
  178. /* Create EPID member context if required. PvE is responsible for verifying
  179. the Cert signature before storing them in the EPID blob. */
  180. if (create_context)
  181. {
  182. EpidStatus epid_ret = kEpidNoErr;
  183. epid_ret = epid_member_create(rand_func, NULL, NULL, pp_epid_context);
  184. BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR);
  185. epid_ret = EpidProvisionKey(*pp_epid_context,
  186. &(plaintext_epid_data.epid_group_cert),
  187. (PrivKey*)&(secret_epid_data.epid_private_key),
  188. is_old_format ? NULL : &secret_epid_data.member_precomp_data);
  189. BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR);
  190. // start member
  191. epid_ret = EpidMemberStartup(*pp_epid_context);
  192. BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR);
  193. if (is_old_format)
  194. {
  195. epid_ret = EpidMemberWritePrecomp(*pp_epid_context, &secret_epid_data.member_precomp_data);
  196. BREAK_IF_TRUE(kEpidNoErr != epid_ret, ret, QE_UNEXPECTED_ERROR);
  197. }
  198. }
  199. /* Update the Key Blob using the SEAL Key for the current TCB if the TCB is
  200. upgraded after the Key Blob is generated. Here memcmp cpu_svns might be
  201. different even though they're actually same, but for defense in depth we
  202. will keep this comparison here. And we will also upgrade old format EPID
  203. blob to new format here. */
  204. if ((memcmp(&report.body.cpu_svn, &p_epid_blob->key_request.cpu_svn,
  205. sizeof(report.body.cpu_svn)))
  206. || (report.body.isv_svn != p_epid_blob->key_request.isv_svn)
  207. || plaintext_old_format.epid_key_version == EPID_KEY_BLOB_VERSION_SIK)
  208. {
  209. se_ret = sgx_seal_data(sizeof(plaintext_epid_data),
  210. (uint8_t *)&plaintext_epid_data,
  211. sizeof(secret_epid_data),
  212. (uint8_t *)&secret_epid_data,
  213. SGX_TRUSTED_EPID_BLOB_SIZE_SDK,
  214. (sgx_sealed_data_t *)local_epid_blob);
  215. BREAK_IF_TRUE(SGX_SUCCESS != se_ret, ret, QE_UNEXPECTED_ERROR);
  216. memcpy(p_epid_blob, local_epid_blob, blob_size);
  217. resealed = TRUE;
  218. }
  219. *p_is_resealed = resealed;
  220. ret = AE_SUCCESS;
  221. }
  222. while (false);
  223. // Clear the output buffer to make sure nothing leaks.
  224. memset_s(&secret_epid_data, sizeof(secret_epid_data), 0,
  225. sizeof(secret_epid_data));
  226. if (ret != AE_SUCCESS)
  227. {
  228. epid_member_delete(pp_epid_context);
  229. }
  230. return ret;
  231. }
  232. /*
  233. * External function used to verify EPID Blob and check whether QE has
  234. * been updated.
  235. *
  236. * @param p_blob[in, out] Pointer to EPID Blob.
  237. * @param blob_size[in] The size of EPID Blob, in bytes.
  238. * @param p_is_resealed[out] Whether the EPID Blob is resealed within this function call.
  239. * @return uint32_t AE_SUCCESS or other error cases.
  240. */
  241. uint32_t verify_blob(
  242. uint8_t *p_blob,
  243. uint32_t blob_size,
  244. uint8_t *p_is_resealed)
  245. {
  246. se_plaintext_epid_data_sdk_t plain_text;
  247. /* Actually, some cases here will be checked with code generated by
  248. edger8r. Here we just want to defend in depth. */
  249. if(NULL == p_blob || NULL == p_is_resealed)
  250. return QE_PARAMETER_ERROR;
  251. if(SGX_TRUSTED_EPID_BLOB_SIZE_SDK != blob_size)
  252. return QE_PARAMETER_ERROR;
  253. //
  254. // if we mispredict here and blob_size is too
  255. // small, we might overflow
  256. //
  257. sgx_lfence();
  258. if(!sgx_is_within_enclave(p_blob, blob_size))
  259. return QE_PARAMETER_ERROR;
  260. return verify_blob_internal(p_blob, blob_size,
  261. p_is_resealed, FALSE, plain_text, NULL);
  262. }
  263. /*
  264. * An internal function used to sign the EPID signature on the quote body.
  265. * Prefix "emp_" means it is a pointer points memory outside enclave.
  266. *
  267. * For quote with SIG-RL
  268. * |--------------------------------------------------------------------|
  269. * |sgx_quote_t|wrap_key_t|iv|payload_size|basic_sig|rl_ver|n2|nrp..|mac|
  270. * |--------------------------------------------------------------------|
  271. * For quote without SIG-RL
  272. * |--------------------------------------------------------------|
  273. * |sgx_quote_t|wrap_key_t|iv|payload_size|basic_sig|rl_ver|n2|mac|
  274. * |--------------------------------------------------------------|
  275. *
  276. * @param p_epid_context[in] Pointer to the EPID context.
  277. * @param plaintext[in] Reference to the plain text part of EPID blob.
  278. * @param p_basename[in] The pointer to basename.
  279. * @param emp_sig_rl_entries[in] The pointer to SIG-RL entries.
  280. * @param p_sig_rl_header[in] The header of SIG-RL, within EPC.
  281. * @param p_sig_rl_signature[in] The ecdsa signature of SIG-RL, within EPC.
  282. * @param p_enclave_report[in] The input isv report.
  283. * @param p_nonce[in] The input nonce.
  284. * @param p_qe_report[out] The output buffer for qe_report.
  285. * @param emp_quote[out] The output buffer for quote.
  286. * @param p_quote_body[in] The quote body in EPC.
  287. * @param sign_size[in] size of the signature.
  288. * @return ae_error_t AE_SUCCESS for success, otherwise for errors.
  289. */
  290. static ae_error_t qe_epid_sign(
  291. MemberCtx *p_epid_context,
  292. const se_plaintext_epid_data_sdk_t& plaintext,
  293. const sgx_basename_t *p_basename,
  294. const SigRlEntry *emp_sig_rl_entries,
  295. se_sig_rl_t *p_sig_rl_header,
  296. sgx_ec256_signature_t *p_sig_rl_signature,
  297. const sgx_report_t *p_enclave_report,
  298. const sgx_quote_nonce_t *p_nonce,
  299. sgx_report_t *p_qe_report,
  300. uint8_t *emp_quote,
  301. const sgx_quote_t *p_quote_body,
  302. uint32_t sign_size)
  303. {
  304. ae_error_t ret = AE_SUCCESS;
  305. IppStatus ipp_ret = ippStsNoErr;
  306. sgx_status_t se_ret = SGX_SUCCESS;
  307. EpidStatus epid_ret = kEpidNoErr;
  308. se_wrap_key_t wrap_key;
  309. BasicSignature basic_sig;
  310. BasicSignature encrypted_basic_sig;
  311. uint8_t aes_iv[QUOTE_IV_SIZE] = {0};
  312. uint8_t aes_key[QE_AES_KEY_SIZE] = {0};
  313. uint8_t aes_tag[SGX_SEAL_TAG_SIZE] = {0};
  314. Ipp8u seeds[QE_OAEP_SEED_SIZE] = {0};
  315. sgx_report_data_t qe_report_data = {{0}};
  316. sgx_target_info_t report_target;
  317. sgx_ec256_public_t ec_pub_key; // little endian
  318. se_ae_ecdsa_hash_t sig_rl_hash = {{0}};
  319. IppECResult ec_result = ippECValid ;
  320. int aes_context_size = 0;
  321. sgx_sha_state_handle_t sha_context = NULL;
  322. sgx_sha_state_handle_t sha_quote_context = NULL;
  323. IppsAES_GCMState *aes_context = NULL;
  324. IppsRSAPublicKeyState *pub_key = NULL;
  325. int pub_key_size = 0;
  326. uint8_t* pub_key_buffer = NULL;
  327. IppsECCPState *p_ecp = NULL;
  328. memset(&wrap_key, 0, sizeof(wrap_key));
  329. memset(&basic_sig, 0, sizeof(basic_sig));
  330. memset(&encrypted_basic_sig, 0, sizeof(encrypted_basic_sig));
  331. memset(&report_target, 0, sizeof(report_target));
  332. memset(&ec_pub_key, 0, sizeof(ec_pub_key));
  333. se_encrypted_sign_t *emp_p = (se_encrypted_sign_t *)
  334. (((sgx_quote_t *)emp_quote)->signature);
  335. uint8_t* emp_nr = NULL;
  336. uint32_t match = FALSE;
  337. /* Sign the quote body and get the basic signature*/
  338. epid_ret = EpidSignBasic(p_epid_context,
  339. (uint8_t *)const_cast<sgx_quote_t *>(p_quote_body),
  340. (uint32_t)QE_QUOTE_BODY_SIZE,
  341. (uint8_t *)const_cast<sgx_basename_t *>(p_basename),
  342. sizeof(*p_basename),
  343. &basic_sig,
  344. NULL);
  345. if(kEpidNoErr != epid_ret)
  346. {
  347. ret = QE_UNEXPECTED_ERROR;
  348. goto CLEANUP;
  349. }
  350. /* Prepare the context for SHA256 of quote. */
  351. if(p_qe_report)
  352. {
  353. se_ret = sgx_sha256_init(&sha_quote_context);
  354. if(SGX_SUCCESS != se_ret)
  355. {
  356. ret = QE_UNEXPECTED_ERROR;
  357. goto CLEANUP;
  358. }
  359. // Update hash for nonce.
  360. se_ret = sgx_sha256_update((uint8_t *)const_cast<sgx_quote_nonce_t *>(p_nonce),
  361. sizeof(*p_nonce),
  362. sha_quote_context);
  363. if(SGX_SUCCESS != se_ret)
  364. {
  365. ret = QE_UNEXPECTED_ERROR;
  366. goto CLEANUP;
  367. }
  368. // Update hash for the first part of quote.
  369. se_ret = sgx_sha256_update((uint8_t *)const_cast<sgx_quote_t *>(p_quote_body),
  370. sizeof(*p_quote_body),
  371. sha_quote_context);
  372. if(SGX_SUCCESS != se_ret)
  373. {
  374. ret = QE_UNEXPECTED_ERROR;
  375. goto CLEANUP;
  376. }
  377. }
  378. /* Prepare the context for SHA256 and start calculate the hash of header
  379. * of SIG-RL. */
  380. if(emp_sig_rl_entries)
  381. {
  382. se_ret = sgx_sha256_init(&sha_context);
  383. if(SGX_SUCCESS != se_ret)
  384. {
  385. ret = QE_UNEXPECTED_ERROR;
  386. goto CLEANUP;
  387. }
  388. /* Calculate the hash of SIG-RL header. */
  389. se_ret = sgx_sha256_update((Ipp8u *)p_sig_rl_header,
  390. (uint32_t)(sizeof(se_sig_rl_t) - sizeof(SigRlEntry)),
  391. sha_context);
  392. if(SGX_SUCCESS != se_ret)
  393. {
  394. ret = QE_UNEXPECTED_ERROR;
  395. goto CLEANUP;
  396. }
  397. }
  398. // Start encrypt the signature.
  399. ipp_ret = ippsAES_GCMGetSize(&aes_context_size);
  400. if(ipp_ret != ippStsNoErr){
  401. ret = QE_UNEXPECTED_ERROR;
  402. goto CLEANUP;
  403. }
  404. aes_context = (IppsAES_GCMState *)malloc(aes_context_size);
  405. if(NULL == aes_context)
  406. {
  407. ret = QE_UNEXPECTED_ERROR;
  408. goto CLEANUP;
  409. }
  410. /* Get the random wrap key */
  411. se_ret = sgx_read_rand(aes_key, sizeof(aes_key));
  412. if(SGX_SUCCESS != se_ret)
  413. {
  414. ret = QE_UNEXPECTED_ERROR;
  415. goto CLEANUP;
  416. }
  417. /* Copy the hash of wrap key into output buffer. */
  418. se_static_assert(sizeof(wrap_key.key_hash) == sizeof(sgx_sha256_hash_t));
  419. se_ret = sgx_sha256_msg(aes_key, sizeof(aes_key),
  420. (sgx_sha256_hash_t *)wrap_key.key_hash);
  421. if(SGX_SUCCESS != se_ret)
  422. {
  423. ret = QE_UNEXPECTED_ERROR;
  424. goto CLEANUP;
  425. }
  426. //Start encrypt the wrap key by RSA IPP algorithm.
  427. ipp_ret = create_rsa_pub_key(sizeof(g_qsdk_pub_key_n),
  428. sizeof(g_qsdk_pub_key_e),
  429. g_qsdk_pub_key_n,
  430. g_qsdk_pub_key_e,
  431. &pub_key);
  432. if(ipp_ret != ippStsNoErr)
  433. {
  434. ret = QE_UNEXPECTED_ERROR;
  435. goto CLEANUP;
  436. }
  437. se_ret = sgx_read_rand(seeds, sizeof(seeds));
  438. if(SGX_SUCCESS != se_ret)
  439. {
  440. ret = QE_UNEXPECTED_ERROR;
  441. goto CLEANUP;
  442. }
  443. ipp_ret = ippsRSA_GetBufferSizePublicKey(&pub_key_size, pub_key);
  444. if (ipp_ret != ippStsNoErr)
  445. {
  446. ret = QE_UNEXPECTED_ERROR;
  447. goto CLEANUP;
  448. }
  449. pub_key_buffer = (uint8_t*)malloc(pub_key_size);
  450. if (pub_key_buffer == NULL)
  451. {
  452. ret = QE_UNEXPECTED_ERROR;
  453. goto CLEANUP;
  454. }
  455. ipp_ret = ippsRSAEncrypt_OAEP(aes_key, sizeof(aes_key),
  456. NULL, 0, seeds,
  457. wrap_key.encrypted_key,
  458. pub_key, IPP_ALG_HASH_SHA256,
  459. pub_key_buffer);
  460. if(ipp_ret != ippStsNoErr)
  461. {
  462. ret = QE_UNEXPECTED_ERROR;
  463. goto CLEANUP;
  464. }
  465. ipp_ret = ippsAES_GCMInit(aes_key,
  466. sizeof(aes_key),
  467. aes_context,
  468. aes_context_size);
  469. memset_s(aes_key, sizeof(aes_key), 0, sizeof(aes_key));
  470. if(ipp_ret != ippStsNoErr)
  471. {
  472. ret = QE_UNEXPECTED_ERROR;
  473. goto CLEANUP;
  474. }
  475. /* Create the random AES IV. */
  476. se_ret = sgx_read_rand(aes_iv, sizeof(aes_iv));
  477. if(SGX_SUCCESS != se_ret)
  478. {
  479. ret = QE_UNEXPECTED_ERROR;
  480. goto CLEANUP;
  481. }
  482. /* Copy the wrap_key_t into output buffer. */
  483. memcpy(&emp_p->wrap_key, &wrap_key, sizeof(wrap_key));
  484. /* Copy the AES IV into output buffer. */
  485. memcpy(&emp_p->iv, aes_iv, sizeof(aes_iv));
  486. /* Copy the AES Blob payload size into output buffer. */
  487. memcpy(&emp_p->payload_size, &sign_size, sizeof(sign_size));
  488. ipp_ret = ippsAES_GCMStart(aes_iv, sizeof(aes_iv), NULL, 0,
  489. aes_context);
  490. if(ipp_ret != ippStsNoErr)
  491. {
  492. ret = QE_UNEXPECTED_ERROR;
  493. goto CLEANUP;
  494. }
  495. /* Encrypt the basic signature. */
  496. ipp_ret = ippsAES_GCMEncrypt((Ipp8u *)&basic_sig,
  497. (uint8_t *)&encrypted_basic_sig,
  498. sizeof(encrypted_basic_sig),
  499. aes_context);
  500. if(ipp_ret != ippStsNoErr)
  501. {
  502. ret = QE_UNEXPECTED_ERROR;
  503. goto CLEANUP;
  504. }
  505. /* Copy the encrypted basic signature into output buffer. */
  506. memcpy(&emp_p->basic_sign, &encrypted_basic_sig,
  507. sizeof(encrypted_basic_sig));
  508. if(p_qe_report)
  509. {
  510. se_ret = sgx_sha256_update((uint8_t *)&wrap_key,
  511. sizeof(wrap_key),
  512. sha_quote_context);
  513. if(SGX_SUCCESS != se_ret)
  514. {
  515. ret = QE_UNEXPECTED_ERROR;
  516. goto CLEANUP;
  517. }
  518. se_ret = sgx_sha256_update(aes_iv,
  519. sizeof(aes_iv),
  520. sha_quote_context);
  521. if(SGX_SUCCESS != se_ret)
  522. {
  523. ret = QE_UNEXPECTED_ERROR;
  524. goto CLEANUP;
  525. }
  526. se_ret = sgx_sha256_update((uint8_t *)&sign_size,
  527. sizeof(sign_size),
  528. sha_quote_context);
  529. if(SGX_SUCCESS != se_ret)
  530. {
  531. ret = QE_UNEXPECTED_ERROR;
  532. goto CLEANUP;
  533. }
  534. se_ret = sgx_sha256_update((uint8_t *)&encrypted_basic_sig,
  535. sizeof(encrypted_basic_sig),
  536. sha_quote_context);
  537. if(SGX_SUCCESS != se_ret)
  538. {
  539. ret = QE_UNEXPECTED_ERROR;
  540. goto CLEANUP;
  541. }
  542. }
  543. /* Start process the SIG-RL. */
  544. if(emp_sig_rl_entries)
  545. {
  546. unsigned int entry_count = 0;
  547. unsigned int i = 0;
  548. RLver_t encrypted_rl_ver = {{0}};
  549. RLCount encrypted_n2 = {{0}};
  550. entry_count = lv_ntohl(p_sig_rl_header->sig_rl.n2);//entry count for big endian to little endian
  551. // Continue encrypt the output
  552. ipp_ret = ippsAES_GCMEncrypt((Ipp8u *)&(p_sig_rl_header->sig_rl.version),
  553. (Ipp8u *)&encrypted_rl_ver,
  554. sizeof(encrypted_rl_ver),
  555. aes_context);
  556. if(ipp_ret != ippStsNoErr)
  557. {
  558. ret = QE_UNEXPECTED_ERROR;
  559. goto CLEANUP;
  560. }
  561. ipp_ret = ippsAES_GCMEncrypt((Ipp8u *)&(p_sig_rl_header->sig_rl.n2),
  562. (Ipp8u *)&encrypted_n2,
  563. sizeof(encrypted_n2),
  564. aes_context);
  565. if(ipp_ret != ippStsNoErr)
  566. {
  567. ret = QE_UNEXPECTED_ERROR;
  568. goto CLEANUP;
  569. }
  570. memcpy(&(emp_p->rl_ver), &encrypted_rl_ver,
  571. sizeof(encrypted_rl_ver));
  572. memcpy(&(emp_p->rl_num), &encrypted_n2,
  573. sizeof(encrypted_n2));
  574. if(p_qe_report)
  575. {
  576. se_ret = sgx_sha256_update((uint8_t *)&encrypted_rl_ver,
  577. sizeof(encrypted_rl_ver),
  578. sha_quote_context);
  579. if(SGX_SUCCESS != se_ret)
  580. {
  581. ret = QE_UNEXPECTED_ERROR;
  582. goto CLEANUP;
  583. }
  584. se_ret = sgx_sha256_update((uint8_t *)&encrypted_n2,
  585. sizeof(encrypted_n2),
  586. sha_quote_context);
  587. if(SGX_SUCCESS != se_ret)
  588. {
  589. ret = QE_UNEXPECTED_ERROR;
  590. goto CLEANUP;
  591. }
  592. }
  593. /* Start process the SIG-RL entries one by one. */
  594. emp_nr = emp_p->nrp_mac;
  595. for (i = 0; i < entry_count; i++, emp_nr += sizeof(NrProof))
  596. {
  597. /* Generate non-revoke prove one by one. */
  598. SigRlEntry entry;
  599. NrProof temp_nr;
  600. NrProof encrypted_temp_nr;
  601. memcpy(&entry, emp_sig_rl_entries + i, sizeof(entry));
  602. memset_s(&temp_nr, sizeof(temp_nr), 0, sizeof(temp_nr));
  603. memset_s(&encrypted_temp_nr, sizeof(encrypted_temp_nr), 0, sizeof(encrypted_temp_nr));
  604. epid_ret = EpidNrProve(p_epid_context,
  605. (uint8_t *)const_cast<sgx_quote_t *>(p_quote_body),
  606. (uint32_t)QE_QUOTE_BODY_SIZE,
  607. (uint8_t *)const_cast<sgx_basename_t *>(p_basename),
  608. sizeof(*p_basename),
  609. &basic_sig, // Basic signature with 'b' and 'k' in it
  610. &entry, //Single entry in SigRl composed of 'b' and 'k'
  611. &temp_nr); // The generated non-revoked proof
  612. if(kEpidNoErr != epid_ret)
  613. {
  614. if(kEpidSigRevokedInSigRl == epid_ret)
  615. match = TRUE;
  616. else
  617. {
  618. ret = QE_UNEXPECTED_ERROR;
  619. goto CLEANUP;
  620. }
  621. }
  622. /* Update the hash of SIG-RL */
  623. se_ret = sgx_sha256_update((Ipp8u *)&entry,
  624. sizeof(entry), sha_context);
  625. if(SGX_SUCCESS != se_ret)
  626. {
  627. ret = QE_UNEXPECTED_ERROR;
  628. goto CLEANUP;
  629. }
  630. ipp_ret = ippsAES_GCMEncrypt((Ipp8u *)&temp_nr,
  631. (Ipp8u *)&encrypted_temp_nr,
  632. sizeof(encrypted_temp_nr),
  633. aes_context);
  634. if(ipp_ret != ippStsNoErr)
  635. {
  636. ret = QE_UNEXPECTED_ERROR;
  637. goto CLEANUP;
  638. }
  639. memcpy(emp_nr, &encrypted_temp_nr, sizeof(encrypted_temp_nr));
  640. if(p_qe_report)
  641. {
  642. se_ret = sgx_sha256_update((uint8_t *)&encrypted_temp_nr,
  643. sizeof(encrypted_temp_nr),
  644. sha_quote_context);
  645. if(SGX_SUCCESS != se_ret)
  646. {
  647. ret = QE_UNEXPECTED_ERROR;
  648. goto CLEANUP;
  649. }
  650. }
  651. }
  652. /* Get the final hash of the whole SIG-RL. */
  653. se_ret = sgx_sha256_get_hash(sha_context,
  654. (sgx_sha256_hash_t *)&sig_rl_hash.hash);
  655. if(SGX_SUCCESS != se_ret)
  656. {
  657. ret = QE_UNEXPECTED_ERROR;
  658. goto CLEANUP;
  659. }
  660. /* Verify the integraty of SIG-RL by check ECDSA signature. */
  661. ipp_ret = new_std_256_ecp(&p_ecp);
  662. if(ipp_ret != ippStsNoErr)
  663. {
  664. ret = QE_UNEXPECTED_ERROR;
  665. goto CLEANUP;
  666. }
  667. se_static_assert(sizeof(ec_pub_key) == sizeof(plaintext.epid_sk));
  668. // Both plaintext.epid_sk and ec_pub_key are little endian
  669. memcpy(&ec_pub_key, plaintext.epid_sk, sizeof(ec_pub_key));
  670. // se_ecdsa_verify_internal will take ec_pub_key as little endian
  671. se_ret = se_ecdsa_verify_internal(p_ecp,
  672. &ec_pub_key,
  673. p_sig_rl_signature,
  674. &sig_rl_hash,
  675. &ec_result);
  676. if(SGX_SUCCESS != se_ret)
  677. {
  678. ret = QE_UNEXPECTED_ERROR;
  679. goto CLEANUP;
  680. }
  681. else if(ippECValid != ec_result)
  682. {
  683. ret = QE_SIGRL_ERROR;
  684. goto CLEANUP;
  685. }
  686. else if(match)
  687. {
  688. ret = QE_REVOKED_ERROR;
  689. goto CLEANUP;
  690. }
  691. }
  692. else
  693. {
  694. se_static_assert(sizeof(emp_p->rl_ver) == sizeof(RLver_t));
  695. se_static_assert(sizeof(emp_p->rl_num) == sizeof(RLCount));
  696. uint8_t temp_buf[sizeof(RLver_t) + sizeof(RLCount)] = {0};
  697. uint8_t encrypted_temp_buf[sizeof(temp_buf)] = {0};
  698. ipp_ret = ippsAES_GCMEncrypt(temp_buf,
  699. (Ipp8u *)&encrypted_temp_buf,
  700. sizeof(encrypted_temp_buf),
  701. aes_context);
  702. if(ipp_ret != ippStsNoErr)
  703. {
  704. ret = QE_UNEXPECTED_ERROR;
  705. goto CLEANUP;
  706. }
  707. /* This will copy both encrypted rl_ver and encrypted rl_num into
  708. Output buffer. */
  709. memcpy(&emp_p->rl_ver, &encrypted_temp_buf,
  710. sizeof(encrypted_temp_buf));
  711. if(p_qe_report)
  712. {
  713. se_ret = sgx_sha256_update((uint8_t *)&encrypted_temp_buf,
  714. sizeof(encrypted_temp_buf),
  715. sha_quote_context);
  716. if(SGX_SUCCESS != se_ret)
  717. {
  718. ret = QE_UNEXPECTED_ERROR;
  719. goto CLEANUP;
  720. }
  721. }
  722. }
  723. ipp_ret = ippsAES_GCMGetTag(aes_tag, sizeof(aes_tag), aes_context);
  724. if(ipp_ret != ippStsNoErr)
  725. {
  726. ret = QE_UNEXPECTED_ERROR;
  727. goto CLEANUP;
  728. }
  729. memcpy((uint8_t *)&(emp_p->basic_sign) + sign_size, &aes_tag,
  730. sizeof(aes_tag));
  731. if(p_qe_report)
  732. {
  733. se_ret = sgx_sha256_update(aes_tag, sizeof(aes_tag),
  734. sha_quote_context);
  735. if(SGX_SUCCESS != se_ret)
  736. {
  737. ret = QE_UNEXPECTED_ERROR;
  738. goto CLEANUP;
  739. }
  740. se_ret = sgx_sha256_get_hash(sha_quote_context,
  741. (sgx_sha256_hash_t *)&qe_report_data);
  742. if(SGX_SUCCESS != se_ret)
  743. {
  744. ret = QE_UNEXPECTED_ERROR;
  745. goto CLEANUP;
  746. }
  747. memcpy(&(report_target.attributes),
  748. &(((const sgx_report_t *)p_enclave_report)->body.attributes),
  749. sizeof(report_target.attributes));
  750. memcpy(&(report_target.mr_enclave),
  751. &(((const sgx_report_t *)p_enclave_report)->body.mr_enclave),
  752. sizeof(report_target.mr_enclave));
  753. memcpy(&(report_target.misc_select),
  754. &(((const sgx_report_t *)p_enclave_report)->body.misc_select),
  755. sizeof(report_target.misc_select));
  756. se_ret = sgx_create_report(&report_target, &qe_report_data, p_qe_report);
  757. if(SGX_SUCCESS != se_ret)
  758. {
  759. ret = QE_PARAMETER_ERROR;
  760. goto CLEANUP;
  761. }
  762. }
  763. CLEANUP:
  764. memset_s(aes_key, sizeof(aes_key), 0, sizeof(aes_key));
  765. sgx_sha256_close(sha_context);
  766. sgx_sha256_close(sha_quote_context);
  767. if(aes_context)
  768. free(aes_context);
  769. if(pub_key)
  770. secure_free_rsa_pub_key(sizeof(plaintext.qsdk_mod),
  771. sizeof(plaintext.qsdk_exp), pub_key);
  772. if(pub_key_buffer)
  773. free(pub_key_buffer);
  774. secure_free_std_256_ecp(p_ecp);
  775. return ret;
  776. }
  777. /*
  778. * External function used to get quote. Prefix "emp_" means it is a pointer
  779. * points memory outside enclave.
  780. *
  781. * @param p_blob[in, out] Pointer to the EPID Blob.
  782. * @param blob_size[in] The size of EPID Blob, in bytes.
  783. * @param p_enclave_report[in] The application enclave's report.
  784. * @param quote_type[in] The type of quote, random based or name based.
  785. * @param p_spid[in] Pointer to SPID.
  786. * @param p_nonce[in] Pointer to nonce.
  787. * @param emp_sig_rl[in] Pointer to SIG-RL.
  788. * @param sig_rl_size[in] The size of SIG-RL, in bytes.
  789. * @param p_qe_report[out] Pointer to QE report, which reportdata is
  790. * sha256(nonce || quote)
  791. * @param emp_quote[out] Pointer to the output buffer for quote.
  792. * @param quote_size[in] The size of emp_quote, in bytes.
  793. * @param pce_isvsvn[in] The ISVSVN of PCE.
  794. * @return ae_error_t AE_SUCCESS for success, otherwise for errors.
  795. */
  796. uint32_t get_quote(
  797. uint8_t *p_blob,
  798. uint32_t blob_size,
  799. const sgx_report_t *p_enclave_report,
  800. sgx_quote_sign_type_t quote_type,
  801. const sgx_spid_t *p_spid,
  802. const sgx_quote_nonce_t *p_nonce,
  803. const uint8_t *emp_sig_rl,
  804. uint32_t sig_rl_size,
  805. sgx_report_t *p_qe_report,
  806. uint8_t *emp_quote,
  807. uint32_t quote_size,
  808. sgx_isv_svn_t pce_isvsvn)
  809. {
  810. ae_error_t ret = AE_SUCCESS;
  811. EpidStatus epid_ret = kEpidNoErr;
  812. MemberCtx *p_epid_context = NULL;
  813. sgx_quote_t quote_body;
  814. uint8_t is_resealed = 0;
  815. sgx_basename_t basename = {{0}};
  816. uint64_t sign_size = 0;
  817. sgx_status_t se_ret = SGX_SUCCESS;
  818. sgx_report_t qe_report;
  819. uint64_t required_buffer_size = 0;
  820. se_sig_rl_t sig_rl_header;
  821. se_plaintext_epid_data_sdk_t plaintext;
  822. sgx_ec256_signature_t ec_signature;
  823. memset(&quote_body, 0, sizeof(quote_body));
  824. memset(&sig_rl_header, 0, sizeof(sig_rl_header));
  825. memset(&plaintext, 0, sizeof(plaintext));
  826. memset(&ec_signature, 0, sizeof(ec_signature));
  827. /* Actually, some cases here will be checked with code generated by
  828. edger8r. Here we just want to defend in depth. */
  829. if((NULL == p_blob)
  830. || (NULL == p_enclave_report)
  831. || (NULL == p_spid)
  832. || (NULL == emp_quote)
  833. || (!quote_size)
  834. || ((NULL != emp_sig_rl) && (sig_rl_size < sizeof(se_sig_rl_t)
  835. + 2 * SE_ECDSA_SIGN_SIZE))
  836. //
  837. // this size check could mispredict and cause us to
  838. // overflow, but we have an lfence below
  839. // that's safe to use for this case
  840. //
  841. || ((NULL == emp_sig_rl) && (sig_rl_size != 0)))
  842. return QE_PARAMETER_ERROR;
  843. if(SGX_TRUSTED_EPID_BLOB_SIZE_SDK != blob_size)
  844. return QE_PARAMETER_ERROR;
  845. //
  846. // this could mispredict and cause us to
  847. // overflow, but we have an lfence below
  848. // that's safe to use for this case
  849. //
  850. if(SGX_LINKABLE_SIGNATURE != quote_type
  851. && SGX_UNLINKABLE_SIGNATURE != quote_type)
  852. return QE_PARAMETER_ERROR;
  853. if(!p_nonce && p_qe_report)
  854. return QE_PARAMETER_ERROR;
  855. if(p_nonce && !p_qe_report)
  856. return QE_PARAMETER_ERROR;
  857. /* To reduce the memory footprint of QE, we should leave sig_rl and
  858. quote buffer outside enclave. */
  859. if(!sgx_is_outside_enclave(emp_sig_rl, sig_rl_size))
  860. return QE_PARAMETER_ERROR;
  861. //
  862. // for user_check SigRL input
  863. // based on quote_size input parameter
  864. //
  865. sgx_lfence();
  866. if(!sgx_is_outside_enclave(emp_quote, quote_size))
  867. return QE_PARAMETER_ERROR;
  868. /* Check whether p_blob is copied into EPC. If we want to reduce the
  869. memory usage, maybe we can leave the p_blob outside EPC. */
  870. if(!sgx_is_within_enclave(p_blob, blob_size))
  871. return QE_PARAMETER_ERROR;
  872. if(!sgx_is_within_enclave(p_enclave_report, sizeof(*p_enclave_report)))
  873. return QE_PARAMETER_ERROR;
  874. if(!sgx_is_within_enclave(p_spid, sizeof(*p_spid)))
  875. return QE_PARAMETER_ERROR;
  876. /* If the code reach here, if p_nonce is NULL, then p_qe_report will be
  877. NULL also. So we only check p_nonce here.*/
  878. if(p_nonce)
  879. {
  880. /* Actually Edger8r will alloc the buffer within EPC, this is just kind
  881. of defense in depth. */
  882. if(!sgx_is_within_enclave(p_nonce, sizeof(*p_nonce)))
  883. return QE_PARAMETER_ERROR;
  884. if(!sgx_is_within_enclave(p_qe_report, sizeof(*p_qe_report)))
  885. return QE_PARAMETER_ERROR;
  886. }
  887. /* Verify the input report. */
  888. if(SGX_SUCCESS != sgx_verify_report(p_enclave_report))
  889. return QE_PARAMETER_ERROR;
  890. /* Verify EPID p_blob and create the context */
  891. ret = verify_blob_internal(p_blob,
  892. blob_size,
  893. &is_resealed,
  894. TRUE,
  895. plaintext,
  896. &p_epid_context);
  897. if(AE_SUCCESS != ret)
  898. goto CLEANUP;
  899. /* If SIG-RL is provided, we should check its size. */
  900. if(emp_sig_rl)
  901. {
  902. uint64_t temp_size = 0;
  903. uint64_t n2 = 0;
  904. memcpy(&sig_rl_header, emp_sig_rl, sizeof(sig_rl_header));
  905. if(sig_rl_header.protocol_version != SE_EPID_SIG_RL_VERSION)
  906. {
  907. ret = QE_PARAMETER_ERROR;
  908. goto CLEANUP;
  909. }
  910. if(sig_rl_header.epid_identifier != SE_EPID_SIG_RL_ID)
  911. {
  912. ret = QE_PARAMETER_ERROR;
  913. goto CLEANUP;
  914. }
  915. if(memcmp(&sig_rl_header.sig_rl.gid, &plaintext.epid_group_cert.gid,
  916. sizeof(sig_rl_header.sig_rl.gid)))
  917. {
  918. ret = QE_PARAMETER_ERROR;
  919. goto CLEANUP;
  920. }
  921. temp_size = se_get_sig_rl_size(&sig_rl_header);
  922. if(temp_size != sig_rl_size)
  923. {
  924. ret = QE_PARAMETER_ERROR;
  925. goto CLEANUP;
  926. }
  927. se_static_assert(sizeof(ec_signature.x) == SE_ECDSA_SIGN_SIZE);
  928. se_static_assert(sizeof(ec_signature.y) == SE_ECDSA_SIGN_SIZE);
  929. memcpy(ec_signature.x,
  930. emp_sig_rl + sig_rl_size - (SE_ECDSA_SIGN_SIZE * 2),
  931. sizeof(ec_signature.x));
  932. SWAP_ENDIAN_32B(ec_signature.x);
  933. memcpy(ec_signature.y,
  934. emp_sig_rl + sig_rl_size - (SE_ECDSA_SIGN_SIZE * 1),
  935. sizeof(ec_signature.y));
  936. SWAP_ENDIAN_32B(ec_signature.y);
  937. n2 = SWAP_4BYTES(sig_rl_header.sig_rl.n2);
  938. temp_size = sizeof(EpidSignature) - sizeof(NrProof)
  939. + n2 * sizeof(NrProof);
  940. if(temp_size > UINT32_MAX)
  941. {
  942. ret = QE_PARAMETER_ERROR;
  943. goto CLEANUP;
  944. }
  945. sign_size = temp_size;
  946. }
  947. else
  948. {
  949. sign_size = sizeof(BasicSignature)
  950. + sizeof(uint32_t) // rl_ver
  951. + sizeof(uint32_t); // rl_num
  952. }
  953. /* Verify sizeof basename is large enough and it should always be true*/
  954. se_static_assert(sizeof(basename) > sizeof(*p_spid));
  955. /* Because basename has already been zeroed,
  956. so we don't need to concatenating with 0s.*/
  957. memcpy(&basename, p_spid, sizeof(*p_spid));
  958. if(SGX_UNLINKABLE_SIGNATURE == quote_type)
  959. {
  960. uint8_t *p = (uint8_t *)&basename + sizeof(*p_spid);
  961. se_ret = sgx_read_rand(p, sizeof(basename) - sizeof(*p_spid));
  962. if(SGX_SUCCESS != se_ret)
  963. {
  964. ret = QE_UNEXPECTED_ERROR;
  965. goto CLEANUP;
  966. }
  967. }
  968. epid_ret = EpidRegisterBasename(p_epid_context, (uint8_t *)&basename,
  969. sizeof(basename));
  970. if(kEpidNoErr != epid_ret)
  971. {
  972. ret = QE_UNEXPECTED_ERROR;
  973. goto CLEANUP;
  974. }
  975. required_buffer_size = SE_QUOTE_LENGTH_WITHOUT_SIG + sign_size;
  976. /* We should make sure the buffer size is big enough. */
  977. if(quote_size < required_buffer_size)
  978. {
  979. ret = QE_PARAMETER_ERROR;
  980. goto CLEANUP;
  981. }
  982. //
  983. // for user_check SigRL input
  984. // based on n2 field in SigRL
  985. //
  986. sgx_lfence();
  987. /* Copy the data in the report into quote body. */
  988. memset(emp_quote, 0, quote_size);
  989. quote_body.version = QE_QUOTE_VERSION;
  990. quote_body.sign_type = (uint16_t)quote_type;
  991. quote_body.pce_svn = pce_isvsvn; // Both are little endian
  992. quote_body.xeid = plaintext.xeid; // Both are little endian
  993. se_static_assert(sizeof(plaintext.epid_group_cert.gid) == sizeof(OctStr32));
  994. se_static_assert(sizeof(quote_body.epid_group_id) == sizeof(uint32_t));
  995. ((uint8_t *)(&quote_body.epid_group_id))[0] = plaintext.epid_group_cert.gid.data[3];
  996. ((uint8_t *)(&quote_body.epid_group_id))[1] = plaintext.epid_group_cert.gid.data[2];
  997. ((uint8_t *)(&quote_body.epid_group_id))[2] = plaintext.epid_group_cert.gid.data[1];
  998. ((uint8_t *)(&quote_body.epid_group_id))[3] = plaintext.epid_group_cert.gid.data[0];
  999. memcpy(&quote_body.basename, &basename, sizeof(quote_body.basename));
  1000. // Get the QE's report.
  1001. se_ret = sgx_create_report(NULL, NULL, &qe_report);
  1002. if(SGX_SUCCESS != se_ret)
  1003. {
  1004. ret = QE_PARAMETER_ERROR;
  1005. goto CLEANUP;
  1006. }
  1007. // Copy QE's security version in to Quote body.
  1008. quote_body.qe_svn = qe_report.body.isv_svn;
  1009. // Copy the incoming report into Quote body.
  1010. memcpy(&quote_body.report_body, &(p_enclave_report->body),
  1011. sizeof(quote_body.report_body));
  1012. /* Because required_buffer_size is larger than signature_len, so if we
  1013. get here, then no integer overflow will ocur. */
  1014. quote_body.signature_len = (uint32_t)(sizeof(se_wrap_key_t)
  1015. + QUOTE_IV_SIZE
  1016. + sizeof(uint32_t)
  1017. + sign_size
  1018. + sizeof(sgx_mac_t));
  1019. /* Make the signature. */
  1020. ret = qe_epid_sign(p_epid_context,
  1021. plaintext,
  1022. &basename,
  1023. emp_sig_rl ? ((const se_sig_rl_t *)emp_sig_rl)->sig_rl.bk
  1024. : NULL,
  1025. &sig_rl_header,
  1026. &ec_signature,
  1027. p_enclave_report,
  1028. p_nonce,
  1029. p_qe_report,
  1030. emp_quote,
  1031. &quote_body,
  1032. (uint32_t)sign_size);
  1033. if(AE_SUCCESS != ret)
  1034. {
  1035. // Only need to clean the buffer after the fixed length part.
  1036. memset_s(emp_quote + sizeof(sgx_quote_t), quote_size - sizeof(sgx_quote_t),
  1037. 0, quote_size - sizeof(sgx_quote_t));
  1038. goto CLEANUP;
  1039. }
  1040. memcpy(emp_quote, &quote_body, sizeof(sgx_quote_t));
  1041. CLEANUP:
  1042. if(p_epid_context)
  1043. epid_member_delete(&p_epid_context);
  1044. return ret;
  1045. }