monotonic_counter_database_sqlite_rpdb.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  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_rpdb.h"
  32. #include "monotonic_counter_database_sqlite_access_hw_mc.h"
  33. #include "monotonic_counter_database_sqlite_bin_hash_tree_utility.h"
  34. #include "monotonic_counter_database_sqlite_cache.h"
  35. #include "pse_op_t.h"
  36. #include "util.h"
  37. #include "utility.h"
  38. #include "sgx_tcrypto.h"
  39. #define CHECK_ERROR_CODE(ret, lable) if(OP_SUCCESS != ret) { ret = OP_ERROR_INTERNAL; goto lable; }
  40. /*******************************************************************
  41. ** Function name: calculate_owner_id
  42. ** Descrption:
  43. ** Calculate VMC Access Control Information. An ID of the creator of a VMC is defined as:
  44. ** MR=[];
  45. ** If (OwnerPolicy.MRSIGNER==1) MR=MR||REPORT(creator).MRSIGNER;
  46. ** If (OwnerPolicy.MREnclave==1) MR=MR||REPORT(creator).MRENCLAVE;
  47. ** MaskedAttrs = REPORT(creator).ATTRIBUTES & OwnerAttrMask
  48. ** OwnerID =SHA256(MR||MaskedAttrs|| REPORT(creator).ProdID));
  49. *******************************************************************/
  50. static sgx_status_t calculate_owner_id(
  51. const isv_attributes_t &owner_attributes, // [IN] ISV's attributes info
  52. const uint16_t mc_policy, // [IN] user's access control policy
  53. const uint8_t* mc_att_mask, // [IN] attribute mask
  54. void* owner_id) // [OUT] ID of the creator of VMC
  55. {
  56. sgx_sha_state_handle_t ctx = NULL;
  57. sgx_status_t sgx_ret = SGX_SUCCESS;
  58. assert(owner_id != NULL && mc_att_mask != NULL);
  59. do
  60. {
  61. sgx_ret = sgx_sha256_init(&ctx);
  62. BREAK_ON_ERROR(sgx_ret);
  63. if (mc_policy & MC_POLICY_SIGNER)
  64. {
  65. sgx_ret = sgx_sha256_update((const uint8_t *)(&owner_attributes.mr_signer),
  66. sizeof(owner_attributes.mr_signer),
  67. ctx);
  68. BREAK_ON_ERROR(sgx_ret);
  69. }
  70. if (mc_policy & MC_POLICY_ENCLAVE)
  71. {
  72. sgx_ret = sgx_sha256_update((const uint8_t *)(&owner_attributes.mr_enclave),
  73. sizeof(owner_attributes.mr_enclave),
  74. ctx);
  75. BREAK_ON_ERROR(sgx_ret);
  76. }
  77. uint64_t masked_att_flags = owner_attributes.attribute.flags & *((const uint64_t*)mc_att_mask);
  78. sgx_ret = sgx_sha256_update((const uint8_t *)&masked_att_flags, sizeof(masked_att_flags), ctx);
  79. BREAK_ON_ERROR(sgx_ret);
  80. uint64_t masked_att_xfrm = owner_attributes.attribute.xfrm & *((const uint64_t*)(mc_att_mask+8));
  81. sgx_ret = sgx_sha256_update((const uint8_t *)&masked_att_xfrm, sizeof(masked_att_xfrm), ctx);
  82. BREAK_ON_ERROR(sgx_ret);
  83. sgx_ret = sgx_sha256_update((const uint8_t *)(&owner_attributes.isv_prod_id), sizeof(sgx_prod_id_t), ctx);
  84. BREAK_ON_ERROR(sgx_ret);
  85. sgx_ret = sgx_sha256_get_hash(ctx, (sgx_sha256_hash_t*)owner_id);
  86. BREAK_ON_ERROR(sgx_ret);
  87. } while (0);
  88. if(ctx)
  89. {
  90. sgx_status_t ret = sgx_sha256_close(ctx);
  91. sgx_ret = (sgx_ret != SGX_SUCCESS)? sgx_ret : ret;
  92. }
  93. return sgx_ret;
  94. }
  95. /*******************************************************************
  96. ** Function name: rpdb_accessible
  97. ** Descrption: check permission of accessing to a VMC entry, according to UUID and ISV's attributes.
  98. ** Return Value:
  99. ** OP_SUCCESS --- the ISV has access right of the VMC
  100. ** else ERROR --- the ISV doesn't have access right of the VMC
  101. **
  102. *******************************************************************/
  103. static pse_op_error_t rpdb_accessible(
  104. const isv_attributes_t &owner_attributes, //[in] ISV's attributes
  105. const vmc_data_blob_t &vmc) // [in] Points to VMC data blob buffer read from SQLite Database
  106. {
  107. uint8_t sha256_value[32] = {0};
  108. // calculate ID of ISV
  109. if(SGX_SUCCESS!= calculate_owner_id(owner_attributes, vmc.owner_policy, (const uint8_t*)(vmc.owner_attr_mask), sha256_value))
  110. {
  111. return OP_ERROR_INTERNAL;
  112. }
  113. // compare the ID of ISV and the ID of creator of the VMC entry.
  114. if(memcmp(sha256_value, vmc.owner_id, sizeof(sha256_value)))
  115. {
  116. return OP_ERROR_INVALID_OWNER;
  117. }
  118. // if ISV's SVN is less than the SVN of the VMC's creator, deny access.
  119. if (vmc.owner_svn > owner_attributes.isv_svn)
  120. {
  121. return OP_ERROR_INVALID_OWNER;
  122. }
  123. // PASS permission check.
  124. return OP_SUCCESS;
  125. }
  126. /*******************************************************************
  127. ** Function name: operate_vmc
  128. ** Descrption:
  129. ** This function perform READ or WRITE operation on VMC SQLite Database, which depends
  130. ** on the parameter rpdb_op.
  131. **
  132. *******************************************************************/
  133. static pse_op_error_t operate_vmc(const isv_attributes_t &owner_attributes, // [IN] ISV's attributes that
  134. const mc_rpdb_uuid_t &mc_rpdb_uuid, // [IN] UUID of VMC
  135. vmc_data_blob_t &rpdb, // [IN,OUT] Pointer that points to VMC data blob
  136. rpdb_op_t rpdb_op, // [IN] operation type
  137. op_leafnode_flag_t* op_leafnode_flag_info) // [IN] flag struture used to update USED flag in SQLite Database
  138. {
  139. pse_op_error_t rc = OP_SUCCESS;
  140. sgx_status_t stat = SGX_SUCCESS;
  141. uint32_t entry_index = 0;
  142. uint32_t leaf_id;
  143. uint32_t invalid_node_id;
  144. pse_vmc_hash_tree_cache_t cache;
  145. bool is_read_from_cache = false;
  146. uint8_t rpdata_roothash[ROOT_HASH_SIZE] = {0};
  147. memset(&cache, 0, sizeof(cache));
  148. // For CREATE/DELETE operation, op_leafnode_flag_info must point to a valid flag struture, since
  149. // the USED flag and QOUTA table in SQLite Database would be updated according to the flag info.
  150. assert(!((RPDB_OP_CREATE == rpdb_op || RPDB_OP_DELETE == rpdb_op) && !op_leafnode_flag_info));
  151. // get RPDB ID for UUID
  152. memcpy(&entry_index, mc_rpdb_uuid.entry_index, UUID_ENTRY_INDEX_SIZE);
  153. if(entry_index > (INIT_LEAF_NODE_ID_BASE-1))
  154. {
  155. return OP_ERROR_INVALID_COUNTER;
  156. }
  157. // Read the current RPDATA from CSME to check whether the cached vm db is not of date.
  158. // The newly read RPDATA_EPOCH must match the cached RPDATA_EPOCH.
  159. if ((rc = read_rpdata()) != OP_SUCCESS)
  160. {
  161. return rc;
  162. }
  163. if ((rc = get_cached_roothash(rpdata_roothash)) != OP_SUCCESS)
  164. {
  165. return rc;
  166. }
  167. // get LEAF ID from RPDB ID.
  168. leaf_id = entry_index + INIT_LEAF_NODE_ID_BASE;
  169. // set all related nodes ids
  170. set_related_nodes_ids(leaf_id, &cache);
  171. // check the cached vmc db root with current rpdata value
  172. // if the cached vmc db is not out of date, try to get all related nodes from cache
  173. rc = access_hash_tree_cache(rpdb_op, CACHE_OP_READ, &cache, rpdata_roothash);
  174. if(OP_SUCCESS == rc)
  175. {
  176. is_read_from_cache = true;
  177. }
  178. if(!is_read_from_cache)
  179. {
  180. // not found in the cache, need to read from VMC DB -- OCall
  181. stat = sqlite_read_db(&rc,
  182. leaf_id,
  183. &cache);
  184. if(OP_SUCCESS != rc || SGX_SUCCESS != stat)
  185. {
  186. if (stat != SGX_SUCCESS)
  187. {
  188. rc = OP_ERROR_INTERNAL;
  189. }
  190. goto clean_up;
  191. }
  192. // node ids may be modified in untrusted domain, so reset them
  193. set_related_nodes_ids(leaf_id, &cache);
  194. // verify the integrition of the data
  195. rc = verify_related_nodes_of_leaf(&cache, &invalid_node_id);
  196. if(OP_SUCCESS != rc)
  197. {
  198. goto clean_up;
  199. }
  200. }
  201. if(RPDB_OP_READ == rpdb_op)
  202. {
  203. // first check the is_used flag, a VMC must have been created before being read.
  204. if(0 == cache.self.leaf.is_used)
  205. {
  206. rc = OP_ERROR_INVALID_COUNTER;
  207. goto clean_up;
  208. }
  209. if(0 != memcmp(mc_rpdb_uuid.nonce, cache.self.leaf.nonce, UUID_NONCE_SIZE))
  210. {
  211. rc = OP_ERROR_INVALID_COUNTER;
  212. goto clean_up;
  213. }
  214. memcpy(&rpdb, &cache.self.leaf, LEAF_NODE_SIZE);
  215. if(!is_read_from_cache) // need to update caculated root into cache buffer
  216. {
  217. if ((rc = get_cached_roothash(cache.root.hash)) != OP_SUCCESS)
  218. {
  219. goto clean_up;
  220. }
  221. }
  222. rc = OP_SUCCESS;
  223. // for READ operation, return here.
  224. goto clean_up;
  225. }
  226. // READING RPDB won't reach here.
  227. assert(RPDB_OP_READ != rpdb_op);
  228. if(rpdb_op == RPDB_OP_CREATE) // CREATING VMC
  229. {
  230. if(0 != cache.self.leaf.is_used)
  231. {
  232. rc = OP_ERROR_INTERNAL;
  233. goto clean_up;
  234. }
  235. }
  236. else // INCREMENTING and DELETING VMC need access right.
  237. {
  238. // first check the is_used flag, a VMC must have been created before being read.
  239. if(0 == cache.self.leaf.is_used)
  240. {
  241. rc = OP_ERROR_INVALID_COUNTER;
  242. goto clean_up;
  243. }
  244. // nonce must be the same with the value stored in the VMC entry
  245. if(memcmp(mc_rpdb_uuid.nonce, ((vmc_data_blob_t*)&cache.self.leaf)->nonce, UUID_NONCE_SIZE))
  246. {
  247. return OP_ERROR_INVALID_COUNTER;
  248. }
  249. // check access right
  250. rc = rpdb_accessible(owner_attributes, *((vmc_data_blob_t*)&cache.self.leaf));
  251. if(OP_SUCCESS != rc)
  252. {
  253. goto clean_up;
  254. }
  255. }
  256. if(RPDB_OP_INCREMENT == rpdb_op)
  257. {
  258. cache.self.leaf.value += 1;
  259. // output updated leaf node
  260. memcpy(&rpdb, &cache.self.leaf, LEAF_NODE_SIZE);
  261. }
  262. else // rpdb_op is RPDB_OP_CREATE or RPDB_OP_DELETE
  263. {
  264. memcpy(&cache.self.leaf, &rpdb, LEAF_NODE_SIZE);
  265. }
  266. // calculate all effected nodes new hash value and root hash
  267. rc = update_related_nodes_of_leaf(&cache,
  268. (RPDB_OP_CREATE == rpdb_op || RPDB_OP_DELETE == rpdb_op) ? op_leafnode_flag_info->op_type : NON_OP);
  269. if(OP_SUCCESS != rc)
  270. {
  271. goto clean_up;
  272. }
  273. // write back all ralated nodes to database
  274. stat = sqlite_write_db(&rc,
  275. &cache,
  276. (RPDB_OP_CREATE == rpdb_op || RPDB_OP_DELETE == rpdb_op),
  277. op_leafnode_flag_info);
  278. if(OP_SUCCESS != rc || SGX_SUCCESS != stat)
  279. {
  280. if (stat != SGX_SUCCESS)
  281. {
  282. rc = OP_ERROR_INTERNAL;
  283. }
  284. goto clean_up;
  285. }
  286. rc = update_rpdata(cache.root.hash);
  287. clean_up:
  288. if(OP_SUCCESS == rc)
  289. {
  290. // a successful access to VMC entry
  291. if(RPDB_OP_READ != rpdb_op || !is_read_from_cache)
  292. {
  293. // update cache
  294. access_hash_tree_cache(rpdb_op, CACHE_OP_UPDATE, &cache, NULL);
  295. }
  296. }
  297. return rc;
  298. }
  299. /*******************************************************************
  300. ** Function name: create_vmc
  301. ** Descrption: create a VMC in SQLite Database and return UUID of the VMC to the caller.
  302. **
  303. *******************************************************************/
  304. pse_op_error_t create_vmc(const isv_attributes_t &owner_attributes, // [IN] ISV's attributes
  305. vmc_data_blob_t &data, // [IN,OUT] VMC blob data
  306. mc_rpdb_uuid_t &mc_rpdb_uuid) // [OUT] UUID of VMC
  307. {
  308. pse_op_error_t rc = OP_SUCCESS;
  309. sgx_status_t stat = SGX_SUCCESS;
  310. uint32_t tmp_rpdb_id = {0};
  311. int leaf_node_id = 0;
  312. op_leafnode_flag_t op_leafnode_flag_info;
  313. int retry_times = 1;
  314. // Check MC Service Availablity Status
  315. if((rc = get_mc_service_status()) != OP_SUCCESS)
  316. {
  317. if ((rc = initialize_sqlite_database_file(false)) != OP_SUCCESS)
  318. return rc;
  319. }
  320. // Calculate Owner ID and copy to "data->owner_id"
  321. if(SGX_SUCCESS != calculate_owner_id(owner_attributes,
  322. data.owner_policy,
  323. data.owner_attr_mask,
  324. data.owner_id))
  325. {
  326. rc = OP_ERROR_INTERNAL;
  327. goto end;
  328. }
  329. // Copy Owner's SVN
  330. data.owner_svn = owner_attributes.isv_svn;
  331. // read sgx random number for uuid->nonce.
  332. stat = sgx_read_rand(mc_rpdb_uuid.nonce, UUID_NONCE_SIZE);
  333. if( SGX_SUCCESS != stat )
  334. {
  335. rc = OP_ERROR_INTERNAL;
  336. goto end;
  337. }
  338. do{
  339. // get an empty database leaf node and return coressponding ID as rpdb ID to caller
  340. stat = sqlite_get_empty_leafnode(&rc, &leaf_node_id, const_cast<sgx_measurement_t*>(&owner_attributes.mr_signer));
  341. if(stat == SGX_SUCCESS) // OCALL success
  342. {
  343. if (rc == OP_SUCCESS)
  344. {
  345. // check leaf_node_id
  346. if (leaf_node_id < INIT_LEAF_NODE_ID_BASE || leaf_node_id > INIT_MAX_LEAF_NODE_ID)
  347. {
  348. // Invalid leaf node id, valid range must be [INIT_LEAF_NODE_ID_BASE, INIT_LEAF_NODE_ID_BASE*2-1]
  349. rc = OP_ERROR_INTERNAL;
  350. break;
  351. }
  352. }
  353. else if( (rc == OP_ERROR_DATABASE_FATAL || rc == OP_ERROR_INVALID_VMC_DB) && retry_times > 0)
  354. {
  355. // try to re-initialize vmc db
  356. if (OP_SUCCESS != (rc = initialize_sqlite_database_file(true)))
  357. {
  358. break;
  359. }
  360. else
  361. {
  362. // if successful, try to create again
  363. continue;
  364. }
  365. }
  366. else
  367. {
  368. // other errors
  369. break;
  370. }
  371. }
  372. else // OCALL failure
  373. {
  374. rc = OP_ERROR_INTERNAL;
  375. break;
  376. }
  377. // RPDB ID = LEAD ID - OFFSET(which is INIT_LEAF_NODE_ID_BASE)
  378. // Valid range of RPDB ID is from 0 to (INIT_LEAF_NODE_ID_BASE-1).
  379. tmp_rpdb_id = leaf_node_id - INIT_LEAF_NODE_ID_BASE;
  380. memcpy(mc_rpdb_uuid.entry_index, &tmp_rpdb_id, UUID_ENTRY_INDEX_SIZE);
  381. memcpy(data.nonce, mc_rpdb_uuid.nonce, UUID_NONCE_SIZE);
  382. // mark the flag as USED
  383. data.is_used = 1;
  384. // copy creator's mrsigner
  385. memcpy(&op_leafnode_flag_info.mr_signer, &owner_attributes.mr_signer, sizeof(sgx_measurement_t));
  386. // will set the USED flag in SQLite Database
  387. op_leafnode_flag_info.op_type = SET_LEAFNODE_FLAG;
  388. // call operate_vmc to store VMC creation info into SQLite Database.
  389. rc = operate_vmc(owner_attributes,
  390. mc_rpdb_uuid,
  391. data,
  392. RPDB_OP_CREATE,
  393. &op_leafnode_flag_info);
  394. if((OP_ERROR_INVALID_VMC_DB == rc || OP_ERROR_DATABASE_FATAL == rc)
  395. && retry_times > 0)
  396. {
  397. // try to re-initialize vmc db
  398. if (OP_SUCCESS != (rc = initialize_sqlite_database_file(true)) )
  399. {
  400. break;
  401. }
  402. else
  403. {
  404. // if successful, try to create vmc again
  405. continue;
  406. }
  407. }
  408. else
  409. {
  410. break;
  411. }
  412. }while(retry_times--);
  413. end:
  414. if(OP_SUCCESS != rc)
  415. {
  416. memset(mc_rpdb_uuid.entry_index, 0xFF, UUID_ENTRY_INDEX_SIZE);
  417. memset(mc_rpdb_uuid.nonce, 0x0, UUID_NONCE_SIZE);
  418. }
  419. return rc;
  420. }
  421. pse_op_error_t read_vmc(
  422. const isv_attributes_t &owner_attributes, // [IN] ISV's attributes that
  423. const mc_rpdb_uuid_t &mc_rpdb_uuid, // [IN] UUID of VMC
  424. vmc_data_blob_t &rpdb) // [IN,OUT] Pointer that points to VMC data blob
  425. {
  426. pse_op_error_t op_ret = OP_SUCCESS;
  427. // Check MC Service Availablity Status
  428. if((op_ret = get_mc_service_status()) != OP_SUCCESS)
  429. {
  430. if ((op_ret = initialize_sqlite_database_file(false)) != OP_SUCCESS)
  431. return op_ret;
  432. }
  433. op_ret = operate_vmc(owner_attributes,
  434. mc_rpdb_uuid,
  435. rpdb,
  436. RPDB_OP_READ,
  437. NULL); // the op_leafnode_flag_info that is used to update USED flag in SQLite Database is not required for READ operation.
  438. if (OP_ERROR_INVALID_VMC_DB == op_ret ||
  439. OP_ERROR_DATABASE_FATAL == op_ret)
  440. {
  441. op_ret = initialize_sqlite_database_file(true);
  442. if(OP_SUCCESS == op_ret)
  443. {
  444. // If initilize_sqlite_database_file() is successful, return INVALId_VMC_ID, as the DB initialization cleared all existing VMCs.
  445. return OP_ERROR_INVALID_COUNTER;
  446. }
  447. }
  448. return op_ret;
  449. }
  450. pse_op_error_t inc_vmc(
  451. const isv_attributes_t &owner_attributes, // [IN] ISV's attributes that
  452. const mc_rpdb_uuid_t &mc_rpdb_uuid, // [IN] UUID of VMC
  453. vmc_data_blob_t &rpdb) // [IN,OUT] Pointer that points to VMC data blob
  454. {
  455. pse_op_error_t op_ret = OP_SUCCESS;
  456. // Check MC Service Availablity Status
  457. if((op_ret = get_mc_service_status()) != OP_SUCCESS)
  458. {
  459. if ((op_ret = initialize_sqlite_database_file(false)) != OP_SUCCESS)
  460. return op_ret;
  461. }
  462. op_ret = operate_vmc(owner_attributes,
  463. mc_rpdb_uuid,
  464. rpdb,
  465. RPDB_OP_INCREMENT,
  466. NULL); // the op_leafnode_flag_info that is used to update USED flag in SQLite Database is not required for INC operation.
  467. if (OP_ERROR_INVALID_VMC_DB == op_ret ||
  468. OP_ERROR_DATABASE_FATAL == op_ret)
  469. {
  470. op_ret = initialize_sqlite_database_file(true);
  471. if(OP_SUCCESS == op_ret)
  472. {
  473. // If initilize_sqlite_database_file() is successful, return INVALId_VMC_ID, as the DB initialization cleared all existing VMCs.
  474. return OP_ERROR_INVALID_COUNTER;
  475. }
  476. }
  477. return op_ret;
  478. }
  479. /*******************************************************************
  480. ** Function name: delete_vmc
  481. ** Descrption: delete VMC from SQLite Database according to the specified UUID.
  482. **
  483. *******************************************************************/
  484. pse_op_error_t delete_vmc(const isv_attributes_t &owner_attributes, // [IN] ISV's attributes
  485. const mc_rpdb_uuid_t &mc_rpdb_uuid) // [IN] UUID of VMC
  486. {
  487. pse_op_error_t op_ret = OP_SUCCESS;
  488. hash_tree_leaf_node_t leaf_node;
  489. uint32_t rpdb_id = 0;
  490. op_leafnode_flag_t op_leafnode_flag_info;
  491. // Check MC Service Availablity Status
  492. if((op_ret = get_mc_service_status()) != OP_SUCCESS)
  493. {
  494. if ((op_ret = initialize_sqlite_database_file(false)) != OP_SUCCESS)
  495. return op_ret;
  496. }
  497. memset(&leaf_node, 0, sizeof(leaf_node));
  498. // get RPDB ID
  499. memcpy(&rpdb_id, mc_rpdb_uuid.entry_index, UUID_ENTRY_INDEX_SIZE);
  500. // check the RPDB ID
  501. if(rpdb_id>(INIT_LEAF_NODE_ID_BASE-1))
  502. {
  503. return OP_ERROR_INVALID_COUNTER;
  504. }
  505. // will clear the USED flag in SQLite Database
  506. op_leafnode_flag_info.op_type = CLR_LEAFNODE_FLAG;
  507. // call operate_vmc to delete VMC blob from SQLite Database.
  508. op_ret = operate_vmc(owner_attributes,
  509. mc_rpdb_uuid,
  510. leaf_node,
  511. RPDB_OP_DELETE,
  512. &op_leafnode_flag_info);
  513. if (OP_ERROR_INVALID_VMC_DB == op_ret ||
  514. OP_ERROR_DATABASE_FATAL == op_ret)
  515. {
  516. op_ret = initialize_sqlite_database_file(true);
  517. }
  518. return op_ret;
  519. }