Add backend id to database scheme
[platform/core/security/key-manager.git] / tests / test_db_crypto.cpp
1 #include <boost/test/unit_test.hpp>
2 #include <unistd.h>
3 #include <db-crypto.h>
4 #include <iostream>
5 #include <ckm/ckm-type.h>
6 #include <ckm/ckm-error.h>
7 #include <errno.h>
8 #include <test_common.h>
9 #include <DBFixture.h>
10
11 using namespace CKM;
12
13 namespace
14 {
15 const int restricted_local = 1;
16 const int restricted_global = 0;
17
18 const unsigned int c_test_retries = 1000;
19 const unsigned int c_num_names = 500;
20 const unsigned int c_num_names_add_test = 5000;
21 const unsigned int c_names_per_label = 15;
22
23 } // namespace anonymous
24
25 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_TEST, DBFixture)
26 BOOST_AUTO_TEST_CASE(DBtestSimple) {
27     DB::Row rowPattern = create_default_row();
28     rowPattern.data = RawBuffer(32, 1);
29     rowPattern.dataSize = rowPattern.data.size();
30     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
31
32     check_DB_integrity(rowPattern);
33 }
34 BOOST_AUTO_TEST_CASE(DBtestBIG) {
35     DB::Row rowPattern = create_default_row();
36     rowPattern.data = createBigBlob(4096);
37     rowPattern.dataSize = rowPattern.data.size();
38     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
39
40     check_DB_integrity(rowPattern);
41 }
42 BOOST_AUTO_TEST_CASE(DBtestGlobal) {
43     DB::Row rowPattern = create_default_row();
44     rowPattern.data = RawBuffer(1024, 2);
45     rowPattern.dataSize = rowPattern.data.size();
46     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
47
48     BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
49
50     DB::Row name_duplicate = rowPattern;
51     rowPattern.ownerLabel = rowPattern.ownerLabel + "1";
52 }
53 BOOST_AUTO_TEST_CASE(DBtestTransaction) {
54     DB::Row rowPattern = create_default_row();
55     rowPattern.data = RawBuffer(100, 20);
56     rowPattern.dataSize = rowPattern.data.size();
57     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
58     DB::Crypto::Transaction transaction(&m_db);
59
60     BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
61     BOOST_REQUIRE_NO_THROW(transaction.rollback());
62
63     DB::Crypto::RowOptional row_optional;
64     BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow(m_default_name, m_default_label,
65                                                       DataType::BINARY_DATA));
66     BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback");
67 }
68
69 BOOST_AUTO_TEST_CASE(DBtestBackend) {
70     DB::Row rowPattern = create_default_row();
71     rowPattern.data = RawBuffer(32, 1);
72     rowPattern.dataSize = rowPattern.data.size();
73     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
74
75     rowPattern.backendId =  CryptoBackend::OpenSSL;
76     check_DB_integrity(rowPattern);
77
78     rowPattern.backendId =  CryptoBackend::TrustZone;
79     check_DB_integrity(rowPattern);
80
81     rowPattern.backendId =  CryptoBackend::None;
82     check_DB_integrity(rowPattern);
83 }
84
85 BOOST_AUTO_TEST_SUITE_END()
86
87
88
89 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_PERF_TEST, DBFixture)
90
91 BOOST_AUTO_TEST_CASE(DBperfAddNames)
92 {
93     // actual test
94     performance_start("saveRow");
95     {
96         generate_perf_DB(c_num_names_add_test, c_names_per_label);
97     }
98     performance_stop(c_num_names_add_test);
99 }
100
101 BOOST_AUTO_TEST_CASE(DBperfLookupAliasByOwner)
102 {
103     // prepare data
104     generate_perf_DB(c_num_names, c_names_per_label);
105
106     unsigned int num_labels = c_num_names/c_names_per_label;
107     Name name;
108     Label label;
109
110     // actual test - successful lookup
111     performance_start("getRow");
112     for(unsigned int t=0; t<c_test_retries; t++)
113     {
114         int label_num = rand() % num_labels;
115         generate_label(label_num, label);
116
117         unsigned int start_name = label_num*c_names_per_label;
118         for(unsigned int name_num=start_name; name_num<(start_name+c_names_per_label); name_num++)
119         {
120             generate_name(name_num, name);
121             read_row_expect_success(name, label);
122         }
123     }
124     performance_stop(c_test_retries * c_num_names);
125 }
126
127 BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions)
128 {
129     // prepare data
130     generate_perf_DB(c_num_names, c_names_per_label);
131
132     Name name;
133     Label owner_label;
134     Label smack_label;
135     unsigned int num_labels = c_num_names / c_names_per_label;
136
137     // actual test - random lookup
138     performance_start("getRow");
139     for(unsigned int t=0; t<c_test_retries; t++)
140     {
141         int name_idx = rand()%c_num_names;
142         generate_name(name_idx, name);
143         generate_label(name_idx/c_names_per_label, owner_label);
144         generate_label(rand()%num_labels, smack_label);
145
146         // do not care of result
147         m_db.getRow(name, owner_label, DataType::BINARY_DATA);
148     }
149     performance_stop(c_test_retries * c_num_names);
150 }
151
152 BOOST_AUTO_TEST_CASE(DBperfAddPermissions)
153 {
154     // prepare data
155     generate_perf_DB(c_num_names, c_names_per_label);
156
157     // actual test - add access rights
158     performance_start("setPermission");
159     long iterations = add_full_access_rights(c_num_names, c_names_per_label);
160     performance_stop(iterations);
161 }
162
163 BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
164 {
165     // prepare data
166     generate_perf_DB(c_num_names, c_names_per_label);
167     add_full_access_rights(c_num_names, c_names_per_label);
168
169     // actual test - random lookup
170     performance_start("deleteRow");
171     Name name;
172     Label label;
173     for(unsigned int t=0; t<c_num_names; t++)
174     {
175         generate_name(t, name);
176         generate_label(t/c_names_per_label, label);
177
178         BOOST_REQUIRE_NO_THROW(m_db.deleteRow(name, label));
179     }
180     performance_stop(c_num_names);
181
182     // verify everything has been removed
183     unsigned int num_labels = c_num_names / c_names_per_label;
184     for(unsigned int l=0; l<num_labels; l++)
185     {
186         generate_label(l, label);
187         LabelNameVector expect_no_data;
188         BOOST_REQUIRE_NO_THROW(m_db.listNames(label, expect_no_data, DataType::BINARY_DATA));
189         BOOST_REQUIRE(0 == expect_no_data.size());
190     }
191 }
192
193 BOOST_AUTO_TEST_CASE(DBperfGetAliasList)
194 {
195     // prepare data
196     generate_perf_DB(c_num_names, c_names_per_label);
197     add_full_access_rights(c_num_names, c_names_per_label);
198
199     unsigned int num_labels = c_num_names / c_names_per_label;
200     Label label;
201
202     // actual test - random lookup
203     performance_start("listNames");
204     for(unsigned int t=0; t<(c_test_retries/num_labels); t++)
205     {
206         LabelNameVector ret_list;
207         generate_label(rand()%num_labels, label);
208
209         BOOST_REQUIRE_NO_THROW(m_db.listNames(label, ret_list, DataType::BINARY_DATA));
210         BOOST_REQUIRE(c_num_names == ret_list.size());
211         ret_list.clear();
212     }
213     performance_stop(c_test_retries/num_labels);
214 }
215 BOOST_AUTO_TEST_SUITE_END()
216
217
218 BOOST_AUTO_TEST_SUITE(DBCRYPTO_MIGRATION_TEST)
219 namespace
220 {
221 const unsigned migration_names = 16107;
222 const unsigned migration_labels = 273;
223 const unsigned migration_reference_label_idx = 0;
224 const unsigned migration_accessed_element_idx = 7;
225
226 void verifyDBisValid(DBFixture & fixture)
227 {
228     /**
229      * there are (migration_labels), each having (migration_names)/(migration_labels) entries.
230      * reference label (migration_reference_label_idx) exists such that it has access to
231      * all others' label element with index (migration_accessed_element_idx).
232      *
233      * Example:
234      * - migration_label_63 has access to all items owned by migration_label_63,
235      *   which gives (migration_names)/(migration_labels) entries.
236      *
237      * - migration_label_0 (0 is the reference label) has access to all items
238      *   owned by migration_label_0 and all others' label element index 7,
239      *   which gives (migration_names)/(migration_labels)  + (migration_labels-1) entries.
240      *
241      */
242     Label reference_label;
243     fixture.generate_label(migration_reference_label_idx, reference_label);
244
245     // check number of elements accessible to the reference label
246     LabelNameVector ret_list;
247     BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(reference_label, ret_list, DataType::BINARY_DATA));
248     BOOST_REQUIRE((migration_names/migration_labels)/*own items*/ + (migration_labels-1)/*other labels'*/ == ret_list.size());
249     ret_list.clear();
250
251     // check number of elements accessible to the other labels
252     for(unsigned int l=0; l<migration_labels; l++)
253     {
254         // bypass the reference owner label
255         if(l == migration_reference_label_idx)
256             continue;
257
258         Label current_label;
259         fixture.generate_label(l, current_label);
260         BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(current_label, ret_list, DataType::BINARY_DATA));
261         BOOST_REQUIRE((migration_names/migration_labels) == ret_list.size());
262         for(auto it: ret_list)
263             BOOST_REQUIRE(it.first == current_label);
264         ret_list.clear();
265     }
266 }
267
268 struct DBVer1Migration : public DBFixture
269 {
270     DBVer1Migration() : DBFixture("/usr/share/ckm-db-test/testme_ver1.db")
271     {}
272 };
273
274 struct DBVer2Migration : public DBFixture
275 {
276     DBVer2Migration() : DBFixture("/usr/share/ckm-db-test/testme_ver2.db")
277     {}
278 };
279
280 struct DBVer3Migration : public DBFixture
281 {
282     DBVer3Migration() : DBFixture("/usr/share/ckm-db-test/testme_ver3.db")
283     {}
284 };
285 }
286
287 BOOST_AUTO_TEST_CASE(DBMigrationDBVer1)
288 {
289     DBVer1Migration DBver1;
290     verifyDBisValid(DBver1);
291 }
292
293 BOOST_AUTO_TEST_CASE(DBMigrationDBVer2)
294 {
295     DBVer2Migration DBver2;
296     verifyDBisValid(DBver2);
297 }
298
299 BOOST_AUTO_TEST_CASE(DBMigrationDBVer3)
300 {
301     DBVer3Migration DBver3;
302     verifyDBisValid(DBver3);
303 }
304
305 BOOST_AUTO_TEST_CASE(DBMigrationDBCurrent)
306 {
307     DBFixture currentDB;
308
309     // prepare data using current DB mechanism
310     Label reference_label;
311     currentDB.generate_label(migration_reference_label_idx, reference_label);
312     {
313         currentDB.generate_perf_DB(migration_names, migration_names/migration_labels);
314
315         // only the reference label has access to the other labels element <migration_accessed_element_idx>
316         for(unsigned int l=0; l<migration_labels; l++)
317         {
318             // bypass the reference owner label
319             if(l == migration_reference_label_idx)
320                 continue;
321
322             unsigned element_index = migration_accessed_element_idx + l*migration_names/migration_labels;
323
324             // add permission
325             Name accessed_name;
326             currentDB.generate_name(element_index, accessed_name);
327             Label current_label;
328             currentDB.generate_label(l, current_label);
329             currentDB.add_permission(accessed_name, current_label, reference_label);
330         }
331     }
332
333     verifyDBisValid(currentDB);
334 }
335
336 BOOST_AUTO_TEST_SUITE_END()