service_provider.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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 "service_provider.h"
  32. #include "sample_libcrypto.h"
  33. #include "ecp.h"
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <stddef.h>
  37. #include <time.h>
  38. #include <string.h>
  39. #include "ias_ra.h"
  40. #ifndef SAFE_FREE
  41. #define SAFE_FREE(ptr) {if (NULL != (ptr)) {free(ptr); (ptr) = NULL;}}
  42. #endif
  43. // This is supported extended epid group of SP. SP can support more than one
  44. // extended epid group with different extended epid group id and credentials.
  45. static const sample_extended_epid_group g_extended_epid_groups[] = {
  46. {
  47. 0,
  48. ias_enroll,
  49. ias_get_sigrl,
  50. ias_verify_attestation_evidence
  51. }
  52. };
  53. // This is the private EC key of SP, the corresponding public EC key is
  54. // hard coded in isv_enclave. It is based on NIST P-256 curve.
  55. static const sample_ec256_private_t g_sp_priv_key = {
  56. {
  57. 0x90, 0xe7, 0x6c, 0xbb, 0x2d, 0x52, 0xa1, 0xce,
  58. 0x3b, 0x66, 0xde, 0x11, 0x43, 0x9c, 0x87, 0xec,
  59. 0x1f, 0x86, 0x6a, 0x3b, 0x65, 0xb6, 0xae, 0xea,
  60. 0xad, 0x57, 0x34, 0x53, 0xd1, 0x03, 0x8c, 0x01
  61. }
  62. };
  63. // This is the public EC key of SP, this key is hard coded in isv_enclave.
  64. // It is based on NIST P-256 curve. Not used in the SP code.
  65. static const sample_ec_pub_t g_sp_pub_key = {
  66. {
  67. 0x72, 0x12, 0x8a, 0x7a, 0x17, 0x52, 0x6e, 0xbf,
  68. 0x85, 0xd0, 0x3a, 0x62, 0x37, 0x30, 0xae, 0xad,
  69. 0x3e, 0x3d, 0xaa, 0xee, 0x9c, 0x60, 0x73, 0x1d,
  70. 0xb0, 0x5b, 0xe8, 0x62, 0x1c, 0x4b, 0xeb, 0x38
  71. },
  72. {
  73. 0xd4, 0x81, 0x40, 0xd9, 0x50, 0xe2, 0x57, 0x7b,
  74. 0x26, 0xee, 0xb7, 0x41, 0xe7, 0xc6, 0x14, 0xe2,
  75. 0x24, 0xb7, 0xbd, 0xc9, 0x03, 0xf2, 0x9a, 0x28,
  76. 0xa8, 0x3c, 0xc8, 0x10, 0x11, 0x14, 0x5e, 0x06
  77. }
  78. };
  79. // This is a context data structure used on SP side
  80. typedef struct _sp_db_item_t
  81. {
  82. sample_ec_pub_t g_a;
  83. sample_ec_pub_t g_b;
  84. sample_ec_key_128bit_t vk_key;// Shared secret key for the REPORT_DATA
  85. sample_ec_key_128bit_t mk_key;// Shared secret key for generating MAC's
  86. sample_ec_key_128bit_t sk_key;// Shared secret key for encryption
  87. sample_ec_key_128bit_t smk_key;// Used only for SIGMA protocol
  88. sample_ec_priv_t b;
  89. sample_ps_sec_prop_desc_t ps_sec_prop;
  90. }sp_db_item_t;
  91. static sp_db_item_t g_sp_db;
  92. static const sample_extended_epid_group* g_sp_extended_epid_group_id= NULL;
  93. static bool g_is_sp_registered = false;
  94. static int g_sp_credentials = 0;
  95. static int g_authentication_token = 0;
  96. uint8_t g_secret[8] = {0,1,2,3,4,5,6,7};
  97. sample_spid_t g_spid;
  98. // Verify message 0 then configure extended epid group.
  99. int sp_ra_proc_msg0_req(const sample_ra_msg0_t *p_msg0,
  100. uint32_t msg0_size)
  101. {
  102. int ret = -1;
  103. if (!p_msg0 ||
  104. (msg0_size != sizeof(sample_ra_msg0_t)))
  105. {
  106. return -1;
  107. }
  108. uint32_t extended_epid_group_id = p_msg0->extended_epid_group_id;
  109. // Check to see if we have registered with the attestation server yet?
  110. if (!g_is_sp_registered ||
  111. (g_sp_extended_epid_group_id != NULL && g_sp_extended_epid_group_id->extended_epid_group_id != extended_epid_group_id))
  112. {
  113. // Check to see if the extended_epid_group_id is supported?
  114. ret = SP_UNSUPPORTED_EXTENDED_EPID_GROUP;
  115. for (size_t i = 0; i < sizeof(g_extended_epid_groups) / sizeof(sample_extended_epid_group); i++)
  116. {
  117. if (g_extended_epid_groups[i].extended_epid_group_id == extended_epid_group_id)
  118. {
  119. g_sp_extended_epid_group_id = &(g_extended_epid_groups[i]);
  120. // In the product, the SP will establish a mutually
  121. // authenticated SSL channel. During the enrollment process, the ISV
  122. // registers it exchanges TLS certs with attestation server and obtains an SPID and
  123. // Report Key from the attestation server.
  124. // For a product attestation server, enrollment is an offline process. See the 'on-boarding'
  125. // documentation to get the information required. The enrollment process is
  126. // simulated by a call in this sample.
  127. ret = g_sp_extended_epid_group_id->enroll(g_sp_credentials, &g_spid,
  128. &g_authentication_token);
  129. if (0 != ret)
  130. {
  131. ret = SP_IAS_FAILED;
  132. break;
  133. }
  134. g_is_sp_registered = true;
  135. ret = SP_OK;
  136. break;
  137. }
  138. }
  139. }
  140. else
  141. {
  142. ret = SP_OK;
  143. }
  144. return ret;
  145. }
  146. // Verify message 1 then generate and return message 2 to isv.
  147. int sp_ra_proc_msg1_req(const sample_ra_msg1_t *p_msg1,
  148. uint32_t msg1_size,
  149. ra_samp_response_header_t **pp_msg2)
  150. {
  151. int ret = 0;
  152. ra_samp_response_header_t* p_msg2_full = NULL;
  153. sample_ra_msg2_t *p_msg2 = NULL;
  154. sample_ecc_state_handle_t ecc_state = NULL;
  155. sample_status_t sample_ret = SAMPLE_SUCCESS;
  156. bool derive_ret = false;
  157. if(!p_msg1 ||
  158. !pp_msg2 ||
  159. (msg1_size != sizeof(sample_ra_msg1_t)))
  160. {
  161. return -1;
  162. }
  163. // Check to see if we have registered?
  164. if (!g_is_sp_registered)
  165. {
  166. return SP_UNSUPPORTED_EXTENDED_EPID_GROUP;
  167. }
  168. do
  169. {
  170. // Get the sig_rl from attestation server using GID.
  171. // GID is Base-16 encoded of EPID GID in little-endian format.
  172. // In the product, the SP and attesation server uses an established channel for
  173. // communication.
  174. uint8_t* sig_rl;
  175. uint32_t sig_rl_size = 0;
  176. // The product interface uses a REST based message to get the SigRL.
  177. ret = g_sp_extended_epid_group_id->get_sigrl(p_msg1->gid, &sig_rl_size, &sig_rl);
  178. if(0 != ret)
  179. {
  180. fprintf(stderr, "\nError, ias_get_sigrl [%s].", __FUNCTION__);
  181. ret = SP_IAS_FAILED;
  182. break;
  183. }
  184. // Need to save the client's public ECCDH key to local storage
  185. if (memcpy_s(&g_sp_db.g_a, sizeof(g_sp_db.g_a), &p_msg1->g_a,
  186. sizeof(p_msg1->g_a)))
  187. {
  188. fprintf(stderr, "\nError, cannot do memcpy in [%s].", __FUNCTION__);
  189. ret = SP_INTERNAL_ERROR;
  190. break;
  191. }
  192. // Generate the Service providers ECCDH key pair.
  193. sample_ret = sample_ecc256_open_context(&ecc_state);
  194. if(SAMPLE_SUCCESS != sample_ret)
  195. {
  196. fprintf(stderr, "\nError, cannot get ECC context in [%s].",
  197. __FUNCTION__);
  198. ret = -1;
  199. break;
  200. }
  201. sample_ec256_public_t pub_key = {{0},{0}};
  202. sample_ec256_private_t priv_key = {{0}};
  203. sample_ret = sample_ecc256_create_key_pair(&priv_key, &pub_key,
  204. ecc_state);
  205. if(SAMPLE_SUCCESS != sample_ret)
  206. {
  207. fprintf(stderr, "\nError, cannot generate key pair in [%s].",
  208. __FUNCTION__);
  209. ret = SP_INTERNAL_ERROR;
  210. break;
  211. }
  212. // Need to save the SP ECCDH key pair to local storage.
  213. if(memcpy_s(&g_sp_db.b, sizeof(g_sp_db.b), &priv_key,sizeof(priv_key))
  214. || memcpy_s(&g_sp_db.g_b, sizeof(g_sp_db.g_b),
  215. &pub_key,sizeof(pub_key)))
  216. {
  217. fprintf(stderr, "\nError, cannot do memcpy in [%s].", __FUNCTION__);
  218. ret = SP_INTERNAL_ERROR;
  219. break;
  220. }
  221. // Generate the client/SP shared secret
  222. sample_ec_dh_shared_t dh_key = {{0}};
  223. sample_ret = sample_ecc256_compute_shared_dhkey(&priv_key,
  224. (sample_ec256_public_t *)&p_msg1->g_a,
  225. (sample_ec256_dh_shared_t *)&dh_key,
  226. ecc_state);
  227. if(SAMPLE_SUCCESS != sample_ret)
  228. {
  229. fprintf(stderr, "\nError, compute share key fail in [%s].",
  230. __FUNCTION__);
  231. ret = SP_INTERNAL_ERROR;
  232. break;
  233. }
  234. #ifdef SUPPLIED_KEY_DERIVATION
  235. // smk is only needed for msg2 generation.
  236. derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SMK_SK,
  237. &g_sp_db.smk_key, &g_sp_db.sk_key);
  238. if(derive_ret != true)
  239. {
  240. fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
  241. ret = SP_INTERNAL_ERROR;
  242. break;
  243. }
  244. // The rest of the keys are the shared secrets for future communication.
  245. derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_MK_VK,
  246. &g_sp_db.mk_key, &g_sp_db.vk_key);
  247. if(derive_ret != true)
  248. {
  249. fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
  250. ret = SP_INTERNAL_ERROR;
  251. break;
  252. }
  253. #else
  254. // smk is only needed for msg2 generation.
  255. derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SMK,
  256. &g_sp_db.smk_key);
  257. if(derive_ret != true)
  258. {
  259. fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
  260. ret = SP_INTERNAL_ERROR;
  261. break;
  262. }
  263. // The rest of the keys are the shared secrets for future communication.
  264. derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_MK,
  265. &g_sp_db.mk_key);
  266. if(derive_ret != true)
  267. {
  268. fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
  269. ret = SP_INTERNAL_ERROR;
  270. break;
  271. }
  272. derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SK,
  273. &g_sp_db.sk_key);
  274. if(derive_ret != true)
  275. {
  276. fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
  277. ret = SP_INTERNAL_ERROR;
  278. break;
  279. }
  280. derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_VK,
  281. &g_sp_db.vk_key);
  282. if(derive_ret != true)
  283. {
  284. fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
  285. ret = SP_INTERNAL_ERROR;
  286. break;
  287. }
  288. #endif
  289. uint32_t msg2_size = sizeof(sample_ra_msg2_t) + sig_rl_size;
  290. p_msg2_full = (ra_samp_response_header_t*)malloc(msg2_size
  291. + sizeof(ra_samp_response_header_t));
  292. if(!p_msg2_full)
  293. {
  294. fprintf(stderr, "\nError, out of memory in [%s].", __FUNCTION__);
  295. ret = SP_INTERNAL_ERROR;
  296. break;
  297. }
  298. memset(p_msg2_full, 0, msg2_size + sizeof(ra_samp_response_header_t));
  299. p_msg2_full->type = TYPE_RA_MSG2;
  300. p_msg2_full->size = msg2_size;
  301. // The simulated message2 always passes. This would need to be set
  302. // accordingly in a real service provider implementation.
  303. p_msg2_full->status[0] = 0;
  304. p_msg2_full->status[1] = 0;
  305. p_msg2 = (sample_ra_msg2_t *)p_msg2_full->body;
  306. // Assemble MSG2
  307. if(memcpy_s(&p_msg2->g_b, sizeof(p_msg2->g_b), &g_sp_db.g_b,
  308. sizeof(g_sp_db.g_b)) ||
  309. memcpy_s(&p_msg2->spid, sizeof(sample_spid_t),
  310. &g_spid, sizeof(g_spid)))
  311. {
  312. fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
  313. ret = SP_INTERNAL_ERROR;
  314. break;
  315. }
  316. // The service provider is responsible for selecting the proper EPID
  317. // signature type and to understand the implications of the choice!
  318. p_msg2->quote_type = SAMPLE_QUOTE_LINKABLE_SIGNATURE;
  319. #ifdef SUPPLIED_KEY_DERIVATION
  320. //isv defined key derivation function id
  321. #define ISV_KDF_ID 2
  322. p_msg2->kdf_id = ISV_KDF_ID;
  323. #else
  324. p_msg2->kdf_id = SAMPLE_AES_CMAC_KDF_ID;
  325. #endif
  326. // Create gb_ga
  327. sample_ec_pub_t gb_ga[2];
  328. if(memcpy_s(&gb_ga[0], sizeof(gb_ga[0]), &g_sp_db.g_b,
  329. sizeof(g_sp_db.g_b))
  330. || memcpy_s(&gb_ga[1], sizeof(gb_ga[1]), &g_sp_db.g_a,
  331. sizeof(g_sp_db.g_a)))
  332. {
  333. fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
  334. ret = SP_INTERNAL_ERROR;
  335. break;
  336. }
  337. // Sign gb_ga
  338. sample_ret = sample_ecdsa_sign((uint8_t *)&gb_ga, sizeof(gb_ga),
  339. (sample_ec256_private_t *)&g_sp_priv_key,
  340. (sample_ec256_signature_t *)&p_msg2->sign_gb_ga,
  341. ecc_state);
  342. if(SAMPLE_SUCCESS != sample_ret)
  343. {
  344. fprintf(stderr, "\nError, sign ga_gb fail in [%s].", __FUNCTION__);
  345. ret = SP_INTERNAL_ERROR;
  346. break;
  347. }
  348. // Generate the CMACsmk for gb||SPID||TYPE||KDF_ID||Sigsp(gb,ga)
  349. uint8_t mac[SAMPLE_EC_MAC_SIZE] = {0};
  350. uint32_t cmac_size = offsetof(sample_ra_msg2_t, mac);
  351. sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.smk_key,
  352. (uint8_t *)&p_msg2->g_b, cmac_size, &mac);
  353. if(SAMPLE_SUCCESS != sample_ret)
  354. {
  355. fprintf(stderr, "\nError, cmac fail in [%s].", __FUNCTION__);
  356. ret = SP_INTERNAL_ERROR;
  357. break;
  358. }
  359. if(memcpy_s(&p_msg2->mac, sizeof(p_msg2->mac), mac, sizeof(mac)))
  360. {
  361. fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
  362. ret = SP_INTERNAL_ERROR;
  363. break;
  364. }
  365. if(memcpy_s(&p_msg2->sig_rl[0], sig_rl_size, sig_rl, sig_rl_size))
  366. {
  367. fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
  368. ret = SP_INTERNAL_ERROR;
  369. break;
  370. }
  371. p_msg2->sig_rl_size = sig_rl_size;
  372. }while(0);
  373. if(ret)
  374. {
  375. *pp_msg2 = NULL;
  376. SAFE_FREE(p_msg2_full);
  377. }
  378. else
  379. {
  380. // Freed by the network simulator in ra_free_network_response_buffer
  381. *pp_msg2 = p_msg2_full;
  382. }
  383. if(ecc_state)
  384. {
  385. sample_ecc256_close_context(ecc_state);
  386. }
  387. return ret;
  388. }
  389. // Process remote attestation message 3
  390. int sp_ra_proc_msg3_req(const sample_ra_msg3_t *p_msg3,
  391. uint32_t msg3_size,
  392. ra_samp_response_header_t **pp_att_result_msg)
  393. {
  394. int ret = 0;
  395. sample_status_t sample_ret = SAMPLE_SUCCESS;
  396. const uint8_t *p_msg3_cmaced = NULL;
  397. sample_quote_t *p_quote = NULL;
  398. sample_sha_state_handle_t sha_handle = NULL;
  399. sample_report_data_t report_data = {0};
  400. sample_ra_att_result_msg_t *p_att_result_msg = NULL;
  401. ra_samp_response_header_t* p_att_result_msg_full = NULL;
  402. uint32_t i;
  403. if((!p_msg3) ||
  404. (msg3_size < sizeof(sample_ra_msg3_t)) ||
  405. (!pp_att_result_msg))
  406. {
  407. return SP_INTERNAL_ERROR;
  408. }
  409. // Check to see if we have registered?
  410. if (!g_is_sp_registered)
  411. {
  412. return SP_UNSUPPORTED_EXTENDED_EPID_GROUP;
  413. }
  414. do
  415. {
  416. // Compare g_a in message 3 with local g_a.
  417. ret = memcmp(&g_sp_db.g_a, &p_msg3->g_a, sizeof(sample_ec_pub_t));
  418. if(ret)
  419. {
  420. fprintf(stderr, "\nError, g_a is not same [%s].", __FUNCTION__);
  421. ret = SP_PROTOCOL_ERROR;
  422. break;
  423. }
  424. //Make sure that msg3_size is bigger than sample_mac_t.
  425. uint32_t mac_size = msg3_size - sizeof(sample_mac_t);
  426. p_msg3_cmaced = reinterpret_cast<const uint8_t*>(p_msg3);
  427. p_msg3_cmaced += sizeof(sample_mac_t);
  428. // Verify the message mac using SMK
  429. sample_cmac_128bit_tag_t mac = {0};
  430. sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.smk_key,
  431. p_msg3_cmaced,
  432. mac_size,
  433. &mac);
  434. if(SAMPLE_SUCCESS != sample_ret)
  435. {
  436. fprintf(stderr, "\nError, cmac fail in [%s].", __FUNCTION__);
  437. ret = SP_INTERNAL_ERROR;
  438. break;
  439. }
  440. // In real implementation, should use a time safe version of memcmp here,
  441. // in order to avoid side channel attack.
  442. ret = memcmp(&p_msg3->mac, mac, sizeof(mac));
  443. if(ret)
  444. {
  445. fprintf(stderr, "\nError, verify cmac fail [%s].", __FUNCTION__);
  446. ret = SP_INTEGRITY_FAILED;
  447. break;
  448. }
  449. if(memcpy_s(&g_sp_db.ps_sec_prop, sizeof(g_sp_db.ps_sec_prop),
  450. &p_msg3->ps_sec_prop, sizeof(p_msg3->ps_sec_prop)))
  451. {
  452. fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
  453. ret = SP_INTERNAL_ERROR;
  454. break;
  455. }
  456. p_quote = (sample_quote_t *)p_msg3->quote;
  457. // Check the quote version if needed. Only check the Quote.version field if the enclave
  458. // identity fields have changed or the size of the quote has changed. The version may
  459. // change without affecting the legacy fields or size of the quote structure.
  460. //if(p_quote->version < ACCEPTED_QUOTE_VERSION)
  461. //{
  462. // fprintf(stderr,"\nError, quote version is too old.", __FUNCTION__);
  463. // ret = SP_QUOTE_VERSION_ERROR;
  464. // break;
  465. //}
  466. // Verify the report_data in the Quote matches the expected value.
  467. // The first 32 bytes of report_data are SHA256 HASH of {ga|gb|vk}.
  468. // The second 32 bytes of report_data are set to zero.
  469. sample_ret = sample_sha256_init(&sha_handle);
  470. if(sample_ret != SAMPLE_SUCCESS)
  471. {
  472. fprintf(stderr,"\nError, init hash failed in [%s].", __FUNCTION__);
  473. ret = SP_INTERNAL_ERROR;
  474. break;
  475. }
  476. sample_ret = sample_sha256_update((uint8_t *)&(g_sp_db.g_a),
  477. sizeof(g_sp_db.g_a), sha_handle);
  478. if(sample_ret != SAMPLE_SUCCESS)
  479. {
  480. fprintf(stderr,"\nError, udpate hash failed in [%s].",
  481. __FUNCTION__);
  482. ret = SP_INTERNAL_ERROR;
  483. break;
  484. }
  485. sample_ret = sample_sha256_update((uint8_t *)&(g_sp_db.g_b),
  486. sizeof(g_sp_db.g_b), sha_handle);
  487. if(sample_ret != SAMPLE_SUCCESS)
  488. {
  489. fprintf(stderr,"\nError, udpate hash failed in [%s].",
  490. __FUNCTION__);
  491. ret = SP_INTERNAL_ERROR;
  492. break;
  493. }
  494. sample_ret = sample_sha256_update((uint8_t *)&(g_sp_db.vk_key),
  495. sizeof(g_sp_db.vk_key), sha_handle);
  496. if(sample_ret != SAMPLE_SUCCESS)
  497. {
  498. fprintf(stderr,"\nError, udpate hash failed in [%s].",
  499. __FUNCTION__);
  500. ret = SP_INTERNAL_ERROR;
  501. break;
  502. }
  503. sample_ret = sample_sha256_get_hash(sha_handle,
  504. (sample_sha256_hash_t *)&report_data);
  505. if(sample_ret != SAMPLE_SUCCESS)
  506. {
  507. fprintf(stderr,"\nError, Get hash failed in [%s].", __FUNCTION__);
  508. ret = SP_INTERNAL_ERROR;
  509. break;
  510. }
  511. ret = memcmp((uint8_t *)&report_data,
  512. (uint8_t *)&(p_quote->report_body.report_data),
  513. sizeof(report_data));
  514. if(ret)
  515. {
  516. fprintf(stderr, "\nError, verify hash fail [%s].", __FUNCTION__);
  517. ret = SP_INTEGRITY_FAILED;
  518. break;
  519. }
  520. // Verify Enclave policy (an attestation server may provide an API for this if we
  521. // registered an Enclave policy)
  522. // Verify quote with attestation server.
  523. // In the product, an attestation server could use a REST message and JSON formatting to request
  524. // attestation Quote verification. The sample only simulates this interface.
  525. ias_att_report_t attestation_report = {0};
  526. ret = g_sp_extended_epid_group_id->verify_attestation_evidence(p_quote, NULL,
  527. &attestation_report);
  528. if(0 != ret)
  529. {
  530. ret = SP_IAS_FAILED;
  531. break;
  532. }
  533. FILE* OUTPUT = stdout;
  534. fprintf(OUTPUT, "\n\n\tAttestation Report:");
  535. fprintf(OUTPUT, "\n\tid: 0x%0x.", attestation_report.id);
  536. fprintf(OUTPUT, "\n\tstatus: %d.", attestation_report.status);
  537. fprintf(OUTPUT, "\n\trevocation_reason: %u.",
  538. attestation_report.revocation_reason);
  539. // attestation_report.info_blob;
  540. fprintf(OUTPUT, "\n\tpse_status: %d.", attestation_report.pse_status);
  541. // Note: This sample always assumes the PIB is sent by attestation server. In the product
  542. // implementation, the attestation server could only send the PIB for certain attestation
  543. // report statuses. A product SP implementation needs to handle cases
  544. // where the PIB is zero length.
  545. // Respond the client with the results of the attestation.
  546. uint32_t att_result_msg_size = sizeof(sample_ra_att_result_msg_t);
  547. p_att_result_msg_full =
  548. (ra_samp_response_header_t*)malloc(att_result_msg_size
  549. + sizeof(ra_samp_response_header_t) + sizeof(g_secret));
  550. if(!p_att_result_msg_full)
  551. {
  552. fprintf(stderr, "\nError, out of memory in [%s].", __FUNCTION__);
  553. ret = SP_INTERNAL_ERROR;
  554. break;
  555. }
  556. memset(p_att_result_msg_full, 0, att_result_msg_size
  557. + sizeof(ra_samp_response_header_t) + sizeof(g_secret));
  558. p_att_result_msg_full->type = TYPE_RA_ATT_RESULT;
  559. p_att_result_msg_full->size = att_result_msg_size;
  560. if(IAS_QUOTE_OK != attestation_report.status)
  561. {
  562. p_att_result_msg_full->status[0] = 0xFF;
  563. }
  564. if(IAS_PSE_OK != attestation_report.pse_status)
  565. {
  566. p_att_result_msg_full->status[1] = 0xFF;
  567. }
  568. p_att_result_msg =
  569. (sample_ra_att_result_msg_t *)p_att_result_msg_full->body;
  570. // In a product implementation of attestation server, the HTTP response header itself could have
  571. // an RK based signature that the service provider needs to check here.
  572. // The platform_info_blob signature will be verified by the client
  573. // when sent. No need to have the Service Provider to check it. The SP
  574. // should pass it down to the application for further analysis.
  575. fprintf(OUTPUT, "\n\n\tEnclave Report:");
  576. fprintf(OUTPUT, "\n\tSignature Type: 0x%x", p_quote->sign_type);
  577. fprintf(OUTPUT, "\n\tSignature Basename: ");
  578. for(i=0; i<sizeof(p_quote->basename.name) && p_quote->basename.name[i];
  579. i++)
  580. {
  581. fprintf(OUTPUT, "%c", p_quote->basename.name[i]);
  582. }
  583. #ifdef __x86_64__
  584. fprintf(OUTPUT, "\n\tattributes.flags: 0x%0lx",
  585. p_quote->report_body.attributes.flags);
  586. fprintf(OUTPUT, "\n\tattributes.xfrm: 0x%0lx",
  587. p_quote->report_body.attributes.xfrm);
  588. #else
  589. fprintf(OUTPUT, "\n\tattributes.flags: 0x%0llx",
  590. p_quote->report_body.attributes.flags);
  591. fprintf(OUTPUT, "\n\tattributes.xfrm: 0x%0llx",
  592. p_quote->report_body.attributes.xfrm);
  593. #endif
  594. fprintf(OUTPUT, "\n\tmr_enclave: ");
  595. for(i=0;i<sizeof(sample_measurement_t);i++)
  596. {
  597. fprintf(OUTPUT, "%02x",p_quote->report_body.mr_enclave[i]);
  598. //fprintf(stderr, "%02x",p_quote->report_body.mr_enclave.m[i]);
  599. }
  600. fprintf(OUTPUT, "\n\tmr_signer: ");
  601. for(i=0;i<sizeof(sample_measurement_t);i++)
  602. {
  603. fprintf(OUTPUT, "%02x",p_quote->report_body.mr_signer[i]);
  604. //fprintf(stderr, "%02x",p_quote->report_body.mr_signer.m[i]);
  605. }
  606. fprintf(OUTPUT, "\n\tisv_prod_id: 0x%0x",
  607. p_quote->report_body.isv_prod_id);
  608. fprintf(OUTPUT, "\n\tisv_svn: 0x%0x",p_quote->report_body.isv_svn);
  609. fprintf(OUTPUT, "\n");
  610. // A product service provider needs to verify that its enclave properties
  611. // match what is expected. The SP needs to check these values before
  612. // trusting the enclave. For the sample, we always pass the policy check.
  613. // Attestation server only verifies the quote structure and signature. It does not
  614. // check the identity of the enclave.
  615. bool isv_policy_passed = true;
  616. // Assemble Attestation Result Message
  617. // Note, this is a structure copy. We don't copy the policy reports
  618. // right now.
  619. p_att_result_msg->platform_info_blob = attestation_report.info_blob;
  620. // Generate mac based on the mk key.
  621. mac_size = sizeof(ias_platform_info_blob_t);
  622. sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.mk_key,
  623. (const uint8_t*)&p_att_result_msg->platform_info_blob,
  624. mac_size,
  625. &p_att_result_msg->mac);
  626. if(SAMPLE_SUCCESS != sample_ret)
  627. {
  628. fprintf(stderr, "\nError, cmac fail in [%s].", __FUNCTION__);
  629. ret = SP_INTERNAL_ERROR;
  630. break;
  631. }
  632. // Generate shared secret and encrypt it with SK, if attestation passed.
  633. uint8_t aes_gcm_iv[SAMPLE_SP_IV_SIZE] = {0};
  634. p_att_result_msg->secret.payload_size = 8;
  635. if((IAS_QUOTE_OK == attestation_report.status) &&
  636. (IAS_PSE_OK == attestation_report.pse_status) &&
  637. (isv_policy_passed == true))
  638. {
  639. ret = sample_rijndael128GCM_encrypt(&g_sp_db.sk_key,
  640. &g_secret[0],
  641. p_att_result_msg->secret.payload_size,
  642. p_att_result_msg->secret.payload,
  643. &aes_gcm_iv[0],
  644. SAMPLE_SP_IV_SIZE,
  645. NULL,
  646. 0,
  647. &p_att_result_msg->secret.payload_tag);
  648. }
  649. }while(0);
  650. if(ret)
  651. {
  652. *pp_att_result_msg = NULL;
  653. SAFE_FREE(p_att_result_msg_full);
  654. }
  655. else
  656. {
  657. // Freed by the network simulator in ra_free_network_response_buffer
  658. *pp_att_result_msg = p_att_result_msg_full;
  659. }
  660. return ret;
  661. }