service_provider.cpp 24 KB

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