monotonic_counter_database_sqlite_bin_hash_tree_utility.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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 "monotonic_counter_database_sqlite_bin_hash_tree_utility.h"
  32. #include "monotonic_counter_database_sqlite_access_hw_mc.h"
  33. #include "pse_op_t.h"
  34. #include "monotonic_counter_database_sqlite_cache.h"
  35. #include "util.h"
  36. #include "t_pairing_blob.h"
  37. #include "monotonic_counter_database_sqlite_check_error.h"
  38. #include "psda_service.h"
  39. #include "sgx_tcrypto.h"
  40. #include "sgx_sha256_128.h"
  41. #define CHECK_ERROR_CODE(ret, lable) if(OP_SUCCESS != ret) { ret = OP_ERROR_INTERNAL; goto lable; }
  42. #define ASSEMBLE_SELF_BROTHER(id,buf,self,brother,size) \
  43. if(IS_LEFT_CHILD(id)) {memcpy(buf,self,size); memcpy(((uint8_t*)buf)+(size),brother,size);} \
  44. else {memcpy(buf,brother,size); memcpy(((uint8_t*)buf)+(size),self,size);}
  45. static pse_op_error_t g_mc_service_status = OP_ERROR_INTERNAL; // indicates VMC service status
  46. /*******************************************************************
  47. ** Function name: get_mc_service_status
  48. ** Descrption: get monotonic counter service status
  49. **
  50. *******************************************************************/
  51. pse_op_error_t get_mc_service_status()
  52. {
  53. return g_mc_service_status;
  54. }
  55. /*******************************************************************
  56. ** Function name: set_related_nodes_ids
  57. ** Descrption: set all related nodes id into the cache structure
  58. **
  59. *******************************************************************/
  60. void set_related_nodes_ids(uint32_t leaf_node_index, pse_vmc_hash_tree_cache_t* cache)
  61. {
  62. assert(cache != NULL);
  63. uint32_t node_index = leaf_node_index;
  64. uint32_t ancestor_index = leaf_node_index;
  65. uint32_t i = 0;
  66. cache->self.node_id = leaf_node_index;
  67. cache->brother.node_id = IS_LEFT_CHILD(node_index) ? (node_index+1) : (node_index-1);;
  68. ancestor_index = ( ancestor_index - ancestor_index%2 ) >> 1 ;
  69. while (ancestor_index != 1)
  70. {
  71. cache->ancestors[i].node_id = ancestor_index;
  72. cache->brother_of_ancestors[i].node_id =
  73. IS_LEFT_CHILD(ancestor_index) ? (ancestor_index+1) : (ancestor_index-1);
  74. ancestor_index = ( ancestor_index - ancestor_index%2 ) >> 1 ;
  75. i++;
  76. }
  77. }
  78. /*******************************************************************
  79. ** Function name: update_related_nodes_of_leaf
  80. ** Descrption: Update all related nodes of a leaf node
  81. **
  82. *******************************************************************/
  83. pse_op_error_t update_related_nodes_of_leaf(pse_vmc_hash_tree_cache_t* cache,
  84. leafnode_flag_op_type flag_op)
  85. {
  86. pse_op_error_t ret = OP_SUCCESS;
  87. uint8_t hash[HASH_VALUE_SIZE] = {0};
  88. uint8_t root_hash[ROOT_HASH_SIZE] = {0};
  89. hash_tree_leaf_node_t leaf[2];
  90. sgx_status_t stat = SGX_SUCCESS;
  91. uint32_t index = 0;
  92. cal_root_hash_buf_t tmp;
  93. if(SET_LEAFNODE_FLAG == flag_op)
  94. {
  95. cache->self.leaf.is_used = 1;
  96. }
  97. else if(CLR_LEAFNODE_FLAG == flag_op)
  98. {
  99. cache->self.leaf.is_used = 0;
  100. }
  101. //update hash value for the ancestor of the leaf node
  102. ASSEMBLE_SELF_BROTHER(cache->self.node_id,
  103. &leaf[0],
  104. &cache->self.leaf,
  105. &cache->brother.leaf,
  106. LEAF_NODE_SIZE);
  107. stat = sgx_sha256_msg((uint8_t*)leaf,
  108. 2*LEAF_NODE_SIZE,
  109. (sgx_sha256_hash_t*)hash);
  110. if(stat != SGX_SUCCESS)
  111. {
  112. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  113. ret = OP_ERROR_INTERNAL;
  114. goto end;
  115. }
  116. memcpy(cache->ancestors[0].internal.hash, hash, HASH_VALUE_SIZE);
  117. // update internal nodes
  118. uint8_t internal_node_hash[HASH_VALUE_SIZE*2];
  119. for(index=0; index<(INIT_INTERNAL_NODE_NR-1); index++)
  120. {
  121. ASSEMBLE_SELF_BROTHER(cache->ancestors[index].node_id,
  122. &internal_node_hash[0],
  123. cache->ancestors[index].internal.hash,
  124. cache->brother_of_ancestors[index].internal.hash,
  125. HASH_VALUE_SIZE);
  126. stat = sgx_sha256_msg((uint8_t*)internal_node_hash,
  127. HASH_VALUE_SIZE*2,
  128. (sgx_sha256_hash_t*)hash);
  129. if(stat != SGX_SUCCESS)
  130. {
  131. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  132. ret = OP_ERROR_INTERNAL;
  133. goto end;
  134. }
  135. memcpy(cache->ancestors[index+1].internal.hash, hash, HASH_VALUE_SIZE);
  136. }
  137. // update root node
  138. memset(&tmp, 0, sizeof(cal_root_hash_buf_t));
  139. // now, ancestor_node points to ROOT and brother_node points to the child of ROOT
  140. // determine side of the node
  141. index = INIT_INTERNAL_NODE_NR-1;
  142. ASSEMBLE_SELF_BROTHER(cache->ancestors[index].node_id,
  143. &tmp.children_hash[0],
  144. cache->ancestors[index].internal.hash,
  145. cache->brother_of_ancestors[index].internal.hash,
  146. HASH_VALUE_SIZE);
  147. if (!copy_global_pairing_nonce(&tmp.pairing_nonce[0]))
  148. {
  149. ret = OP_ERROR_INTERNAL;
  150. goto end;
  151. }
  152. ret = get_cached_rpepoch(&tmp.rp_epoch);
  153. CHECK_ERROR_CODE(ret, end)
  154. // calculate sha256-128 for root node
  155. stat = sgx_sha256_128_msg((const uint8_t *)&tmp, sizeof(cal_root_hash_buf_t), (sgx_sha256_128_hash_t*)root_hash);
  156. if (stat != SGX_SUCCESS)
  157. {
  158. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  159. ret = OP_ERROR_INTERNAL;
  160. goto end;
  161. }
  162. memcpy(cache->root.hash, root_hash, ROOT_HASH_SIZE);
  163. end:
  164. return ret;
  165. }
  166. /********************************************************************************
  167. * @brief Verify the related nodes of a leaf node
  168. *
  169. * @param pse_vmc_hash_tree_cache_t All related nodes of the leaf node, including the leaf node itself
  170. * @param invalid_node_id [out] To store invalid node id when verification fails.
  171. *
  172. * @return SGX_SUCCESS for a successful verification.
  173. ********************************************************************************/
  174. // split it to different levels
  175. pse_op_error_t verify_related_nodes_of_leaf(const pse_vmc_hash_tree_cache_t* cache,
  176. uint32_t* invalid_node_id)
  177. {
  178. sgx_status_t stat = SGX_SUCCESS;
  179. pse_op_error_t ret = OP_SUCCESS;
  180. uint8_t rpdata_roothash[ROOT_HASH_SIZE] = {0};
  181. uint8_t hash[HASH_VALUE_SIZE] = {0};
  182. uint8_t root_hash[ROOT_HASH_SIZE] = {0};
  183. hash_tree_leaf_node_t leaf[2];
  184. uint32_t index = 0;
  185. cal_root_hash_buf_t tmp;
  186. assert(cache != NULL);
  187. assert(invalid_node_id != NULL);
  188. ////////////////////////////////////////////
  189. // FINISH TO CHECK THE INPUT PARAMETERS //
  190. // FRIST, VERIFY THE ROOT NODE //
  191. ////////////////////////////////////////////
  192. memset(&tmp, 0, sizeof(cal_root_hash_buf_t));
  193. // need to determine the left child of the root is in bro or par node array
  194. index = INIT_INTERNAL_NODE_NR - 1;
  195. ASSEMBLE_SELF_BROTHER(cache->ancestors[index].node_id,
  196. &tmp.children_hash[0],
  197. cache->ancestors[index].internal.hash,
  198. cache->brother_of_ancestors[index].internal.hash,
  199. HASH_VALUE_SIZE);
  200. ret = get_cached_roothash(rpdata_roothash);
  201. CHECK_ERROR_CODE(ret, end)
  202. ret = get_cached_rpepoch(&tmp.rp_epoch);
  203. CHECK_ERROR_CODE(ret, end)
  204. if (!copy_global_pairing_nonce(&tmp.pairing_nonce[0]))
  205. {
  206. ret = OP_ERROR_INTERNAL;
  207. goto end;
  208. }
  209. // calculate SHA256-128 for root node
  210. stat = sgx_sha256_128_msg((const uint8_t *)&tmp, sizeof(cal_root_hash_buf_t), (sgx_sha256_128_hash_t*)root_hash);
  211. if(stat != SGX_SUCCESS)
  212. {
  213. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  214. ret = OP_ERROR_INTERNAL;
  215. goto end;
  216. }
  217. if(0 != memcmp(root_hash, rpdata_roothash, ROOT_HASH_SIZE))
  218. {
  219. // this indicates that the whole hash tree is invalid.
  220. ret = OP_ERROR_INVALID_VMC_DB;
  221. *invalid_node_id = 1; // ROOT
  222. goto end;
  223. }
  224. ////////////////////////////////////////////////////////////////////
  225. // Second, VERIFY THE INTERNAL NODES //
  226. ////////////////////////////////////////////////////////////////////
  227. uint8_t internal_nodes_hash[HASH_VALUE_SIZE*2];
  228. for (index = INIT_INTERNAL_NODE_NR - 1; index > 0; index--)
  229. {
  230. ASSEMBLE_SELF_BROTHER(cache->ancestors[index-1].node_id,
  231. &internal_nodes_hash[0],
  232. cache->ancestors[index-1].internal.hash,
  233. cache->brother_of_ancestors[index-1].internal.hash,
  234. HASH_VALUE_SIZE);
  235. // calculate hash value
  236. stat = sgx_sha256_msg((uint8_t*)internal_nodes_hash,
  237. HASH_VALUE_SIZE*2,
  238. (sgx_sha256_hash_t*)hash);
  239. if(stat != SGX_SUCCESS)
  240. {
  241. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  242. ret = OP_ERROR_INTERNAL;
  243. goto end;
  244. }
  245. if(0 != memcmp(hash, cache->ancestors[index].internal.hash, HASH_VALUE_SIZE))
  246. {
  247. ret = OP_ERROR_INVALID_VMC_DB;
  248. *invalid_node_id = cache->ancestors[index].node_id;
  249. goto end;
  250. }
  251. }
  252. ////////////////////////////////////////////////////////////////////
  253. // Last, VERIFY THE LEAF NODE //
  254. ////////////////////////////////////////////////////////////////////
  255. ASSEMBLE_SELF_BROTHER(cache->self.node_id,
  256. &leaf[0],
  257. &cache->self.leaf,
  258. &cache->brother.leaf,
  259. LEAF_NODE_SIZE);
  260. stat = sgx_sha256_msg((uint8_t*)leaf,
  261. 2*LEAF_NODE_SIZE,
  262. (sgx_sha256_hash_t*)hash);
  263. if(stat != SGX_SUCCESS)
  264. {
  265. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  266. ret = OP_ERROR_INTERNAL;
  267. goto end;
  268. }
  269. if(0 != memcmp(hash, cache->ancestors[0].internal.hash, HASH_VALUE_SIZE))
  270. {
  271. ret = OP_ERROR_INVALID_VMC_DB;
  272. *invalid_node_id = cache->ancestors[0].node_id;
  273. goto end;
  274. }
  275. end:
  276. return ret;
  277. }
  278. /*******************************************************************
  279. ** Function name: get_db_children_of_root
  280. ** Descrption: read children nodes of the root from SQLite VMC Database.
  281. **
  282. *******************************************************************/
  283. pse_op_error_t get_db_children_of_root(pse_vmc_children_of_root_t* children)
  284. {
  285. pse_op_error_t retval;
  286. sgx_status_t stat = SGX_SUCCESS;
  287. assert(children != NULL);
  288. // OCALL
  289. stat = sqlite_read_children_of_root(&retval, children);
  290. if (stat != SGX_SUCCESS)
  291. {
  292. return OP_ERROR_INTERNAL;
  293. }
  294. return retval;
  295. }
  296. /*******************************************************************
  297. ** Function name: initialize_sqlite_database_file
  298. ** Descrption: Initialize VMC database. If vmc db already exists, this function loads
  299. ** and verifies the root node. It also tries to recover the vmc db from an
  300. ** unstable state. If vmc db doesn't exist or is_for_empty_db_creation is true
  301. ** this function will create a new vmc database.
  302. *******************************************************************/
  303. pse_op_error_t initialize_sqlite_database_file(bool is_for_empty_db_creation)
  304. {
  305. pse_op_error_t ret = OP_ERROR_INTERNAL;
  306. sgx_status_t stat = SGX_SUCCESS;
  307. cal_root_hash_buf_t cal_root_hash_buf;
  308. hash_tree_internal_node_t internal_node;
  309. hash_tree_root_node_t pre_calculated_root_node;
  310. memset(&cal_root_hash_buf, 0, sizeof(cal_root_hash_buf));
  311. memset(&pre_calculated_root_node, 0, sizeof(pre_calculated_root_node));
  312. flush_hash_tree_cache(); // remove all cached hash tree nodes from cache memory
  313. // Read RPDATA from CSE.
  314. if ((ret = read_rpdata()) != OP_SUCCESS)
  315. {
  316. g_mc_service_status = ret;
  317. return ret;
  318. }
  319. // After reading CSE RPDATA, it's safe to use cached rpdata and rpepoch from now on
  320. if(!is_for_empty_db_creation)
  321. {
  322. // check if DB exists and verify root node by root hash
  323. ret = pse_vmc_database_check_error();
  324. if(OP_ERROR_DATABASE_FATAL == ret || OP_ERROR_INVALID_VMC_DB == ret)
  325. {
  326. // Database is broken, proceed to re-initialization process
  327. }
  328. else
  329. {
  330. g_mc_service_status = ret;
  331. return ret;
  332. }
  333. }
  334. // Clear PSDA's RPDATA first
  335. //
  336. //If reset_rpdata() caused the RPEPCOH change in CSME but the full operation (reporting the success back to PSE-Op) somehow failed,
  337. //the mismatch between the RPEPOCH cache and the RPEPOCH in CSME will flag potential attack on all RPDATA operation.
  338. //To allow recovery from RPEPOCH mismatch resulted from partial reset_rpdata() operation,
  339. //reset the RPEPOCH/RPDATA cache.
  340. //It's safe to clear the RPEPOCH cache in the VMC service initialization flow,
  341. //because no VMC operation can proceed without a successful VMC service initialization.
  342. if ((ret = reset_rpdata()) != OP_SUCCESS)
  343. {
  344. // clear RPDATA cache to handle the situation that the reset_rpdata() caused the RPEPCOH change in CSME
  345. // but the full operation (reporting the success back to PSE-Op) somehow failed.
  346. clear_cached_rpdata();
  347. goto clean_up;
  348. }
  349. // find children's hash value of the root node from precalculatated internal_node_hash_value_table
  350. memcpy(internal_node.hash, &(internal_node_hash_value_table[INIT_MAX_HASH_TREE_LAYER-3][0]), HASH_VALUE_SIZE);
  351. memcpy(cal_root_hash_buf.children_hash, internal_node.hash, HASH_VALUE_SIZE);
  352. memcpy(cal_root_hash_buf.children_hash + HASH_VALUE_SIZE, internal_node.hash, HASH_VALUE_SIZE);
  353. // copy epoch
  354. ret = get_cached_rpepoch(&cal_root_hash_buf.rp_epoch);
  355. CHECK_ERROR_CODE(ret, clean_up)
  356. // copy pairing NONCE
  357. if (!copy_global_pairing_nonce(&cal_root_hash_buf.pairing_nonce[0]))
  358. {
  359. ret = OP_ERROR_INTERNAL;
  360. goto clean_up;
  361. }
  362. // calculate sha256-128 form root node
  363. stat = sgx_sha256_128_msg((const uint8_t *)&cal_root_hash_buf, sizeof(cal_root_hash_buf_t), (sgx_sha256_128_hash_t *)pre_calculated_root_node.hash);
  364. if (stat != SGX_SUCCESS)
  365. {
  366. assert(stat != SGX_ERROR_OUT_OF_MEMORY);
  367. ret = OP_ERROR_INTERNAL;
  368. goto clean_up;
  369. }
  370. // update PSDA's rpdata
  371. ret = update_rpdata(pre_calculated_root_node.hash);
  372. if(OP_SUCCESS != ret)
  373. {
  374. goto clean_up;
  375. }
  376. // OCALL db reinit
  377. stat = sqlite_db_init_hash_tree_table(&ret);
  378. if (stat != SGX_SUCCESS || ret != OP_SUCCESS)
  379. {
  380. ret = OP_ERROR_INTERNAL;
  381. }
  382. clean_up:
  383. g_mc_service_status = ret;
  384. return ret;
  385. }
  386. pse_op_error_t rollback_db_file()
  387. {
  388. // recovery from backuped DB file
  389. pse_op_error_t ret = OP_ERROR_INTERNAL;
  390. sgx_status_t stat = SGX_SUCCESS;
  391. // OCALL db recovery
  392. stat = sqlite_rollback_db_file(&ret);
  393. if (stat != SGX_SUCCESS || ret != OP_SUCCESS)
  394. {
  395. return OP_ERROR_INTERNAL;
  396. }
  397. return OP_SUCCESS;
  398. }