uecall_bridge.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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 "u_long_term_pairing.h"
  32. #include <cstddef>
  33. #include "u_certificate_provisioning.h"
  34. #include "uecall_bridge.h"
  35. #include "pse_pr_u.h"
  36. #include "pse_pr_u.c"
  37. #include "pse_pr_common.h"
  38. #include <Buffer.h>
  39. #include "pse_pr_sigma_1_1_defs.h"
  40. #include "le2be_macros.h"
  41. #include "aeerror.h"
  42. //
  43. // need to fix this
  44. //
  45. #define __FUNCTIONW__ __FUNCTION__
  46. #include "oal/oal.h"
  47. static sgx_enclave_id_t _enclaveID;
  48. static ae_error_t check_sigrl_entries_max(const EPID11_SIG_RL* pSigRL)
  49. {
  50. if (NULL != pSigRL)
  51. {
  52. const uint32_t* p = reinterpret_cast<const uint32_t*>(pSigRL->entries);
  53. uint32_t nEntries = SwapEndian_DW(*p);
  54. if (nEntries > MAX_SIGRL_ENTRIES)
  55. return AESM_PSE_PR_MAX_SIGRL_ENTRIES_EXCEEDED;
  56. }
  57. return AE_SUCCESS;
  58. }
  59. static ae_error_t check_privrl_entries_max(const EPID11_PRIV_RL* pPrivRL)
  60. {
  61. if (NULL != pPrivRL)
  62. {
  63. const uint32_t* p = reinterpret_cast<const uint32_t*>(pPrivRL->entries);
  64. uint32_t nEntries = SwapEndian_DW(*p);
  65. if (nEntries > MAX_PRIVRL_ENTRIES)
  66. return AESM_PSE_PR_MAX_PRIVRL_ENTRIES_EXCEEDED;
  67. }
  68. return AE_SUCCESS;
  69. }
  70. void SaveEnclaveID(sgx_enclave_id_t eid)
  71. {
  72. _enclaveID = eid;
  73. }
  74. ae_error_t tPrepareForCertificateProvisioning
  75. (
  76. /*in */ upse::Buffer& nonce,
  77. /*in */ upse::Buffer& target_info,
  78. /*out*/ upse::Buffer& csr_pse,
  79. /*out*/ upse::Buffer& report,
  80. /*out*/ upse::Buffer& pairingBlob
  81. )
  82. {
  83. ae_error_t retval;
  84. UINT8* pCsr = NULL;
  85. do
  86. {
  87. sgx_status_t seStatus;
  88. UINT64* pNonce64 = (UINT64*)const_cast<UINT8*>(nonce.getData());
  89. UINT32 nNonce64 = nonce.getSize();
  90. UINT8* pTargetInfo = const_cast<UINT8*>(target_info.getData());
  91. UINT32 nTargetInfo = target_info.getSize();
  92. BREAK_IF_TRUE( (NULL == pNonce64 || NULL == pTargetInfo),
  93. retval, PSE_PR_ASN1DER_DECODING_ERROR);
  94. BREAK_IF_FALSE( (nNonce64 == sizeof(UINT64)), retval, PSE_PR_INTERNAL_ERROR);
  95. UINT16 nCsrPse = (UINT16)MaxBytesForCSR();
  96. UINT32 nReport = NeededBytesForREPORT();
  97. UINT32 nPairingBlob = NeededBytesForPairingBlob();
  98. // Allocate memory for output buffers
  99. upse::Buffer tmpReport;
  100. retval = tmpReport.Alloc(nReport);
  101. if (AE_FAILED(retval))
  102. break;
  103. upse::Buffer tmpPairingBlob;
  104. if (nPairingBlob == pairingBlob.getSize())
  105. retval = tmpPairingBlob.Clone(pairingBlob);
  106. else
  107. {
  108. // If pairingBlob is not the correct size, start with empty blob
  109. retval = tmpPairingBlob.Alloc(nPairingBlob);
  110. }
  111. if (AE_FAILED(retval))
  112. break;
  113. upse::BufferWriter bwReport(tmpReport);
  114. upse::BufferWriter bwPairingBlob(tmpPairingBlob);
  115. pCsr = (UINT8*)calloc(1, nCsrPse);
  116. BREAK_IF_FALSE((NULL != pCsr), retval, PSE_PR_INSUFFICIENT_MEMORY_ERROR);
  117. UINT8* pReport;
  118. retval = bwReport.reserve(nReport, &pReport);
  119. if (AE_FAILED(retval))
  120. break;
  121. UINT8* pPairingBlob;
  122. retval = bwPairingBlob.reserve(nPairingBlob, &pPairingBlob);
  123. if (AE_FAILED(retval))
  124. break;
  125. BREAK_IF_FALSE((nTargetInfo == sizeof(sgx_target_info_t)), retval, PSE_PR_INTERNAL_ERROR);
  126. BREAK_IF_FALSE((nReport == sizeof(sgx_report_t)), retval, PSE_PR_INTERNAL_ERROR);
  127. if (nPairingBlob != pairingBlob.getSize())
  128. {
  129. // generate new sw_instance_id only when no valid LTP blob
  130. BREAK_IF_FAILED(generate_pse_instance_id(((pairing_blob_t*)pPairingBlob)->plaintext.pse_instance_id));
  131. }
  132. // Call to get size required of output buffers
  133. seStatus = ecall_tPrepareForCertificateProvisioning(_enclaveID, &retval,
  134. *pNonce64,
  135. (sgx_target_info_t*)pTargetInfo,
  136. nCsrPse, pCsr, &nCsrPse,
  137. (sgx_report_t*)pReport,
  138. (pairing_blob_t*)pPairingBlob);
  139. BREAK_IF_TRUE( (SGX_ERROR_ENCLAVE_LOST == seStatus), retval, PSE_PR_ENCLAVE_LOST_ERROR);
  140. BREAK_IF_TRUE( (SGX_SUCCESS != seStatus), retval, PSE_PR_ENCLAVE_BRIDGE_ERROR);
  141. BREAK_IF_FAILED(retval);
  142. retval = report.Clone(tmpReport);
  143. BREAK_IF_FAILED(retval);
  144. retval = pairingBlob.Clone(tmpPairingBlob);
  145. BREAK_IF_FAILED(retval);
  146. retval = csr_pse.Alloc(pCsr, nCsrPse);
  147. BREAK_IF_FAILED(retval);
  148. } while (0);
  149. if (pCsr != NULL)
  150. free(pCsr);
  151. SGX_DBGPRINT_PRINT_FUNCTION_AND_RETURNVAL(__FUNCTIONW__, retval);
  152. return retval;
  153. }
  154. #if defined(NO_PROVISIONING_SERVER)
  155. ae_error_t tPrepareForCertificateProvisioning_hardcoded_privatekey
  156. (
  157. /*out*/ upse::Buffer& pairingBlob
  158. )
  159. {
  160. ae_error_t retval;
  161. do
  162. {
  163. sgx_status_t seStatus;
  164. UINT32 nPairingBlob = NeededBytesForPairingBlob();
  165. // Allocate memory for output buffers
  166. upse::Buffer tmpPairingBlob;
  167. if (nPairingBlob == pairingBlob.getSize())
  168. retval = tmpPairingBlob.Clone(pairingBlob);
  169. else
  170. retval = tmpPairingBlob.Alloc(nPairingBlob);
  171. if (AE_FAILED(retval))
  172. break;
  173. upse::BufferWriter bwPairingBlob(tmpPairingBlob);
  174. UINT8* pPairingBlob;
  175. retval = bwPairingBlob.reserve(nPairingBlob, &pPairingBlob);
  176. BREAK_IF_FAILED(retval);
  177. // calculate platform instance id
  178. BREAK_IF_FAILED(generate_pse_instance_id(((pairing_blob_t*)pPairingBlob)->plaintext.pse_instance_id));
  179. // Call to get size required of output buffers
  180. seStatus = ecall_tPrepareForCertificateProvisioning(_enclaveID, &retval,
  181. 0,
  182. NULL,
  183. 0, NULL, NULL,
  184. NULL,
  185. (pairing_blob_t*)pPairingBlob);
  186. BREAK_IF_TRUE( (SGX_ERROR_ENCLAVE_LOST == seStatus), retval, PSE_PR_ENCLAVE_LOST_ERROR);
  187. BREAK_IF_TRUE( (SGX_SUCCESS != seStatus), retval, PSE_PR_ENCLAVE_BRIDGE_ERROR);
  188. BREAK_IF_FAILED(retval);
  189. retval = pairingBlob.Clone(tmpPairingBlob);
  190. BREAK_IF_FAILED(retval);
  191. } while (0);
  192. return retval;
  193. }
  194. #endif
  195. ae_error_t tGenM7
  196. (
  197. /*in */ upse::Buffer& s1,
  198. /*in */ upse::Buffer& sigRL,
  199. /*in */ upse::Buffer& ocspResp,
  200. /*in */ upse::Buffer& verifierCert,
  201. /*in */ upse::Buffer& pairingBlob,
  202. /*out*/ upse::Buffer& s2
  203. )
  204. {
  205. ae_error_t retval;
  206. do
  207. {
  208. sgx_status_t seStatus;
  209. BREAK_IF_TRUE( (s1.getSize() < sizeof(SIGMA_S1_MESSAGE)), retval, AESM_PSE_PR_INTERNAL_ERROR);
  210. const SIGMA_S1_MESSAGE* pS1 = (const SIGMA_S1_MESSAGE*)(s1.getData());
  211. const UINT8* pSigRL = sigRL.getSize() ? const_cast<uint8_t*>(sigRL.getData()) : NULL;
  212. retval = check_sigrl_entries_max((const EPID11_SIG_RL*)pSigRL);
  213. BREAK_IF_FAILED(retval);
  214. const UINT8* pOcspResp = const_cast<uint8_t*>(ocspResp.getData());
  215. UINT32 nOcspResp = ocspResp.getSize();
  216. const UINT8* pVCert = const_cast<uint8_t*>(verifierCert.getData());
  217. UINT32 nVCert = verifierCert.getSize();
  218. UINT32 nPairingBlob = pairingBlob.getSize();
  219. BREAK_IF_FALSE((nPairingBlob == NeededBytesForPairingBlob()), retval,
  220. PSE_PAIRING_BLOB_INVALID_ERROR);
  221. UINT8* pPairingBlob = const_cast<uint8_t*>(pairingBlob.getData());
  222. UINT32 nS2 = NeededBytesForS2(nVCert, sigRL.getSize(), nOcspResp);
  223. // Allocate memory for output buffer
  224. retval = s2.Alloc(nS2);
  225. BREAK_IF_FAILED(retval);
  226. upse::BufferWriter bwS2(s2);
  227. UINT8* p;
  228. retval = bwS2.reserve(nS2, &p);
  229. BREAK_IF_FAILED(retval);
  230. SIGMA_S2_MESSAGE* pS2 = (SIGMA_S2_MESSAGE*)p;
  231. AESM_DBG_INFO("start gen M7 ...");
  232. // Call to get size required of output buffers
  233. seStatus = ecall_tGenM7(_enclaveID, &retval, pS1,
  234. (const EPID11_SIG_RL*)pSigRL, sigRL.getSize(), pOcspResp, nOcspResp,
  235. pVCert, nVCert, (pairing_blob_t*)pPairingBlob,
  236. nS2, pS2, &nS2);
  237. BREAK_IF_TRUE( (SGX_ERROR_ENCLAVE_LOST == seStatus), retval, PSE_PR_ENCLAVE_LOST_ERROR);
  238. BREAK_IF_TRUE( (SGX_SUCCESS != seStatus), retval, PSE_PR_ENCLAVE_BRIDGE_ERROR);
  239. BREAK_IF_FAILED(retval);
  240. } while (0);
  241. SGX_DBGPRINT_PRINT_FUNCTION_AND_RETURNVAL(__FUNCTIONW__, retval);
  242. return retval;
  243. }
  244. ae_error_t tVerifyM8
  245. (
  246. /*in */ upse::Buffer& s3,
  247. /*in */ upse::Buffer& privRL,
  248. /*out*/ upse::Buffer& pairingBlob,
  249. /*out*/ bool& new_pairing
  250. )
  251. {
  252. ae_error_t retval;
  253. do
  254. {
  255. sgx_status_t seStatus;
  256. UINT8 uNewPairing = 0;
  257. UINT32 nS3 = s3.getSize();
  258. BREAK_IF_TRUE( (nS3 < sizeof(SIGMA_S3_MESSAGE)), retval, AESM_PSE_PR_INTERNAL_ERROR);
  259. const SIGMA_S3_MESSAGE* pS3 = (const SIGMA_S3_MESSAGE*)(s3.getData());
  260. UINT8* pPrivRL = privRL.getSize() ? const_cast<uint8_t*>(privRL.getData()) : NULL;
  261. retval = check_privrl_entries_max((const EPID11_PRIV_RL*)pPrivRL);
  262. BREAK_IF_FAILED(retval);
  263. UINT32 nPairingBlob = NeededBytesForPairingBlob();
  264. BREAK_IF_FALSE((nPairingBlob == pairingBlob.getSize()), retval,
  265. PSE_PAIRING_BLOB_INVALID_ERROR);
  266. upse::BufferWriter bw(pairingBlob);
  267. pairing_blob_t* pPairingBlob = NULL;
  268. retval = bw.reserve(nPairingBlob, (uint8_t**)&pPairingBlob);
  269. // Call to get size required of output buffers
  270. seStatus = ecall_tVerifyM8(_enclaveID, &retval, pS3, nS3,
  271. (const EPID11_PRIV_RL*)pPrivRL, privRL.getSize(), pPairingBlob, &uNewPairing);
  272. BREAK_IF_TRUE( (SGX_ERROR_ENCLAVE_LOST == seStatus), retval, PSE_PR_ENCLAVE_LOST_ERROR);
  273. BREAK_IF_TRUE( (SGX_SUCCESS != seStatus), retval, PSE_PR_ENCLAVE_BRIDGE_ERROR);
  274. BREAK_IF_FAILED(retval);
  275. new_pairing = (uNewPairing == 0) ? false : true;
  276. } while (0);
  277. SGX_DBGPRINT_PRINT_FUNCTION_AND_RETURNVAL(__FUNCTIONW__, retval);
  278. return retval;
  279. }
  280. #if 0
  281. void ocall_OutputOctets(const char* pMsg, const void* pData, size_t nData)
  282. {
  283. }
  284. void ocall_OutputString(const char* pMsg)
  285. {
  286. }
  287. #endif