2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Kyungwook Tak <k.tak@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
18 * @file test_db_crypto.cpp
19 * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
23 #include <boost/test/unit_test.hpp>
25 #include <db-crypto.h>
27 #include <ckm/ckm-type.h>
28 #include <ckm/ckm-error.h>
30 #include <test_common.h>
31 #include <DBFixture.h>
36 const int restricted_local = 1;
37 const int restricted_global = 0;
39 const unsigned int c_test_retries = 1000;
40 const unsigned int c_num_names = 500;
41 const unsigned int c_num_names_add_test = 5000;
42 const unsigned int c_names_per_owner = 15;
44 } // namespace anonymous
46 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_TEST, DBFixture)
47 BOOST_AUTO_TEST_CASE(DBtestSimple)
49 DB::Row rowPattern = create_default_row();
50 rowPattern.data = RawBuffer(32, 1);
51 rowPattern.dataSize = rowPattern.data.size();
52 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
54 check_DB_integrity(rowPattern);
56 BOOST_AUTO_TEST_CASE(DBtestBIG)
58 DB::Row rowPattern = create_default_row();
59 rowPattern.data = createBigBlob(4096);
60 rowPattern.dataSize = rowPattern.data.size();
61 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
63 check_DB_integrity(rowPattern);
65 BOOST_AUTO_TEST_CASE(DBtestGlobal)
67 DB::Row rowPattern = create_default_row();
68 rowPattern.data = RawBuffer(1024, 2);
69 rowPattern.dataSize = rowPattern.data.size();
70 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
72 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
74 DB::Row name_duplicate = rowPattern;
75 rowPattern.owner = rowPattern.owner + "1";
77 BOOST_AUTO_TEST_CASE(DBtestTransaction)
79 DB::Row rowPattern = create_default_row();
80 rowPattern.data = RawBuffer(100, 20);
81 rowPattern.dataSize = rowPattern.data.size();
82 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
83 DB::Crypto::Transaction transaction(&m_db);
85 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
86 BOOST_REQUIRE_NO_THROW(transaction.rollback());
88 DB::Crypto::RowOptional row_optional;
89 BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow(m_default_name,
91 DataType::BINARY_DATA));
92 BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback");
95 BOOST_AUTO_TEST_CASE(DBtestBackend)
97 DB::Row rowPattern = create_default_row();
98 rowPattern.data = RawBuffer(32, 1);
99 rowPattern.dataSize = rowPattern.data.size();
100 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
102 rowPattern.backendId = CryptoBackend::OpenSSL;
103 check_DB_integrity(rowPattern);
105 rowPattern.backendId = CryptoBackend::TrustZone;
106 check_DB_integrity(rowPattern);
108 rowPattern.backendId = CryptoBackend::None;
109 check_DB_integrity(rowPattern);
112 BOOST_AUTO_TEST_SUITE_END()
116 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_PERF_TEST, DBFixture)
118 BOOST_AUTO_TEST_CASE(DBperfAddNames)
121 performance_start("saveRow");
124 generate_perf_DB(c_num_names_add_test, c_names_per_owner);
127 performance_stop(c_num_names_add_test);
130 BOOST_AUTO_TEST_CASE(DBperfLookupAliasByOwner)
133 generate_perf_DB(c_num_names, c_names_per_owner);
135 unsigned int num_owners = c_num_names / c_names_per_owner;
139 // actual test - successful lookup
140 performance_start("getRow");
142 for (unsigned int t = 0; t < c_test_retries; t++) {
143 int owner_num = rand_r(&t) % num_owners;
144 generate_owner(owner_num, owner);
146 unsigned int start_name = owner_num * c_names_per_owner;
148 for (unsigned int name_num = start_name;
149 name_num < (start_name + c_names_per_owner); name_num++) {
150 generate_name(name_num, name);
151 read_row_expect_success(name, owner);
155 performance_stop(c_test_retries * c_num_names);
158 // TODO this test makes no sense. Rewrite it.
159 BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions)
162 generate_perf_DB(c_num_names, c_names_per_owner);
166 //ClientId smack_label;
167 //unsigned int num_owners = c_num_names / c_names_per_owner;
169 // actual test - random lookup
170 performance_start("getRow");
172 for (unsigned int t = 0; t < c_test_retries; t++) {
173 int name_idx = rand_r(&t) % c_num_names;
174 generate_name(name_idx, name);
175 generate_owner(name_idx / c_names_per_owner, owner);
176 //generate_owner(rand_r(&t) % num_owners, smack_label);
178 // do not care of result
179 m_db.getRow(name, owner, DataType::BINARY_DATA);
182 performance_stop(c_test_retries * c_num_names);
185 BOOST_AUTO_TEST_CASE(DBperfAddPermissions)
188 generate_perf_DB(c_num_names, c_names_per_owner);
190 // actual test - add access rights
191 performance_start("setPermission");
192 long iterations = add_full_access_rights(c_num_names, c_names_per_owner);
193 performance_stop(iterations);
196 BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
199 generate_perf_DB(c_num_names, c_names_per_owner);
200 add_full_access_rights(c_num_names, c_names_per_owner);
202 // actual test - random lookup
203 performance_start("deleteRow");
207 for (unsigned int t = 0; t < c_num_names; t++) {
208 generate_name(t, name);
209 generate_owner(t / c_names_per_owner, owner);
211 BOOST_REQUIRE_NO_THROW(m_db.deleteRow(name, owner));
214 performance_stop(c_num_names);
216 // verify everything has been removed
217 unsigned int num_owners = c_num_names / c_names_per_owner;
219 for (unsigned int l = 0; l < num_owners; l++) {
220 generate_owner(l, owner);
221 OwnerNameVector expect_no_data;
222 BOOST_REQUIRE_NO_THROW(m_db.listNames(owner, expect_no_data,
223 DataType::BINARY_DATA));
224 BOOST_REQUIRE(0 == expect_no_data.size());
228 BOOST_AUTO_TEST_CASE(DBperfGetAliasList)
231 generate_perf_DB(c_num_names, c_names_per_owner);
232 add_full_access_rights(c_num_names, c_names_per_owner);
234 unsigned int num_owners = c_num_names / c_names_per_owner;
237 // actual test - random lookup
238 performance_start("listNames");
240 for (unsigned int t = 0; t < (c_test_retries / num_owners); t++) {
241 OwnerNameVector ret_list;
242 generate_owner(rand_r(&t) % num_owners, owner);
244 BOOST_REQUIRE_NO_THROW(m_db.listNames(owner, ret_list, DataType::BINARY_DATA));
245 BOOST_REQUIRE(c_num_names == ret_list.size());
249 performance_stop(c_test_retries / num_owners);
251 BOOST_AUTO_TEST_SUITE_END()
254 BOOST_AUTO_TEST_SUITE(DBCRYPTO_MIGRATION_TEST)
256 const unsigned migration_names = 16107;
257 const unsigned migration_owners = 273;
258 const unsigned migration_reference_owner_idx = 0;
259 const unsigned migration_accessed_element_idx = 7;
261 void verifyDBisValid(DBFixture &fixture)
264 * There are (migration_owners), each having (migration_names)/(migration_owners)
265 * entries. Reference owner (migration_reference_owner_idx) exists such that
266 * it has access to all other owners' elements with index
267 * (migration_accessed_element_idx).
270 * - migration_owner_63 has access to all items owned by migration_owner_63,
271 * which gives (migration_names)/(migration_owners) entries.
273 * - migration_owner_0 (0 is the reference owner) has access to all items
274 * owned by migration_owner_0 and all other owners' elements with index 7,
275 * which gives (migration_names)/(migration_owners) + (migration_owners-1) entries.
278 ClientId reference_owner;
279 fixture.generate_owner(migration_reference_owner_idx, reference_owner);
281 // check number of elements accessible to the reference owner
282 OwnerNameVector ret_list;
283 BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(reference_owner, ret_list,
284 DataType::BINARY_DATA));
285 BOOST_REQUIRE((migration_names / migration_owners)/*own items*/ +
286 (migration_owners - 1)/*other owners'*/ == ret_list.size());
289 // check number of elements accessible to the other owners
290 for (unsigned int l = 0; l < migration_owners; l++) {
291 // bypass the reference owner
292 if (l == migration_reference_owner_idx)
295 ClientId current_owner;
296 fixture.generate_owner(l, current_owner);
297 BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(current_owner, ret_list,
298 DataType::BINARY_DATA));
299 BOOST_REQUIRE((migration_names / migration_owners) == ret_list.size());
301 for (auto it : ret_list)
302 BOOST_REQUIRE(it.first == current_owner);
308 struct DBVer1Migration : public DBFixture {
309 DBVer1Migration() : DBFixture(DB_TEST_DIR "/testme_ver1.db") {}
312 struct DBVer2Migration : public DBFixture {
313 DBVer2Migration() : DBFixture(DB_TEST_DIR "/testme_ver2.db") {}
316 struct DBVer3Migration : public DBFixture {
317 DBVer3Migration() : DBFixture(DB_TEST_DIR "/testme_ver3.db") {}
321 BOOST_AUTO_TEST_CASE(DBMigrationDBVer1)
323 DBVer1Migration DBver1;
324 verifyDBisValid(DBver1);
327 BOOST_AUTO_TEST_CASE(DBMigrationDBVer2)
329 DBVer2Migration DBver2;
330 verifyDBisValid(DBver2);
333 BOOST_AUTO_TEST_CASE(DBMigrationDBVer3)
335 DBVer3Migration DBver3;
336 verifyDBisValid(DBver3);
339 BOOST_AUTO_TEST_CASE(DBMigrationDBCurrent)
343 // prepare data using current DB mechanism
344 ClientId reference_owner;
345 currentDB.generate_owner(migration_reference_owner_idx, reference_owner);
348 currentDB.generate_perf_DB(migration_names, migration_names / migration_owners);
350 // only the reference owner has access to the other owners' elements <migration_accessed_element_idx>
351 for (unsigned int l = 0; l < migration_owners; l++) {
352 // bypass the reference owner
353 if (l == migration_reference_owner_idx)
356 unsigned element_index = migration_accessed_element_idx + l * migration_names /
361 currentDB.generate_name(element_index, accessed_name);
362 ClientId current_owner;
363 currentDB.generate_owner(l, current_owner);
364 currentDB.add_permission(accessed_name, current_owner, reference_owner);
368 verifyDBisValid(currentDB);
371 BOOST_AUTO_TEST_SUITE_END()