t_long_term_pairing.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  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 <cstddef>
  32. #include "sgx_trts.h"
  33. #include "sgx_utils.h"
  34. #include "sgx_tseal.h"
  35. #include "sgx_lfence.h"
  36. #include "t_long_term_pairing.h"
  37. #include "prepare_hash_sha256.h"
  38. #include "pse_pr_inc.h"
  39. #include "pse_pr_common.h"
  40. #include "pse_pr_sigma_1_1_defs.h"
  41. #include "le2be_macros.h"
  42. #include "t_pairing_blob.h"
  43. #include "epid/common/1.1/types.h"
  44. #include "Keys.h"
  45. #include <string.h>
  46. #include "X509Parser.h"
  47. #include "Epid11_rl.h"
  48. #include "sgx_tcrypto.h"
  49. // Each of the following definitions is larger than
  50. // should ever be encountered.
  51. // MAX possible should be 19280 based on 150 SIGRL entries
  52. #define MAX_ALLOWED_SIGRL_SIZE 20480
  53. #define MAX_ALLOWED_OCSP_SIZE 8192
  54. #define MAX_ALLOWED_CERT_SIZE 8192
  55. // MAX of S2 is defined larger than we should ever encounter
  56. #define MAX_ALLOWED_S2_SIZE 35840
  57. // MAX possible should be 3280 based on 100 PRIVRL entries
  58. #define MAX_ALLOWED_PRIVRL_SIZE 4096
  59. // MAX of S3 is defined larger than we should ever encounter
  60. #define MAX_ALLOWED_S3_SIZE 30720
  61. static ae_error_t map_GenM7_error_for_return(ae_error_t status)
  62. {
  63. #if !defined(_DEBUG)
  64. // Switch to limit errors returned when building for RELEASE
  65. switch (status)
  66. {
  67. case AE_SUCCESS: break;
  68. case PSE_PR_INSUFFICIENT_MEMORY_ERROR:
  69. case PSE_PAIRING_BLOB_UNSEALING_ERROR:
  70. break;
  71. default:
  72. status = AE_FAILURE;
  73. break;
  74. }
  75. #endif
  76. return status;
  77. }
  78. static ae_error_t map_VerifyM8_error_for_return(ae_error_t status)
  79. {
  80. #if !defined(_DEBUG)
  81. // Switch to limit errors returned when building for RELEASE
  82. switch (status)
  83. {
  84. case AE_SUCCESS: break;
  85. case PSE_PR_INSUFFICIENT_MEMORY_ERROR: break;
  86. case PSE_PR_PCH_EPID_NO_MEMORY_ERR:
  87. status = PSE_PR_INSUFFICIENT_MEMORY_ERROR;
  88. break;
  89. case PSE_PR_PCH_EPID_SIG_REVOKED_IN_GROUPRL: break;
  90. default:
  91. status = AE_FAILURE;
  92. break;
  93. }
  94. #else
  95. switch (status)
  96. {
  97. case PSE_PR_PCH_EPID_OUTOFMEMORY:
  98. status = PSE_PR_INSUFFICIENT_MEMORY_ERROR;
  99. break;
  100. }
  101. #endif
  102. return status;
  103. }
  104. // GUID format is DWORD-WORD-WORD-BYTES ARRAY(8)
  105. // Current PSDA applet ID is cbede6f9-6ce4-439c-a1c7-6e2087786616
  106. static const uint8_t PSDA_APPLET_ID[16] = {0xf9, 0xe6, 0xed, 0xcb, 0xe4, 0x6c, 0x9c, 0x43, 0xa1, 0xc7, 0x6e, 0x20, 0x87, 0x78, 0x66, 0x16};
  107. //extern void OutputOctets(const char* pMsg, const void* pData, size_t nData);
  108. TEpidSigma11Verifier::TEpidSigma11Verifier()
  109. {
  110. m_gid = 0;
  111. m_pSigRL = NULL;
  112. m_nSigRL = 0;
  113. m_nSigRLVersion = 0;
  114. m_nPrivRLVersion = 0;
  115. m_nDalAppletVersion = 0;
  116. memset(m_pairingID, 0, sizeof(m_pairingID));
  117. memset(m_pairingNonce, 0, sizeof(m_pairingNonce));
  118. m_nextState = STATE_GENM7;
  119. }
  120. TEpidSigma11Verifier::~TEpidSigma11Verifier(void)
  121. {
  122. if (m_pSigRL)
  123. {
  124. delete[] m_pSigRL;
  125. m_pSigRL = NULL;
  126. }
  127. m_nSigRL = 0;
  128. // Defense-in-depth: clear class members that contain Enclave secrets
  129. memset_s(m_pairingID, sizeof(m_pairingID), 0, sizeof(m_pairingID));
  130. memset_s(m_pairingNonce, sizeof(m_pairingNonce), 0, sizeof(m_pairingNonce));
  131. memset_s(m_verifierPrivateKey, sizeof(m_verifierPrivateKey), 0, sizeof(m_verifierPrivateKey));
  132. }
  133. bool TEpidSigma11Verifier::get_sigRL_info(const EPID11_SIG_RL* pSigRL, uint32_t& sigRL_entries, uint32_t& sigRL_size)
  134. {
  135. if (NULL == pSigRL)
  136. {
  137. // null sigRL is acceptable
  138. sigRL_entries = 0;
  139. sigRL_size = 0;
  140. return true;
  141. }
  142. uint32_t entries = 0;
  143. memcpy(&entries, pSigRL->entries, sizeof(entries));
  144. entries = SwapEndian_DW(entries);
  145. if (entries > MAX_SIGRL_ENTRIES) // invalid sigRL
  146. return false;
  147. sigRL_entries = entries;
  148. sigRL_size = (uint32_t)(sizeof(EPID11_SIG_RL) + (sigRL_entries * EPID11_SIG_RL_ENTRY_SIZE) + EPID11_SIG_RL_SIGNATURE_SIZE);
  149. return true;
  150. }
  151. bool TEpidSigma11Verifier::get_privRL_info(const EPID11_PRIV_RL* pPrivRL, uint32_t& privRL_entries, uint32_t& privRL_size)
  152. {
  153. if (NULL == pPrivRL)
  154. {
  155. // null privRL is acceptable
  156. privRL_entries = 0;
  157. privRL_size = 0;
  158. return true;
  159. }
  160. uint32_t entries = 0;
  161. memcpy(&entries, pPrivRL->entries, sizeof(entries));
  162. entries = SwapEndian_DW(entries);
  163. if (entries > MAX_PRIVRL_ENTRIES) // invalid privRL
  164. return false;
  165. privRL_entries = entries;
  166. privRL_size = (uint32_t)(sizeof(EPID11_PRIV_RL) + (privRL_entries * EPID11_PRIV_RL_ENTRY_SIZE) + EPID11_PRIV_RL_SIGNATURE_SIZE);
  167. return true;
  168. }
  169. //****************************************************************************
  170. //****************************************************************************
  171. //****************************************************************************
  172. // FLOW
  173. // Verifier Prover Intel Server
  174. // uRequestS1FromME |--M1: Start Pairing->| |
  175. // |<-M2: SIGMA S1-------| |
  176. // uGetR2 | | |
  177. // | | |
  178. // uLoadPairingBlob | | |
  179. // | | |
  180. // uGetSigRLFromServer |--M3: GID_cse || R2----------------->|
  181. // |<-M4: Sig_is(RL_cse || R2)-----------|
  182. // uGetOCSPResponseFromServer |--M5: OCSPReq----------------------->|
  183. // |<-M6: OCSPResp-----------------------|
  184. // uCheckOCSPResponseForExpiration | | |
  185. // | | |
  186. // tGenM7 (enclave call) Send S1, Receive S2
  187. // | | |
  188. // uExchangeS2AndS3WithME |--M7: SIGMA S2------>| |
  189. // |<-M8: SIGMA S3-------| |
  190. // uGetGroupIdFromME | | |
  191. // | | |
  192. // tVerifyM8 (enclave call) Send S3, Receive updated pairing blob
  193. // | | |
  194. // uSavePairingBlob | | |
  195. ae_error_t TEpidSigma11Verifier::GenM7
  196. (
  197. /*in */ const SIGMA_S1_MESSAGE* pS1,
  198. /*in */ const EPID11_SIG_RL* pSigRL,
  199. /*in */ uint32_t nTotalLen_SigRL,
  200. /*in */ const UINT8* pOcspResp,
  201. /*in */ UINT32 nLen_OcspResp,
  202. /*in */ const UINT8* pVerifierCert,
  203. /*in */ UINT32 nLen_VerifierCert,
  204. /*in */ const pairing_blob_t* pPairingBlob,
  205. /*in */ UINT32 nMax_S2,
  206. /*out*/ SIGMA_S2_MESSAGE* pS2,
  207. /*out*/ UINT32* pnLen_S2
  208. )
  209. {
  210. ae_error_t status = AE_FAILURE;
  211. bool bResult;
  212. pairing_data_t pairing_data;
  213. memset(&pairing_data, 0, sizeof(pairing_data));
  214. sgx_ecc_state_handle_t sigma_ecc_handle = NULL;
  215. do
  216. {
  217. if (pSigRL != NULL)
  218. {
  219. BREAK_IF_TRUE((nTotalLen_SigRL < sizeof(EPID11_SIG_RL)), status, PSE_PR_PARAMETER_ERROR);
  220. }
  221. //
  222. // stop speculation in case undersized SigRL (where
  223. // access of header would overflow)
  224. //
  225. sgx_lfence();
  226. ae_error_t tmp_status;
  227. // sigRL_size allows for the sigRL header, array of RL entries, and signature at the end
  228. uint32_t sigRL_entries = 0;
  229. uint32_t sigRL_size = 0;
  230. bResult = TEpidSigma11Verifier::get_sigRL_info(pSigRL, sigRL_entries, sigRL_size);
  231. BREAK_IF_FALSE((bResult), status, PSE_PR_BAD_POINTER_ERROR);
  232. BREAK_IF_TRUE((nTotalLen_SigRL < sigRL_size), status, PSE_PR_PARAMETER_ERROR);
  233. // sigRL_size is based on number of entries, which is basically
  234. // an input to the enclave
  235. //
  236. sgx_lfence();
  237. BREAK_IF_TRUE((STATE_GENM7 != m_nextState), status, PSE_PR_CALL_ORDER_ERROR);
  238. //*********************************************************************
  239. // Validate pointers and sizes
  240. //*********************************************************************
  241. BREAK_IF_TRUE((NULL == pS1), status, PSE_PR_BAD_POINTER_ERROR);
  242. // SigRL is allowed to be NULL and will be checked in ValidateSigRL()
  243. BREAK_IF_TRUE((nLen_OcspResp > 0 && NULL == pOcspResp), status, PSE_PR_BAD_POINTER_ERROR);
  244. BREAK_IF_TRUE((NULL == pVerifierCert), status, PSE_PR_BAD_POINTER_ERROR);
  245. BREAK_IF_TRUE((NULL == pPairingBlob), status, PSE_PR_BAD_POINTER_ERROR);
  246. BREAK_IF_TRUE((nLen_VerifierCert > MAX_ALLOWED_CERT_SIZE), status, PSE_PR_PARAMETER_ERROR);
  247. BREAK_IF_TRUE((sigRL_size > MAX_ALLOWED_SIGRL_SIZE), status, PSE_PR_PARAMETER_ERROR);
  248. BREAK_IF_TRUE((nLen_OcspResp > MAX_ALLOWED_OCSP_SIZE), status, PSE_PR_PARAMETER_ERROR);
  249. uint32_t nNeededBytesForS2 = ::NeededBytesForS2(nLen_VerifierCert, sigRL_size, nLen_OcspResp);
  250. BREAK_IF_TRUE((nNeededBytesForS2 > MAX_ALLOWED_S2_SIZE), status, PSE_PR_PARAMETER_ERROR);
  251. BREAK_IF_TRUE((NULL == pS2 || NULL == pnLen_S2 || nMax_S2 < nNeededBytesForS2),
  252. status, PSE_PR_PARAMETER_ERROR);
  253. //*********************************************************************
  254. // Start SIGMA processing of S1 and generate S2
  255. //*********************************************************************
  256. //*********************************************************************
  257. // Extract components of Msg S1
  258. // g^a || GID || OCSPReq
  259. //*********************************************************************
  260. m_sigmaAlg.set_remote_pub_key_ga_be((Ipp8u*)pS1->Ga);
  261. memcpy(&m_gid, &pS1->Gid, sizeof(SAFEID_GID));
  262. //*********************************************************************
  263. // Choose random value 'b' as ephemeral DH private key
  264. // Compute 'g^b' as ephemeral DH public key
  265. //*********************************************************************
  266. sgx_status_t sgx_status = sgx_ecc256_open_context(&sigma_ecc_handle);
  267. BREAK_IF_TRUE((SGX_ERROR_OUT_OF_MEMORY == sgx_status), status, PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  268. BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_KEY_PAIR_GENERATION_ERROR);
  269. /* Get private key b and public key g^b, in little-endian format */
  270. uint8_t Publickey_little_endian[SIGMA_SESSION_PUBKEY_LENGTH];
  271. uint8_t Privatekey_b_little_endian[SIGMA_SESSION_PRIVKEY_LENGTH];
  272. if (SGX_SUCCESS != sgx_ecc256_create_key_pair((sgx_ec256_private_t *)Privatekey_b_little_endian,
  273. (sgx_ec256_public_t*)Publickey_little_endian, sigma_ecc_handle))
  274. {
  275. break;
  276. }
  277. m_sigmaAlg.set_prv_key_b_le(Privatekey_b_little_endian);
  278. // clear buffer containing secrets
  279. memset_s(Privatekey_b_little_endian, sizeof(Privatekey_b_little_endian), 0, sizeof(Privatekey_b_little_endian));
  280. /* Convert to big endian for m_localPublicKey_gb_big_endian */
  281. SwapEndian_32B(&(Publickey_little_endian[0]));
  282. SwapEndian_32B(&(Publickey_little_endian[32]));
  283. m_sigmaAlg.set_pub_key_gb_be(Publickey_little_endian);
  284. // OutputOctets("::GenM7:: g^a (BE)", m_remotePublicKey_ga_big_endian, SIGMA_SESSION_PUBKEY_LENGTH);
  285. // OutputOctets("::GenM7:: b (LE)", m_localPrivateKey_b_little_endian, sizeof(sgx_ec256_private_t));
  286. // OutputOctets("::GenM7:: g^b (BE)", m_localPublicKey_gb_big_endian, SIGMA_SESSION_PUBKEY_LENGTH);
  287. //*********************************************************************
  288. // Compute ((g^a)^b)
  289. // Derive SMK
  290. // SMK := HMAC-SHA256(0x00, g^(ab) || 0x00) with the HMAC key being
  291. // 32 bytes of 0x00 and the data element being g^(ab) little endian
  292. // Derive SK and MK
  293. // a) Compute HMAC-SHA256(0x00, g^(ab) || 0x01)
  294. // with the HMAC key being 32 bytes of 0x00, g^(ab) in little endian
  295. // b) SK is taken as the first 128 bits of the HMAC result
  296. // c) MK is taken as the second 128 bits of the HMAC result
  297. //*********************************************************************
  298. tmp_status = m_sigmaAlg.DeriveSkMk(sigma_ecc_handle);
  299. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  300. // OutputOctets("::GenM7: m_Sk", m_Sk, SIGMA_SK_LENGTH);
  301. // OutputOctets("::GenM7:: m_Mk", m_Mk, SIGMA_MK_LENGTH);
  302. // OutputOctets("::GenM7:: m_SMK", m_SMK, SIGMA_SMK_LENGTH);
  303. //*********************************************************************
  304. // Unseal pairing blob
  305. //*********************************************************************
  306. tmp_status = UnsealPairingBlob(pPairingBlob, &pairing_data);
  307. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  308. //*************************************************************
  309. // Extract Private Key from pairing blob
  310. //*************************************************************
  311. // OutputOctets("::GenM7:: Verifier PrivateKey", unsealedBlobData.VerifierPrivateKey, ECDSA_PRIVKEY_LEN);
  312. memcpy(m_verifierPrivateKey, pairing_data.secret_data.VerifierPrivateKey, ECDSA_PRIVKEY_LEN);
  313. //*************************************************************
  314. // Extract pairing data
  315. //*************************************************************
  316. memcpy(m_pairingID, pairing_data.secret_data.pairingID, sizeof(m_pairingID));
  317. memcpy(m_pairingNonce, pairing_data.secret_data.pairingNonce, sizeof(m_pairingNonce));
  318. // OutputOctets("::GenM7:: m_pairingID", m_pairingID, sizeof(m_pairingID));
  319. // OutputOctets("::GenM7:: m_pairingNonce", m_pairingNonce, sizeof(m_pairingNonce));
  320. //*********************************************************************
  321. // Prepare S2
  322. //*********************************************************************
  323. memset(pS2, 0, nMax_S2);
  324. // Copy Gb in big endian to S2
  325. memcpy(pS2->Gb, m_sigmaAlg.get_pub_key_gb_be(), SIGMA_SESSION_PUBKEY_LENGTH);
  326. // Copy OCSP request sent in S1
  327. memcpy(&pS2->OcspReq, &pS1->OcspReq, sizeof(OCSP_REQ));
  328. // Basename is always set to 0
  329. memset(pS2->Basename, 0, SIGMA_BASENAME_LENGTH);
  330. // Location within pS2->Data where data gets added
  331. size_t index = 0;
  332. //*********************************************************************
  333. // Add verifier certificate chain to S2
  334. //*********************************************************************
  335. tmp_status = AddCertificateChain(pS2, index, nMax_S2,
  336. pVerifierCert, nLen_VerifierCert);
  337. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  338. //*********************************************************************
  339. // Verify SigRL (verify Cert signature and get the RL version)
  340. //*********************************************************************
  341. tmp_status = ValidateSigRL(pSigRL, sigRL_entries, sigRL_size, &m_nSigRLVersion);
  342. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  343. //*********************************************************************
  344. // Add revocation list to S2
  345. //*********************************************************************
  346. tmp_status = AddRevocationList(pS2, index, nMax_S2, pSigRL, sigRL_size);
  347. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  348. //*********************************************************************
  349. // Add OCSP Responses to S2
  350. //*********************************************************************
  351. tmp_status = AddOcspResponses(pS2, index, nMax_S2,
  352. pOcspResp, nLen_OcspResp);
  353. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  354. //*********************************************************************
  355. // Compute the HMAC over S2 using SMK (exclude SigGbGa)
  356. // [g^b || Basename || OCSPReq || Certver || SIG-RL || OCSPResp]SMK
  357. //*********************************************************************
  358. // index is portion of S2 in pS2->Data
  359. tmp_status = m_sigmaAlg.calc_s2_hmac(&pS2->S2Icv, pS2, index);
  360. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  361. //*********************************************************************
  362. // Append Pr_pse, where Pr_pse is HMAC_SHA256(MK, OLD_SK || 0x01)
  363. // if OLD_SK is available, or 256-bit 0x0 if OLD_SK is not available
  364. //*********************************************************************
  365. PR_PSE_T pr = {0};
  366. int nSizePr = sizeof(pr);
  367. const Nonce128_t zeroNonce = {0};
  368. if (0 != memcmp(zeroNonce, m_pairingNonce, sizeof(Nonce128_t)))
  369. {
  370. // A non-zero pairing nonce indicates valid pairing info is available
  371. tmp_status = m_sigmaAlg.ComputePR(&m_pairingID, 0x01, (SIGMA_HMAC*)pr);
  372. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  373. // OutputOctets("::GenM7:: Pr_pse HMAC[(m_pairingID || 0x01)] using m_Mk", pr, nSizePr);
  374. }
  375. nSizePr = sizeof(pr);
  376. memcpy((pS2->Data + index), pr, nSizePr);
  377. index += nSizePr;
  378. //*********************************************************************
  379. // Sign SigGaGb
  380. // Sig_pse(g^a || g^b)
  381. //*********************************************************************
  382. uint8_t combined_pubkeys[SIGMA_SESSION_PUBKEY_LENGTH * 2];
  383. uint8_t ecc_sig[ECDSA_SIG_LENGTH] = {0};
  384. /* GaGb in big endian format */
  385. memcpy(combined_pubkeys, m_sigmaAlg.get_remote_pub_key_ga_be(), SIGMA_SESSION_PUBKEY_LENGTH);
  386. memcpy(combined_pubkeys + SIGMA_SESSION_PUBKEY_LENGTH, m_sigmaAlg.get_pub_key_gb_be(), SIGMA_SESSION_PUBKEY_LENGTH);
  387. if (SGX_SUCCESS == sgx_ecdsa_sign(combined_pubkeys,
  388. sizeof(combined_pubkeys),
  389. (sgx_ec256_private_t *)pairing_data.secret_data.VerifierPrivateKey,
  390. (sgx_ec256_signature_t *)ecc_sig,
  391. sigma_ecc_handle))
  392. {
  393. /* Convert the signature to big endian format for pS2->SigGaGb */
  394. SwapEndian_32B(ecc_sig);
  395. SwapEndian_32B(&(ecc_sig[32]));
  396. memcpy(pS2->SigGaGb, ecc_sig, ECDSA_SIG_LENGTH);
  397. }
  398. else
  399. {
  400. status = PSE_PR_MSG_SIGNING_ERROR;
  401. break;
  402. }
  403. //*********************************************************************
  404. // Set the size of S2 that is being returned
  405. //*********************************************************************
  406. size_t S2IcvSize = SIGMA_S2_ICV_CONSTANT_BUFFER_SIZE + index;
  407. if ( UINT32_MAX - SIGMA_S2_ICV_CONSTANT_BUFFER_SIZE - ECDSA_SIG_LENGTH - SIGMA_HMAC_LENGTH < index)
  408. {
  409. status = PSE_PR_BAD_POINTER_ERROR;
  410. break;
  411. }
  412. *pnLen_S2 = (uint32_t)(S2IcvSize + ECDSA_SIG_LENGTH + SIGMA_HMAC_LENGTH);
  413. //*********************************************************************
  414. // WE PASSED ALL BARRIERS TO SUCCESS
  415. //*********************************************************************
  416. status = AE_SUCCESS;
  417. m_nextState = STATE_VERIFYM8;
  418. } while (false);
  419. /* Defense-in-depth: clear the data on stack that contains enclave secret.*/
  420. memset_s(&pairing_data, sizeof(pairing_data), 0, sizeof(pairing_data));
  421. /* close ecc context handle, the generic crypto lib will free the context memory */
  422. if (sigma_ecc_handle != NULL) sgx_ecc256_close_context(sigma_ecc_handle);
  423. return map_GenM7_error_for_return(status);
  424. }
  425. #define RL_OFFSET 4
  426. /*
  427. This function will check if the S3 ICV is correct.
  428. Then it will verify the EPID signature
  429. */
  430. ae_error_t TEpidSigma11Verifier::VerifyM8
  431. (
  432. /*in */ const SIGMA_S3_MESSAGE* pS3,
  433. /*in */ UINT32 nLen_S3,
  434. /*in */ const EPID11_PRIV_RL* pPrivRL,
  435. /*in */ uint32_t nTotalLen_PrivRL,
  436. /*in, out*/ pairing_blob_t* pPairingBlob,
  437. /*out*/ bool* pbNewPairing
  438. )
  439. {
  440. // S3 --> [TaskInfo || g^a || EpidCert || EpidSig(g^a || g^b) || SIG-RL]SMK
  441. ae_error_t status = AE_FAILURE;
  442. pairing_data_t pairing_data;
  443. //
  444. // This is misleading, PR_PSE_T isn't part of SIGMA, S3, it's part of our (sgx) m8.
  445. // Also, min_s3 is a very low lower bound. m8 message (not s3) is hmac || taskinfo || g**a || group cert || epid sig || pr_pse.
  446. // Group cert and EPID sig are variable-length, but they have fixed length parts so lengths of the fixed
  447. // length parts could be included here.
  448. //
  449. const size_t min_s3 = sizeof(SIGMA_S3_MESSAGE) + sizeof(PR_PSE_T);
  450. bool bResult;
  451. bool bNewPairing = false;
  452. do
  453. {
  454. if (pPrivRL != NULL)
  455. {
  456. BREAK_IF_TRUE((nTotalLen_PrivRL < sizeof(EPID11_PRIV_RL)), status, PSE_PR_PARAMETER_ERROR);
  457. }
  458. //
  459. // stop speculation in case undersized PrivRL (where
  460. // access of header would overflow)
  461. //
  462. sgx_lfence();
  463. ae_error_t tmp_status;
  464. // privRL_size allows for the privRL header, array of RL entries, and signature at the end
  465. uint32_t privRL_entries = 0;
  466. uint32_t privRL_size = 0;
  467. bResult = TEpidSigma11Verifier::get_privRL_info(pPrivRL, privRL_entries, privRL_size);
  468. BREAK_IF_FALSE((bResult), status, PSE_PR_BAD_POINTER_ERROR);
  469. BREAK_IF_TRUE((nTotalLen_PrivRL < privRL_size), status, PSE_PR_PARAMETER_ERROR);
  470. //
  471. // privRL_size is based on number of entries, which is basically
  472. // an input to the enclave
  473. //
  474. sgx_lfence();
  475. BREAK_IF_TRUE( (STATE_VERIFYM8 != m_nextState), status, PSE_PR_CALL_ORDER_ERROR);
  476. //*********************************************************************
  477. // Validate pointers and sizes
  478. //*********************************************************************
  479. BREAK_IF_TRUE((NULL == pS3 || nLen_S3 < min_s3), status, PSE_PR_BAD_POINTER_ERROR);
  480. //
  481. // stop speculation so code below doesn't go past end of
  482. // undersized S3
  483. //
  484. sgx_lfence();
  485. // pPrivRL is allowed to be NULL and will be checked in ValidatePrivRL()
  486. BREAK_IF_TRUE((NULL == pPairingBlob), status, PSE_PR_BAD_POINTER_ERROR);
  487. BREAK_IF_TRUE((NULL == pbNewPairing), status, PSE_PR_BAD_POINTER_ERROR);
  488. BREAK_IF_TRUE((privRL_size > MAX_ALLOWED_PRIVRL_SIZE), status, PSE_PR_PARAMETER_ERROR);
  489. BREAK_IF_TRUE((nLen_S3 > MAX_ALLOWED_S3_SIZE), status, PSE_PR_PARAMETER_ERROR);
  490. BREAK_IF_FALSE(sgx_is_within_enclave(pS3, nLen_S3), status, PSE_PR_BAD_POINTER_ERROR);
  491. //*********************************************************************
  492. // Start SIGMA processing S3
  493. //*********************************************************************
  494. //*********************************************************************
  495. // Initialize for calculating HMAC and indexing to data
  496. //*********************************************************************
  497. size_t S3VLDataLen = nLen_S3 - (sizeof(SIGMA_S3_MESSAGE) + sizeof(PR_PSE_T));
  498. //*********************************************************************
  499. // Verify the S3 HMAC using SMK
  500. // [TaskInfo || g^a || EpidCert || EpidSig(g^a || g^b) || SIG-RL]SMK
  501. //*********************************************************************
  502. SIGMA_HMAC calcHMAC;
  503. tmp_status = m_sigmaAlg.calc_s3_hmac(&calcHMAC, pS3, S3VLDataLen);
  504. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  505. bResult = (1 == consttime_memequal(calcHMAC, pS3->S3Icv, sizeof(SIGMA_HMAC)));
  506. BREAK_IF_FALSE( (bResult), status, PSE_PR_HMAC_COMPARE_ERROR);
  507. //*********************************************************************
  508. // Verify that g^a is the same that arrived in S1
  509. //*********************************************************************
  510. bResult = (0 == memcmp(m_sigmaAlg.get_remote_pub_key_ga_be(), pS3->Ga, sizeof(pS3->Ga)));
  511. BREAK_IF_FALSE( (bResult), status, PSE_PR_GA_COMPARE_ERROR);
  512. //*********************************************************************
  513. // Verify TaskInfo
  514. //*********************************************************************
  515. BREAK_IF_FALSE(TaskInfoIsValid(pS3->TaskInfo), status, PSE_PR_TASK_INFO_ERROR);
  516. //*********************************************************************
  517. // Check the EPID signature
  518. //*********************************************************************
  519. X509_GROUP_CERTIFICATE_VLR* X509GroupCertVlr = NULL;
  520. EPID_SIGNATURE_VLR* EpidSigVlr = NULL;
  521. tmp_status = ValidateS3DataBlock(pS3, nLen_S3, &X509GroupCertVlr, &EpidSigVlr);
  522. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  523. UINT32 S3GID;
  524. Epid11GroupPubKey groupPubKey;
  525. /* X509Parser::ParseGroupCertificate() expecting big endian format public key */
  526. uint8_t SerializedPublicKey[SIGMA_SESSION_PUBKEY_LENGTH];
  527. for (uint32_t i = 0; i < Keys::EpidVerifyKeyNum(); i++)
  528. {
  529. memcpy(SerializedPublicKey, (EcDsaPubKey*)Keys::EpidVerifyKeys()[i], SIGMA_SESSION_PUBKEY_LENGTH);
  530. SwapEndian_32B(SerializedPublicKey);
  531. SwapEndian_32B(&(SerializedPublicKey[32]));
  532. if (0 == X509Parser::ParseGroupCertificate( /*in */ (EcDsaPubKey*)SerializedPublicKey,
  533. /*in */ X509GroupCertVlr, /*out*/ &S3GID, /*out*/ &groupPubKey))
  534. {
  535. tmp_status = AE_SUCCESS;
  536. break;
  537. }
  538. else
  539. {
  540. tmp_status = PSE_PR_X509_PARSE_ERROR;
  541. }
  542. }
  543. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  544. BREAK_IF_FALSE((S3GID == m_gid), status, PSE_PR_GID_MISMATCH_ERROR );
  545. //*********************************************************************
  546. // Verify PrivRL
  547. //*********************************************************************
  548. tmp_status = ValidatePrivRL(pPrivRL, privRL_entries, privRL_size, &m_nPrivRLVersion);
  549. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  550. KeysToSign_t combinedKeys;
  551. memset(&combinedKeys, 0, sizeof(combinedKeys));
  552. // Combine over g^a || g^b to the struct
  553. memcpy(combinedKeys.first, m_sigmaAlg.get_remote_pub_key_ga_be(),
  554. SIGMA_SESSION_PUBKEY_LENGTH);
  555. memcpy(combinedKeys.second, m_sigmaAlg.get_pub_key_gb_be(),
  556. SIGMA_SESSION_PUBKEY_LENGTH);
  557. //*********************************************************************
  558. // the input pPrivRL has a type definition of EPID11_PRIV_RL,
  559. // but the epid-sdk-3.0 library takes Epid11PrivRl as input parameter.
  560. // EPID11_PRIV_RL has 4 addtional bytes at the header so we offset the pointer
  561. // by 4 bytes . Also we need to exclude RL signature because epid-sdk3.0
  562. // checks the RL's size shouldn't include the signature. Similar for SigRL and GroupRL.
  563. //*********************************************************************
  564. uint8_t* pEpid11PrivRL = (pPrivRL == NULL)? NULL:(uint8_t*)pPrivRL+RL_OFFSET;
  565. uint32_t nEpid11PrivRLSize = (pPrivRL == NULL)? 0:privRL_size-RL_OFFSET-ECDSA_SIG_LENGTH;
  566. uint8_t* pEpid11SigRL = (m_pSigRL == NULL)? NULL:m_pSigRL+RL_OFFSET;
  567. uint32_t nEpid11SigRLSize = (m_pSigRL == NULL)? 0:static_cast<uint32_t>(m_nSigRL-RL_OFFSET-ECDSA_SIG_LENGTH);
  568. tmp_status = m_sigmaAlg.MsgVerifyPch((UINT8 *)&groupPubKey,
  569. (uint32_t)(sizeof(EpidCert) - ECDSA_SIG_LENGTH),
  570. NULL, // not required for EPID SDK 3.0
  571. (Ipp8u*)&combinedKeys,
  572. (uint32_t)sizeof(combinedKeys),
  573. NULL, // Bsn
  574. 0, // BsnLen
  575. (UINT8 *)EpidSigVlr->EpidSig,
  576. static_cast<int>(VLR_UNPADDED_PAYLOAD_SIZE(EpidSigVlr->VlrHeader)),
  577. pEpid11PrivRL, nEpid11PrivRLSize, // PrivRL
  578. pEpid11SigRL, nEpid11SigRLSize, // SigRL
  579. NULL, 0); // GroupRL
  580. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  581. //*********************************************************************
  582. // Calculate Id_pse and Id_cse
  583. // Id_pse = hash(sk || mk || 1)
  584. // Id_cse = hash(sk || mk || 2)
  585. //*********************************************************************
  586. SHA256_HASH Id_pse = {0};
  587. SHA256_HASH Id_cse = {0};
  588. tmp_status = m_sigmaAlg.ComputeId(1, &Id_pse);
  589. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  590. tmp_status = m_sigmaAlg.ComputeId(2, &Id_cse);
  591. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  592. //*********************************************************************
  593. // Verify Pr_cse, where Pr_cse is HMAC_SHA256(MK, OLD_SK || 0x02)
  594. // if OLD_SK is available, or 256-bit 0x0 if OLD_SK is not available
  595. //*********************************************************************
  596. size_t nSizePr = sizeof(PR_PSE_T);
  597. PR_PSE_T *pS3_PR_cse = (PR_PSE_T*)((const uint8_t*)pS3 + nLen_S3 - nSizePr);
  598. // OutputOctets("S3", pS3, nLen_S3);
  599. // OutputOctets("VerifyM8 - pS3_PR_cse", pS3_PR_cse, nSizePr);
  600. bNewPairing = true;
  601. PR_PSE_T pr_cse = {0};
  602. const Nonce128_t zeroNonce = {0};
  603. if (0 != memcmp(&pr_cse, pS3_PR_cse, sizeof(pr_cse)) && 0 != memcmp(&m_pairingNonce, &zeroNonce, sizeof(Nonce128_t)))
  604. {
  605. tmp_status = m_sigmaAlg.ComputePR(&m_pairingID, 0x02, (SIGMA_HMAC*)pr_cse);
  606. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  607. // OutputOctets("::VerifyM8:: Computed Pr HMAC[(m_pairingID || 0x02)] using m_Mk", pr_cse, nSizePr);
  608. if (0 == memcmp(&pr_cse, pS3_PR_cse, sizeof(pr_cse)))
  609. bNewPairing = false;
  610. }
  611. if (bNewPairing)
  612. {
  613. memcpy(&m_pairingID, m_sigmaAlg.get_SK(), sizeof(m_pairingID));
  614. sgx_status_t seStatus = sgx_read_rand((uint8_t*)&m_pairingNonce, sizeof(m_pairingNonce));
  615. BREAK_IF_TRUE(SGX_SUCCESS != seStatus, status, PSE_PR_READ_RAND_ERROR);
  616. // LTPBlob.pairingNonce = 0 is used to indicate invalid pairing Info in the LTP blob.
  617. // Under the rare situation of a random number of 0 is returned for pairingNonce generation,
  618. // PSE-Pr declares pairing or re-pairing attempt failure. The next pairing/re-pairing attempt
  619. // most likely will generate a non-zero pairingNonce
  620. BREAK_IF_TRUE(memcmp(&m_pairingNonce, &zeroNonce, sizeof(Nonce128_t)) == 0, status, PSE_PR_READ_RAND_ERROR);
  621. // OutputOctets("VerifyM8 - new pairing", NULL, 0);
  622. }
  623. else
  624. {
  625. // OutputOctets("VerifyM8 - pS3_PR_cse matches pr_cse", NULL, 0);
  626. }
  627. //*********************************************************************
  628. // Update the unsealed pairing data
  629. // [VerifierPrivateKey, id_pse || id_cse || sk || mk ||
  630. // PairingNonce || SigRLVersion_cse || PrvRLVersion_cse ||
  631. // DalAppletVersion]
  632. //*********************************************************************
  633. memset(&pairing_data, 0, sizeof(pairing_data));
  634. memcpy(pairing_data.secret_data.VerifierPrivateKey, m_verifierPrivateKey, sizeof(EcDsaPrivKey));
  635. memcpy(pairing_data.secret_data.Id_cse, &Id_cse, sizeof(SHA256_HASH));
  636. memcpy(pairing_data.secret_data.Id_pse, &Id_pse, sizeof(SHA256_HASH));
  637. memcpy(pairing_data.secret_data.mk, m_sigmaAlg.get_MK(), sizeof(pairing_data.secret_data.mk));
  638. memcpy(pairing_data.secret_data.sk, m_sigmaAlg.get_SK(), sizeof(pairing_data.secret_data.sk));
  639. memcpy(pairing_data.secret_data.pairingID, m_pairingID, sizeof(m_pairingID));
  640. memcpy(pairing_data.secret_data.pairingNonce, m_pairingNonce, sizeof(Nonce128_t));
  641. pairing_data.plaintext.cse_sec_prop.ps_hw_gid = m_gid;
  642. pairing_data.plaintext.cse_sec_prop.ps_hw_sig_rlversion = m_nSigRLVersion;
  643. pairing_data.plaintext.cse_sec_prop.ps_hw_privkey_rlversion = m_nPrivRLVersion;
  644. //NRG: Definition of ME_TASK_INFO and PS_HW_SEC_INFO is still open
  645. // for SunrisePoint from TaskInfo of SIGMA1.1 message:
  646. // byte[ 0- 3] ME_TASK_INFO.TaskID, for SunrisePoint must be 8
  647. // byte[ 4- 7] Reserved, must be 0
  648. // byte[ 8-11] PSDA ID, mapped from the PSDA Applet ID in ME_TASK_INFO (1)
  649. // byte[12-15] PSDA SVN from ME_TASK_INFO
  650. // byte[16-31] Reserved, must be 0
  651. pairing_data.plaintext.cse_sec_prop.ps_hw_sec_info.taskId = pS3->TaskInfo.TaskId;
  652. pairing_data.plaintext.cse_sec_prop.ps_hw_sec_info.psdaId = 1;
  653. pairing_data.plaintext.cse_sec_prop.ps_hw_sec_info.psdaSvn = m_nDalAppletVersion;
  654. //NRG:
  655. // keep instance id
  656. memcpy(pairing_data.plaintext.pse_instance_id,
  657. pPairingBlob->plaintext.pse_instance_id,
  658. sizeof(pairing_data.plaintext.pse_instance_id));
  659. //*********************************************************************
  660. // Seal the pairing blob
  661. //*********************************************************************
  662. tmp_status = SealPairingBlob(&pairing_data, pPairingBlob);
  663. BREAK_IF_TRUE(AE_SUCCESS != tmp_status, status, tmp_status);
  664. *pbNewPairing = bNewPairing;
  665. //*********************************************************************
  666. // WE PASSED ALL BARRIERS TO SUCCESS
  667. //*********************************************************************
  668. status = AE_SUCCESS;
  669. m_nextState = STATE_DONE;
  670. } while (false);
  671. if (AE_FAILED(status))
  672. m_nextState = STATE_ERROR;
  673. /* Defense-in-depth: clear the data on stack that contains enclave secret.*/
  674. memset_s(&pairing_data, sizeof(pairing_data), 0, sizeof(pairing_data));
  675. delete[] m_pSigRL;
  676. m_pSigRL = NULL;
  677. m_nSigRL = 0;
  678. return map_VerifyM8_error_for_return(status);
  679. }
  680. bool TEpidSigma11Verifier::TaskInfoIsValid( const ME_TASK_INFO& taskInfo)
  681. {
  682. uint32_t taskInfoType = SwapEndian_DW(taskInfo.Hdr.Type);
  683. if (taskInfoType != ME_TASK) return false;
  684. //check TaskID and Applet ID according to SunrisePoint specification
  685. /* Check the TaskId matches the hardcoded JVM-On-ME Task ID */
  686. if (taskInfo.TaskId != JOM_TASK_ID) return false;
  687. /* Check the first 16 bytes of RsvdforApp matches the hardcoded PSDA Applet ID */
  688. if (memcmp(taskInfo.RsvdforApp, PSDA_APPLET_ID, DAL_APPLET_ID_LEN))
  689. {
  690. return false;
  691. }
  692. /* retrieve the PSDA SVN */
  693. memcpy(&m_nDalAppletVersion, (const_cast<uint8_t *>(taskInfo.RsvdforApp) + DAL_APPLET_ID_LEN), DAL_APPLET_SVN_LEN);
  694. return true;
  695. }
  696. ae_error_t TEpidSigma11Verifier::ValidateS3DataBlock(const SIGMA_S3_MESSAGE* pS3, uint32_t nLen_S3, X509_GROUP_CERTIFICATE_VLR** X509GroupCertVlr, EPID_SIGNATURE_VLR** EpidSigVlr)
  697. {
  698. X509_GROUP_CERTIFICATE_VLR* pX;
  699. EPID_SIGNATURE_VLR* pE;
  700. uint32_t data_offset = offsetof(SIGMA_S3_MESSAGE, Data);
  701. if (NULL == pS3 || NULL == X509GroupCertVlr || NULL == EpidSigVlr)
  702. return AESM_PSE_PR_BAD_POINTER_ERROR;
  703. // Make sure certificate is within bounds of S3 message allocated in trusted memory
  704. if (data_offset + sizeof(X509_GROUP_CERTIFICATE_VLR) >= nLen_S3)
  705. return PSE_PR_S3_DATA_ERROR;
  706. pX = (X509_GROUP_CERTIFICATE_VLR *)(((uint8_t*)pS3) + data_offset);
  707. //
  708. // if above mispredicts and we end up here, then below
  709. // can overflow
  710. //
  711. sgx_lfence();
  712. // Make sure epid signature VLR is within bounds of S3 message allocated in trusted memory
  713. if ((data_offset + sizeof(EPID_SIGNATURE_VLR) + pX->VlrHeader.Length) >= nLen_S3)
  714. return PSE_PR_S3_DATA_ERROR;
  715. //
  716. // attacker can control pX->VlrHeader.Length
  717. //
  718. sgx_lfence();
  719. pE = (EPID_SIGNATURE_VLR*)((UINT8*)(pX) + pX->VlrHeader.Length);
  720. // Make sure epid signature data is within bounds of S3 message allocated in trusted memory
  721. if ((data_offset + pX->VlrHeader.Length + pE->VlrHeader.Length) >= nLen_S3)
  722. return PSE_PR_S3_DATA_ERROR;
  723. //
  724. // attacker can control pE->VlrHeader.Length
  725. //
  726. sgx_lfence();
  727. *X509GroupCertVlr = pX;
  728. *EpidSigVlr = pE;
  729. return AE_SUCCESS;
  730. }
  731. ae_error_t TEpidSigma11Verifier::AddCertificateChain(SIGMA_S2_MESSAGE* pS2,
  732. size_t& index, size_t nMaxS2, const UINT8* pCertChain, size_t nCertChain)
  733. {
  734. ae_error_t status = PSE_PR_INTERNAL_ERROR;
  735. do
  736. {
  737. if (nMaxS2 < ((pS2->Data - (uint8_t*)pS2) + index + nCertChain))
  738. break;
  739. memcpy((pS2->Data + index), pCertChain, nCertChain);
  740. index += nCertChain;
  741. status = AE_SUCCESS;
  742. } while (false);
  743. return status;
  744. }
  745. ae_error_t TEpidSigma11Verifier::AddRevocationList(SIGMA_S2_MESSAGE* pS2,
  746. size_t& index, size_t nMaxS2, const EPID11_SIG_RL* pRL, uint32_t nSigRL)
  747. {
  748. ae_error_t status = PSE_PR_INTERNAL_ERROR;
  749. do
  750. {
  751. if (NULL != m_pSigRL)
  752. delete [] m_pSigRL;
  753. m_nSigRL = 0;
  754. m_pSigRL = NULL;
  755. if (nSigRL > 0)
  756. {
  757. m_nSigRL = nSigRL;
  758. m_pSigRL = new (std::nothrow) UINT8[m_nSigRL];
  759. BREAK_IF_TRUE( (NULL == m_pSigRL), status,
  760. PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  761. int nPaddedBytes = static_cast<int>(REQUIRED_PADDING_DWORD_ALIGNMENT(m_nSigRL));
  762. memcpy(m_pSigRL, pRL , m_nSigRL);
  763. SIGNATURE_REV_LIST_VLR sigRL_VLR;
  764. sigRL_VLR.VlrHeader.ID = SIGNATURE_REVOCATION_LIST_VLR_ID;
  765. sigRL_VLR.VlrHeader.PaddedBytes = (uint8_t)nPaddedBytes;
  766. if (sizeof(SIGMA_VLR_HEADER) + nPaddedBytes + m_nSigRL > UINT16_MAX)
  767. break;
  768. sigRL_VLR.VlrHeader.Length = (uint16_t)(sizeof(SIGMA_VLR_HEADER) + nPaddedBytes + m_nSigRL);
  769. if (nMaxS2 < ((pS2->Data - (uint8_t*)pS2) + index + nSigRL + sizeof(SIGNATURE_REV_LIST_VLR)))
  770. break;
  771. memcpy((pS2->Data + index), &sigRL_VLR, sizeof(SIGNATURE_REV_LIST_VLR));
  772. index += sizeof(SIGNATURE_REV_LIST_VLR);
  773. memcpy((pS2->Data + index), m_pSigRL, m_nSigRL);
  774. index += m_nSigRL;
  775. // must skip nPaddedBytes for alignment
  776. index += nPaddedBytes;
  777. }
  778. status = AE_SUCCESS;
  779. } while (false);
  780. return status;
  781. }
  782. ae_error_t TEpidSigma11Verifier::AddOcspResponses(SIGMA_S2_MESSAGE* pS2,
  783. size_t& index, size_t nMaxS2, const UINT8* pOcspResp, size_t nOcspResp)
  784. {
  785. ae_error_t status = PSE_PR_INTERNAL_ERROR;
  786. do
  787. {
  788. if (pS2->OcspReq.ReqType == NO_OCSP)
  789. {
  790. status = AE_SUCCESS;
  791. break;
  792. }
  793. BREAK_IF_TRUE( (0 == nOcspResp), status ,
  794. PSE_PR_NO_OCSP_RESPONSE_ERROR);
  795. if (nMaxS2 < ((pS2->Data - (uint8_t*)pS2) + index + nOcspResp))
  796. break;
  797. memcpy((pS2->Data+index), pOcspResp, nOcspResp);
  798. index += nOcspResp;
  799. status = AE_SUCCESS;
  800. } while (false);
  801. return status;
  802. }
  803. ae_error_t TEpidSigma11Verifier::ValidateSigRL(const EPID11_SIG_RL* pSigRL, uint32_t sigRL_entries, uint32_t sigRL_size, uint32_t* pVersion)
  804. {
  805. sgx_ecc_state_handle_t ivk_ecc_handle = NULL;
  806. uint8_t result;
  807. ae_error_t status = PSE_PR_MSG_COMPARE_ERROR;
  808. if (NULL == pVersion)
  809. return PSE_PR_BAD_POINTER_ERROR;
  810. *pVersion = 0;
  811. if (0 == sigRL_size || NULL == pSigRL)
  812. return AE_SUCCESS;
  813. do
  814. {
  815. uint32_t nBaseSigRL_size = sigRL_size - EPID11_SIG_RL_SIGNATURE_SIZE;
  816. if (sigRL_entries > MAX_SIGRL_ENTRIES)
  817. break;
  818. uint8_t* p_rl_version = const_cast<uint8_t*>(pSigRL->rl_version);
  819. *pVersion = SwapEndian_DW(*reinterpret_cast<UINT32*>(p_rl_version));
  820. sgx_status_t sgx_status = sgx_ecc256_open_context(&ivk_ecc_handle);
  821. BREAK_IF_TRUE((SGX_ERROR_OUT_OF_MEMORY == sgx_status), status, PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  822. BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_MSG_COMPARE_ERROR);
  823. //Convert the big endian signature in the Cert to little endian
  824. uint8_t ecc_sig[ECDSA_SIG_LENGTH ];
  825. memcpy(ecc_sig, (uint8_t*)pSigRL + nBaseSigRL_size, ECDSA_SIG_LENGTH );
  826. SwapEndian_32B(ecc_sig);
  827. SwapEndian_32B(&(ecc_sig[32]));
  828. const uint8_t** pEpidVerifyKeys = Keys::EpidVerifyKeys();
  829. for (uint32_t i = 0; i < Keys::EpidVerifyKeyNum(); i++)
  830. {
  831. sgx_status = sgx_ecdsa_verify((uint8_t*)pSigRL,
  832. nBaseSigRL_size,
  833. (sgx_ec256_public_t *)(pEpidVerifyKeys[i]), /* requiring little endian format */
  834. (sgx_ec256_signature_t *)ecc_sig,
  835. &result,
  836. ivk_ecc_handle);
  837. if (sgx_status == SGX_SUCCESS && result == SGX_EC_VALID)
  838. break;
  839. }
  840. BREAK_IF_TRUE((SGX_ERROR_OUT_OF_MEMORY == sgx_status), status, PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  841. BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_MSG_COMPARE_ERROR);
  842. BREAK_IF_TRUE((SGX_EC_VALID != result), status, PSE_PR_MSG_COMPARE_ERROR);
  843. status = AE_SUCCESS;
  844. } while (false);
  845. if (ivk_ecc_handle != NULL) sgx_ecc256_close_context(ivk_ecc_handle);
  846. return status;
  847. }
  848. ae_error_t TEpidSigma11Verifier::ValidatePrivRL(const EPID11_PRIV_RL* pPrivRL, uint32_t privRL_entries, uint32_t privRL_size, uint32_t* pVersion)
  849. {
  850. sgx_ecc_state_handle_t ivk_ecc_handle = NULL;
  851. uint8_t result;
  852. ae_error_t status = PSE_PR_MSG_COMPARE_ERROR;
  853. if (NULL == pVersion)
  854. return PSE_PR_BAD_POINTER_ERROR;
  855. *pVersion = 0;
  856. if (0 == privRL_size || NULL == pPrivRL)
  857. return AE_SUCCESS;
  858. do
  859. {
  860. uint32_t nBasePrivRL_size = privRL_size - EPID11_PRIV_RL_SIGNATURE_SIZE;
  861. if (privRL_entries > MAX_SIGRL_ENTRIES)
  862. break;
  863. uint8_t* p_rl_version = const_cast<uint8_t*>(pPrivRL->rl_version);
  864. *pVersion = SwapEndian_DW(*reinterpret_cast<UINT32*>(p_rl_version));
  865. sgx_status_t sgx_status = sgx_ecc256_open_context(&ivk_ecc_handle);
  866. BREAK_IF_TRUE((SGX_ERROR_OUT_OF_MEMORY == sgx_status), status, PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  867. BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_MSG_COMPARE_ERROR);
  868. //Convert the big endian signature in the Cert to little endian
  869. uint8_t ecc_sig[ECDSA_SIG_LENGTH];
  870. memcpy(ecc_sig, (uint8_t*)pPrivRL + nBasePrivRL_size, ECDSA_SIG_LENGTH);
  871. SwapEndian_32B(ecc_sig);
  872. SwapEndian_32B(&(ecc_sig[32]));
  873. const uint8_t** pEpidVerifyKeys = Keys::EpidVerifyKeys();
  874. for (uint32_t i = 0; i < Keys::EpidVerifyKeyNum(); i++)
  875. {
  876. sgx_status = sgx_ecdsa_verify((uint8_t*)pPrivRL,
  877. nBasePrivRL_size,
  878. (sgx_ec256_public_t *)(pEpidVerifyKeys[i]), /* requiring little endian format */
  879. (sgx_ec256_signature_t *)ecc_sig,
  880. &result,
  881. ivk_ecc_handle);
  882. if (sgx_status == SGX_SUCCESS && result == SGX_EC_VALID)
  883. break;
  884. }
  885. BREAK_IF_TRUE((SGX_ERROR_OUT_OF_MEMORY == sgx_status), status, PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  886. BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_MSG_COMPARE_ERROR);
  887. BREAK_IF_TRUE((SGX_EC_VALID != result), status, PSE_PR_MSG_COMPARE_ERROR);
  888. status = AE_SUCCESS;
  889. } while (false);
  890. if (ivk_ecc_handle != NULL) sgx_ecc256_close_context(ivk_ecc_handle);
  891. return status;
  892. }