2 * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
16 #include <crypto-logic.h>
17 #include <platform/decider.h>
18 #include <generic-backend/gstore.h>
25 #include <boost_macros_wrapper.h>
26 #include "test_common.h"
32 constexpr char TEST_CLIENT[] = "test_client";
33 constexpr char TEST_NAME[] = "test_name";
34 constexpr uid_t TEST_UID = 0;
35 const auto TEST_KEY = createRandom(32);
36 const auto TEST_DATA = createRandom(10);
38 void changeBase64(RawBuffer& data)
40 data = base64Decode<RawBuffer>(data);
41 BOOST_REQUIRE(!data.empty());
45 data = base64Encode<RawBuffer>(data);
46 BOOST_REQUIRE(!data.empty());
49 } // namespace anonymous
51 BOOST_AUTO_TEST_SUITE(CRYPTO_LOGIC_TEST)
53 POSITIVE_TEST_CASE(move_semantics)
57 BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
59 CryptoLogic moved(std::move(logic));
60 BOOST_REQUIRE(!logic.haveKey(TEST_CLIENT));
61 BOOST_REQUIRE(moved.haveKey(TEST_CLIENT));
63 CryptoLogic moveAssigned = std::move(moved);
64 BOOST_REQUIRE(!moved.haveKey(TEST_CLIENT));
65 BOOST_REQUIRE(moveAssigned.haveKey(TEST_CLIENT));
68 POSITIVE_TEST_CASE(push_have_remove_key)
72 char client[] = "duck";
73 for (size_t i = 0; i < 20; ++i) {
75 BOOST_REQUIRE(!logic.haveKey(client));
76 BOOST_REQUIRE_NO_THROW(logic.pushKey(client, TEST_KEY));
77 BOOST_REQUIRE(logic.haveKey(client));
78 BOOST_REQUIRE_NO_THROW(logic.removeKey(client));
79 BOOST_REQUIRE(!logic.haveKey(client));
83 NEGATIVE_TEST_CASE(have_remove_nonexistent_key)
87 BOOST_REQUIRE(!logic.haveKey(TEST_CLIENT));
88 BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
91 NEGATIVE_TEST_CASE(have_remove_empty)
95 BOOST_REQUIRE(!logic.haveKey(""));
96 BOOST_REQUIRE_NO_THROW(logic.removeKey(""));
99 NEGATIVE_TEST_CASE(double_remove_key)
103 BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
104 BOOST_REQUIRE(logic.haveKey(TEST_CLIENT));
105 BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
106 BOOST_REQUIRE(!logic.haveKey(TEST_CLIENT));
107 BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
108 BOOST_REQUIRE(!logic.haveKey(TEST_CLIENT));
111 NEGATIVE_TEST_CASE(push_key)
115 BOOST_REQUIRE_THROW(logic.pushKey("", TEST_KEY), Exc::InternalError);
116 BOOST_REQUIRE_THROW(logic.pushKey(TEST_CLIENT, RawBuffer()), Exc::InternalError);
118 char client[] = "duck";
119 for (size_t i = 0; i < 20; ++i) {
121 BOOST_REQUIRE(!logic.haveKey(client));
122 BOOST_REQUIRE_NO_THROW(logic.pushKey(client, TEST_KEY));
123 BOOST_REQUIRE_THROW(logic.pushKey(client, TEST_KEY), Exc::InternalError);
124 BOOST_REQUIRE(logic.haveKey(client));
128 POSITIVE_TEST_CASE(row_encryption)
130 Policy policy("", true);
131 Crypto::Data data(DataType::BINARY_DATA, TEST_DATA);
132 Crypto::Decider decider;
133 Crypto::GStore &store = decider.getStore(data.type, policy);
135 const auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_CLIENT, TEST_UID);
136 BOOST_REQUIRE(!digest.empty());
138 Token token = store.import(data, policy.password, Crypto::EncryptionParams(), digest);
140 DB::Row row(token, TEST_NAME, TEST_CLIENT, static_cast<int>(policy.extractable));
145 BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
146 BOOST_REQUIRE_NO_THROW(rowCopy = logic.encryptRow(row));
147 BOOST_REQUIRE(rowCopy.algorithmType == DBCMAlgType::AES_GCM_256);
148 BOOST_REQUIRE(rowCopy.dataSize == static_cast<int>(row.data.size()));
149 BOOST_REQUIRE(!rowCopy.iv.empty());
150 BOOST_REQUIRE(!rowCopy.tag.empty());
151 auto scheme = CryptoLogic::getSchemeVersion(rowCopy.encryptionScheme);
152 BOOST_REQUIRE(scheme == CryptoLogic::ENCRYPTION_V2);
154 BOOST_REQUIRE_NO_THROW(logic.decryptRow(policy.password, rowCopy));
155 BOOST_REQUIRE(row.data == rowCopy.data);
158 NEGATIVE_TEST_CASE(row_encryption)
160 const Policy policy("", true);
161 Crypto::Data data(DataType::BINARY_DATA, TEST_DATA);
162 Crypto::Decider decider;
163 Crypto::GStore &store = decider.getStore(data.type, policy);
165 const auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_CLIENT, TEST_UID);
166 BOOST_REQUIRE(!digest.empty());
168 Token token = store.import(data, policy.password, Crypto::EncryptionParams(), digest);
170 DB::Row row(token, TEST_NAME, TEST_CLIENT, static_cast<int>(policy.extractable));
176 BOOST_REQUIRE_THROW(logic.encryptRow(emptyRow), Exc::InternalError);
179 BOOST_REQUIRE_THROW(logic.encryptRow(row), Exc::InternalError);
182 const auto shortKey = RawBuffer(4);
183 BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, shortKey));
184 BOOST_REQUIRE_THROW(logic.encryptRow(row), Exc::InternalError);
185 BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
186 BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
188 // correct encryption
189 DB::Row encryptedRow;
190 BOOST_REQUIRE_NO_THROW(encryptedRow = logic.encryptRow(row));
193 encryptedRow.algorithmType = DBCMAlgType::NONE;
194 BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
195 encryptedRow.algorithmType = DBCMAlgType::AES_GCM_256;
197 // unnecessary password
198 BOOST_REQUIRE_THROW(logic.decryptRow("unnecessary password", encryptedRow),
199 Exc::AuthenticationFailed);
202 BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
203 BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
204 BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
207 ++encryptedRow.owner[0];
208 BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
209 --encryptedRow.owner[0];
212 auto rowCopy = encryptedRow;
214 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
216 // wrong iv (not base64)
217 rowCopy = encryptedRow;
219 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
222 rowCopy = encryptedRow;
223 changeBase64(rowCopy.iv);
224 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
227 rowCopy = encryptedRow;
228 rowCopy.data.clear();
229 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy),Exc::InternalError);
231 // wrong ciphertext (not base64)
232 rowCopy = encryptedRow;
233 rowCopy.data[0] = 64;
234 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
237 rowCopy = encryptedRow;
238 changeBase64(rowCopy.data);
239 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
242 rowCopy = encryptedRow;
244 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
247 rowCopy = encryptedRow;
249 BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
252 BOOST_AUTO_TEST_SUITE_END() // CRYPTO_LOGIC_TEST