Release 0.1.66
[platform/core/security/key-manager.git] / unit-tests / test_sw-backend.cpp
1 /*
2  *  Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16
17 #include <unordered_map>
18 #include <utility>
19 #include <memory>
20 #include <exception>
21 #include <optional>
22
23 #include <boost_macros_wrapper.h>
24 #include <test_common.h>
25
26 #include <sw-backend/internals.h>
27 #include <sw-backend/store.h>
28 #include <sw-backend/crypto.h>
29 #include <sw-backend/obj.h>
30 #include <data-type.h>
31 #include <ckm/ckm-key.h>
32 #include <ckm/ckm-type.h>
33 #include <crypto-logic.h>
34 #include <generic-backend/crypto-params.h>
35
36 using namespace CKM;
37 using namespace CKM::Crypto;
38 using namespace CKM::Crypto::SW;
39
40 namespace {
41
42 const Name TEST_NAME = "test_data";
43 const Name TEST_NAME2 = "test_data2";
44 const ClientId TEST_OWNER = "test_owner";
45 const uid_t TEST_UID = 0;
46
47 Store STORE(CryptoBackend::OpenSSL);
48
49 RawBuffer makeTestDigest()
50 {
51         auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID);
52         BOOST_REQUIRE(!digest.empty());
53         return digest;
54 }
55
56 std::pair<RawBuffer, RawBuffer> makePubPrivTestDigest()
57 {
58         auto digestPub = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID);
59         auto digestPriv = CryptoLogic::makeHash(TEST_NAME2, TEST_OWNER, TEST_UID);
60         BOOST_REQUIRE(!digestPub.empty() && !digestPriv.empty());
61         return std::make_pair(std::move(digestPub), std::move(digestPriv));
62 }
63
64 void checkKey(const Token& token, KeyType keyType, const Password& pass)
65 {
66         DataType dataType(keyType);
67         BOOST_REQUIRE(token.dataType == dataType);
68
69         GObjUPtr obj;
70         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, pass));
71         BOOST_REQUIRE(obj);
72
73         RawBuffer data = obj->getBinary();
74         BOOST_REQUIRE(!data.empty());
75
76         KeyShPtr key;
77         if (dataType.isSymmetricKey())
78                 key = CKM::Key::createAES(data);
79         else
80                 key = CKM::Key::create(data);
81
82         BOOST_REQUIRE(key);
83         BOOST_REQUIRE(!key->empty());
84         BOOST_REQUIRE(!key->getDER().empty());
85         BOOST_REQUIRE(key->getType() == keyType);
86 }
87
88 struct GObjUPtrPair {
89         GObjUPtr prv;
90         GObjUPtr pub;
91 };
92
93 const GObjUPtrPair& generateObjUPtrPair(AlgoType algo, int param)
94 {
95         static std::unordered_map<AlgoType, std::unordered_map<int, GObjUPtrPair>> keyMap;
96
97         auto& algoMap = keyMap[algo];
98         auto it = algoMap.find(param);
99         if (it != algoMap.end())
100                 return it->second;
101
102         CryptoAlgorithm gen;
103         gen.setParam(ParamName::ALGO_TYPE, algo);
104         if (algo == AlgoType::ECDSA_GEN)
105                 gen.setParam(ParamName::GEN_EC, param);
106         else
107                 gen.setParam(ParamName::GEN_KEY_LEN, param);
108
109         const auto [digestPub, digestPriv] = makePubPrivTestDigest();
110
111         auto keyPair = STORE.generateAKey(gen, "", "", digestPriv, digestPub);
112
113         GObjUPtrPair pair;
114         BOOST_REQUIRE_NO_THROW(pair.prv = STORE.getObject(keyPair.first, ""));
115         BOOST_REQUIRE_NO_THROW(pair.pub = STORE.getObject(keyPair.second, ""));
116         BOOST_REQUIRE(pair.prv);
117         BOOST_REQUIRE(pair.pub);
118         return algoMap.emplace(param, std::move(pair)).first->second;
119 }
120
121 struct EvpPtrPair {
122         EvpShPtr prv;
123         EvpShPtr pub;
124 };
125
126 EvpPtrPair generateEvpPair(AlgoType algo, int param)
127 {
128         class AKeyHelper : public AKey {
129         private:
130                 AKeyHelper(RawBuffer buffer, DataType dataType) :
131                         AKey(CryptoBackend::OpenSSL, std::move(buffer), dataType)
132                 {}
133
134         public:
135                 static EvpPtrPair getEvps(const GObjUPtrPair& objPair, DataType prvType, DataType pubType)
136                 {
137                         AKeyHelper prv(objPair.prv->getBinary(), prvType);
138                         AKeyHelper pub(objPair.pub->getBinary(), pubType);
139                         return { prv.getEvpShPtr(), pub.getEvpShPtr() };
140                 }
141         };
142
143         auto& objs = generateObjUPtrPair(algo, param);
144
145         switch (algo) {
146         default:
147                 BOOST_REQUIRE_MESSAGE(algo == AlgoType::RSA_GEN, "Invalid algorithm. Fix the test.");
148                 return AKeyHelper::getEvps(objs, DataType::KEY_RSA_PRIVATE, DataType::KEY_RSA_PUBLIC);
149         case AlgoType::DSA_GEN:
150                 return AKeyHelper::getEvps(objs, DataType::KEY_DSA_PRIVATE, DataType::KEY_DSA_PUBLIC);
151         case AlgoType::ECDSA_GEN:
152                 return AKeyHelper::getEvps(objs, DataType::KEY_ECDSA_PRIVATE, DataType::KEY_ECDSA_PUBLIC);
153         }
154 }
155
156 GObjUPtr generateAes(int len)
157 {
158         CryptoAlgorithm ca;
159         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
160         ca.setParam(ParamName::GEN_KEY_LEN, len);
161
162         Token token;
163
164         const auto digest = makeTestDigest();
165
166         BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, "", digest));
167
168         GObjUPtr obj;
169         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
170         BOOST_REQUIRE(obj);
171         return obj;
172 }
173
174 const RawBuffer X509_CERT = {
175         0x30, 0x82, 0x02, 0xf6, 0x30, 0x82, 0x02, 0x5f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x69,
176         0x63, 0x3b, 0x0d, 0x5c, 0xbf, 0x7a, 0xfb, 0xec, 0xac, 0xac, 0xfc, 0x82, 0x4c, 0xf7, 0xa9, 0x66,
177         0x4a, 0xc3, 0xb1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
178         0x05, 0x00, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
179         0x50, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a,
180         0x6f, 0x77, 0x69, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04,
181         0x07, 0x0c, 0x08, 0x57, 0x61, 0x72, 0x73, 0x7a, 0x61, 0x77, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06,
182         0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30,
183         0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
184         0x55, 0x04, 0x03, 0x0c, 0x0b, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d,
185         0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16,
186         0x10, 0x6e, 0x6f, 0x6e, 0x65, 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f,
187         0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x34, 0x30, 0x39, 0x31, 0x37, 0x35, 0x33, 0x30,
188         0x39, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x34, 0x30, 0x38, 0x31, 0x37, 0x35, 0x33, 0x30, 0x39,
189         0x5a, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x50,
190         0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a, 0x6f,
191         0x77, 0x69, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07,
192         0x0c, 0x08, 0x57, 0x61, 0x72, 0x73, 0x7a, 0x61, 0x77, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
193         0x55, 0x04, 0x0a, 0x0c, 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, 0x09,
194         0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
195         0x04, 0x03, 0x0c, 0x0b, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x31,
196         0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
197         0x6e, 0x6f, 0x6e, 0x65, 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d,
198         0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
199         0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xca, 0xf1, 0xe1,
200         0x57, 0x5c, 0x04, 0x45, 0x92, 0x5d, 0xd3, 0x9a, 0xee, 0x72, 0x6b, 0xe9, 0x58, 0x79, 0xdd, 0x30,
201         0xdf, 0x9e, 0xa8, 0x60, 0x38, 0x64, 0x54, 0x0b, 0xc7, 0x3e, 0x90, 0x65, 0x2e, 0xe3, 0x90, 0xa9,
202         0x85, 0xc1, 0x94, 0xee, 0xae, 0x38, 0xcd, 0xfa, 0xaf, 0x11, 0xd8, 0x24, 0x54, 0x12, 0xbe, 0x63,
203         0xa1, 0x81, 0x32, 0xb6, 0xc1, 0xd1, 0x30, 0x0b, 0xa3, 0x6c, 0xca, 0xe1, 0x15, 0x43, 0x22, 0x04,
204         0xdc, 0xf1, 0x4b, 0x24, 0x6e, 0x20, 0x63, 0x88, 0xfe, 0x1c, 0x1c, 0x1f, 0x99, 0x97, 0x8e, 0xb4,
205         0x91, 0x4f, 0xf4, 0xbc, 0xa6, 0x4f, 0x5a, 0xde, 0xf2, 0x5a, 0xaf, 0x60, 0xf3, 0xb9, 0x69, 0xa4,
206         0x4a, 0xff, 0x7f, 0x44, 0x53, 0x1a, 0xb2, 0xa4, 0x91, 0xc5, 0x5a, 0x74, 0x2c, 0x66, 0x28, 0x82,
207         0xeb, 0xe1, 0x9b, 0x52, 0xf7, 0x9e, 0xb7, 0xc5, 0x71, 0xfe, 0x90, 0xa0, 0x25, 0x02, 0x03, 0x01,
208         0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
209         0x14, 0x01, 0xae, 0x82, 0xb1, 0x4a, 0x2f, 0xa5, 0xe9, 0x1a, 0x8e, 0x0f, 0x98, 0xd0, 0x19, 0x16,
210         0x32, 0xa0, 0xcd, 0x08, 0xd6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
211         0x80, 0x14, 0x01, 0xae, 0x82, 0xb1, 0x4a, 0x2f, 0xa5, 0xe9, 0x1a, 0x8e, 0x0f, 0x98, 0xd0, 0x19,
212         0x16, 0x32, 0xa0, 0xcd, 0x08, 0xd6, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
213         0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
214         0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2d, 0x5f, 0xfa, 0x7e, 0x25, 0xcb,
215         0xce, 0xfa, 0x9d, 0x35, 0xcc, 0x8d, 0xd2, 0x0d, 0x1f, 0xca, 0xa6, 0xc6, 0xb1, 0xce, 0x1f, 0x9e,
216         0x6f, 0xb7, 0xbb, 0xf5, 0x29, 0x85, 0xaa, 0x09, 0x51, 0x52, 0x25, 0xba, 0xad, 0x40, 0xc9, 0x53,
217         0x13, 0xdf, 0x9b, 0xa9, 0x11, 0x8d, 0xd8, 0xba, 0x73, 0x30, 0x19, 0x03, 0x74, 0xd9, 0x06, 0x4a,
218         0xb0, 0x9e, 0xb0, 0x8d, 0x65, 0xfc, 0x55, 0x12, 0xb6, 0x3a, 0x9d, 0xa4, 0x11, 0x8c, 0x8b, 0x57,
219         0xea, 0x14, 0x33, 0x43, 0xc8, 0x15, 0xe4, 0x2c, 0x90, 0xc7, 0xe4, 0x70, 0x0c, 0x47, 0x77, 0xa2,
220         0x85, 0xa8, 0xc7, 0x21, 0xab, 0x1d, 0x19, 0x67, 0x00, 0x7e, 0x3f, 0x82, 0xca, 0xe9, 0x35, 0x29,
221         0xc4, 0xc8, 0x12, 0x40, 0x5f, 0x75, 0x84, 0x7a, 0x6b, 0xc0, 0xb8, 0x83, 0x4e, 0x15, 0x6e, 0x0e,
222         0x8c, 0xd2, 0xa1, 0x23, 0x16, 0x5e, 0x54, 0x4c, 0xcc, 0x26
223 };
224
225 struct CertHelper : public Cert {
226         CertHelper(RawBuffer buffer, DataType dataType) :
227                 Cert(CryptoBackend::OpenSSL, std::move(buffer), dataType) {}
228
229         using Cert::getEvpShPtr;
230 };
231
232 const std::optional<RawBuffer> NO_BUF;
233 const std::optional<size_t> NO_SIZE;
234 const std::optional<KdfPrf> NO_PRF;
235 const std::optional<KbkdfMode> NO_MODE;
236 const std::optional<KbkdfCounterLocation> NO_LOC;
237
238 constexpr KdfPrf HMAC256 = KdfPrf::HMAC_SHA256;
239 constexpr KdfPrf HMAC384 = KdfPrf::HMAC_SHA384;
240 constexpr KdfPrf HMAC512 = KdfPrf::HMAC_SHA512;
241 constexpr KbkdfCounterLocation BEFORE = KbkdfCounterLocation::BEFORE_FIXED;
242 constexpr KbkdfCounterLocation AFTER = KbkdfCounterLocation::AFTER_FIXED;
243 constexpr KbkdfCounterLocation MIDDLE = KbkdfCounterLocation::MIDDLE_FIXED;
244 constexpr KbkdfMode COUNTER = KbkdfMode::COUNTER;
245
246 const RawBuffer CTX{'c','o','n','t','e','x','t'};
247 const RawBuffer LAB{'l','a','b','e','l'};
248 const RawBuffer FIX{'f','i','x','e','d'};
249 const RawBuffer ONE(1);
250 const RawBuffer EMPTY;
251
252 class KbkdfParamTester {
253 public:
254         KbkdfParamTester() {
255                 Token token;
256                 BOOST_REQUIRE_NO_THROW(token = STORE.import(Data(DataType::BINARY_DATA, RawBuffer(16)),
257                                                             "",
258                                                             EncryptionParams(),
259                                                             RawBuffer()));
260
261                 BOOST_REQUIRE_NO_THROW(secret = STORE.getObject(token, ""));
262         }
263
264         void Ok(const std::optional<size_t>& len,
265                         const std::optional<KdfPrf>& prf,
266                         const std::optional<KbkdfMode>& mode,
267                         const std::optional<KbkdfCounterLocation>& location,
268                         const std::optional<RawBuffer>& context,
269                         const std::optional<RawBuffer>& label,
270                         const std::optional<RawBuffer>& fixed,
271                         const std::optional<size_t>& rlen,
272                         const std::optional<size_t>& llen,
273                         bool noSeparator = false)
274         {
275                 return Test(true, len, prf, mode, location, context, label, fixed, rlen, llen, noSeparator);
276         }
277
278         void Fail(const std::optional<size_t>& len,
279                           const std::optional<KdfPrf>& prf,
280                           const std::optional<KbkdfMode>& mode,
281                           const std::optional<KbkdfCounterLocation>& location,
282                           const std::optional<RawBuffer>& context,
283                           const std::optional<RawBuffer>& label,
284                           const std::optional<RawBuffer>& fixed,
285                           const std::optional<size_t>& rlen,
286                           const std::optional<size_t>& llen,
287                           bool noSeparator = false)
288         {
289                 return Test(
290                         false, len, prf, mode, location, context, label, fixed, rlen, llen, noSeparator);
291         }
292 private:
293         void Test(bool ok,
294                           const std::optional<size_t>& len,
295                           const std::optional<KdfPrf>& prf,
296                           const std::optional<KbkdfMode>& mode,
297                           const std::optional<KbkdfCounterLocation>& location,
298                           const std::optional<RawBuffer>& context,
299                           const std::optional<RawBuffer>& label,
300                           const std::optional<RawBuffer>& fixed,
301                           const std::optional<size_t>& rlen,
302                           const std::optional<size_t>& llen,
303                           bool noSeparator = false)
304         {
305                 CryptoAlgorithm derive;
306                 derive.setParam(ParamName::ALGO_TYPE, AlgoType::KBKDF);
307                 if (len)
308                         derive.setParam(ParamName::KDF_LEN, *len);
309                 if (prf)
310                         derive.setParam(ParamName::KDF_PRF, *prf);
311                 if (mode)
312                         derive.setParam(ParamName::KBKDF_MODE, *mode);
313                 if (location)
314                         derive.setParam(ParamName::KBKDF_COUNTER_LOCATION, *location);
315                 if (context)
316                         derive.setParam(ParamName::KBKDF_CONTEXT, *context);
317                 if (label)
318                         derive.setParam(ParamName::KBKDF_LABEL, *label);
319                 if (fixed)
320                         derive.setParam(ParamName::KBKDF_FIXED_INPUT, *fixed);
321                 if (rlen)
322                         derive.setParam(ParamName::KBKDF_RLEN, *rlen);
323                 if (llen)
324                         derive.setParam(ParamName::KBKDF_LLEN, *llen);
325                 if (noSeparator)
326                         derive.setParam(ParamName::KBKDF_NO_SEPARATOR, 1);
327
328                 GObjUPtr key;
329                 if (ok) {
330                         Token derived;
331                         BOOST_REQUIRE_NO_THROW(derived = secret->derive(derive, "", RawBuffer()));
332
333                         BOOST_REQUIRE(derived.backendId == CryptoBackend::OpenSSL);
334                         BOOST_REQUIRE(derived.dataType == DataType::KEY_AES);
335
336                         BOOST_REQUIRE_NO_THROW(key = STORE.getObject(derived, ""));
337
338                         BOOST_REQUIRE(key->getBinary().size() == *len);
339                 } else {
340                         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
341                 }
342         }
343
344         GObjUPtr secret;
345 };
346
347 size_t oaepMaxSize(size_t key_bits, HashAlgorithm hash)
348 {
349         switch (hash) {
350         case HashAlgorithm::SHA1: return key_bits / 8 - 42;
351         case HashAlgorithm::SHA256: return key_bits / 8 - 66;
352         case HashAlgorithm::SHA384: return key_bits / 8 - 98;
353         case HashAlgorithm::SHA512: return key_bits / 8 - 130;
354         default: BOOST_FAIL("Unsupported OAEP hash"); return 0;
355         }
356 }
357
358 } // namespace
359
360 BOOST_AUTO_TEST_SUITE(SW_TEST)
361
362 POSITIVE_TEST_CASE(generateAKey)
363 {
364         static const std::unordered_map<AlgoType, std::pair<KeyType, KeyType>> algo2types = {
365                 { AlgoType::RSA_GEN, { KeyType::KEY_RSA_PRIVATE, KeyType::KEY_RSA_PUBLIC } },
366                 { AlgoType::DSA_GEN, { KeyType::KEY_DSA_PRIVATE, KeyType::KEY_DSA_PUBLIC } },
367                 { AlgoType::ECDSA_GEN, { KeyType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PUBLIC } }
368         };
369
370         CryptoAlgorithm ca;
371
372         auto testAKey = [&](const Password& prvPass = "", const Password& pubPass = "")
373         {
374                 AlgoType algo;
375                 ca.getParam(ParamName::ALGO_TYPE, algo);
376                 auto& types = algo2types.at(algo);
377
378                 TokenPair tokenPair;
379
380                 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
381
382                 BOOST_REQUIRE_NO_THROW(tokenPair = STORE.generateAKey(ca, prvPass, pubPass, digestPriv, digestPub));
383                 checkKey(tokenPair.first, types.first, prvPass);
384                 checkKey(tokenPair.second, types.second, pubPass);
385         };
386
387         ca.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
388         ca.setParam(ParamName::GEN_KEY_LEN, 1024);
389         testAKey();
390         testAKey("prvpass");
391         testAKey("", "pubpass");
392         testAKey("prvpass", "pubpass");
393         ca.setParam(ParamName::GEN_KEY_LEN, 2048);
394         testAKey();
395         ca.setParam(ParamName::GEN_KEY_LEN, 4096);
396         testAKey();
397
398         ca.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
399         for (int keyLen : { 1024, 2048, 3072, 4096 }) {
400                 ca.setParam(ParamName::GEN_KEY_LEN, keyLen);
401                 testAKey();
402         }
403
404         ca.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
405         ca.setParam(ParamName::GEN_EC, ElipticCurve::prime192v1);
406         testAKey();
407         ca.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
408         testAKey();
409         ca.setParam(ParamName::GEN_EC, ElipticCurve::secp384r1);
410         testAKey();
411 }
412
413 NEGATIVE_TEST_CASE(generateAKey)
414 {
415         std::unique_ptr<CryptoAlgorithm> ca(new CryptoAlgorithm());
416
417         auto invalidGen = [&]
418         {
419                 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
420                 BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", "", digestPriv, digestPub), Exc::Crypto::InputParam);
421         };
422
423         invalidGen();
424
425         ca->setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
426         invalidGen();
427
428         for (int keyLen : { 0, 512, 1023, 1025, 3072, 4097, 8192 }) {
429                 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
430                 invalidGen();
431         }
432
433         ca->setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
434
435         for (int keyLen : { 0, 512, 1023, 1025, 4097, 8192 }) {
436                 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
437                 invalidGen();
438         }
439
440         ca->setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
441         invalidGen();
442         ca->setParam(ParamName::GEN_EC, static_cast<ElipticCurve>(-1));
443         invalidGen();
444         ca->setParam(ParamName::GEN_EC, static_cast<ElipticCurve>(3));
445         invalidGen();
446
447         ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
448         ca->setParam(ParamName::GEN_KEY_LEN, 128);
449         invalidGen();
450         ca->setParam(ParamName::GEN_KEY_LEN, 1024);
451         invalidGen();
452
453
454         ca.reset(new CryptoAlgorithm());
455         ca->setParam(ParamName::GEN_KEY_LEN, 1024);
456         ca->setParam(ParamName::GEN_EC, ElipticCurve::prime192v1);
457         invalidGen();
458         ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
459         invalidGen();
460 }
461
462 POSITIVE_TEST_CASE(generateSKey)
463 {
464         CryptoAlgorithm ca;
465
466         auto testSKey = [&](const Password& pass = "")
467         {
468                 Token token;
469                 const auto digest = makeTestDigest();
470                 BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass, digest));
471                 checkKey(token, KeyType::KEY_AES, pass);
472         };
473
474         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
475         ca.setParam(ParamName::GEN_KEY_LEN, 128);
476         testSKey();
477         testSKey("pass");
478         ca.setParam(ParamName::GEN_KEY_LEN, 192);
479         testSKey();
480         ca.setParam(ParamName::GEN_KEY_LEN, 256);
481         testSKey();
482 }
483
484 NEGATIVE_TEST_CASE(generateSKey)
485 {
486         std::unique_ptr<CryptoAlgorithm> ca(new CryptoAlgorithm());
487
488         auto invalidGen = [&]
489         {
490                 const auto digest = makeTestDigest();
491                 BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, "", digest), Exc::Crypto::InputParam);
492         };
493
494         invalidGen();
495
496         ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
497         invalidGen();
498
499         for (int keyLen : { 0, 64, 127, 129, 257, 512 }) {
500                 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
501                 invalidGen();
502         }
503
504         ca->setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
505         ca->setParam(ParamName::GEN_KEY_LEN, 128);
506         invalidGen();
507         ca->setParam(ParamName::GEN_KEY_LEN, 1024);
508         invalidGen();
509
510         ca.reset(new CryptoAlgorithm());
511         ca->setParam(ParamName::GEN_KEY_LEN, 128);
512         invalidGen();
513 }
514
515 POSITIVE_TEST_CASE(symmetricEncryptDecrypt)
516 {
517         const GObjUPtr keys[] = { generateAes(128), generateAes(192), generateAes(256) };
518         const auto data = createRandom(128);
519         CryptoAlgorithm ca;
520
521         auto encryptDecrypt = [&]
522         {
523                 for (const auto& key : keys) {
524                         RawBuffer encrypted, decrypted;
525                         BOOST_REQUIRE_NO_THROW(encrypted = key->encrypt(ca, data));
526                         BOOST_REQUIRE(encrypted.size() >= data.size());
527                         BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
528                         BOOST_REQUIRE(decrypted == data);
529                 }
530         };
531
532         ca.setParam(ParamName::ED_IV, createRandom(Params::DEFAULT_AES_IV_LEN));
533         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
534         encryptDecrypt();
535         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
536         encryptDecrypt();
537         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CFB);
538         encryptDecrypt();
539         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
540         ca.setParam(ParamName::ED_AAD, createRandom(42));
541         encryptDecrypt();
542         ca.setParam(ParamName::ED_IV, createRandom(11));
543         encryptDecrypt();
544         ca.setParam(ParamName::ED_IV, createRandom(1));
545         encryptDecrypt();
546         ca.setParam(ParamName::ED_IV, createRandom(99));
547         encryptDecrypt();
548 }
549
550 NEGATIVE_TEST_CASE(symmetricEncryptDecrypt)
551 {
552         const auto key = generateAes(128);
553         const auto data = createRandom(128);
554         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
555         CryptoAlgorithm ca;
556
557         // no algo
558         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
559
560         // wrong algo
561         ca.setParam(ParamName::ED_IV, iv);
562         ca.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
563         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
564         ca.setParam(ParamName::ALGO_TYPE, static_cast<AlgoType>(0));
565         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
566
567         for (auto algo : { AlgoType::AES_CTR, AlgoType::AES_CBC, AlgoType::AES_CFB }) {
568                 CryptoAlgorithm ca2;
569                 ca2.setParam(ParamName::ALGO_TYPE, algo);
570
571                 // no iv
572                 BOOST_REQUIRE_THROW(key->encrypt(ca2, data), Exc::Crypto::InputParam);
573
574                 // short iv
575                 ca2.setParam(ParamName::ED_IV, RawBuffer(1));
576                 BOOST_REQUIRE_THROW(key->encrypt(ca2, data), Exc::Crypto::InputParam);
577                 ca2.setParam(ParamName::ED_IV, iv);
578
579                 // short key
580                 SKey shortKey(CryptoBackend::OpenSSL, createRandom(128/8 - 1), DataType::KEY_AES);
581                 BOOST_REQUIRE_THROW(shortKey.encrypt(ca2, data), Exc::Crypto::InternalError);
582
583                 // proper encrypt
584                 auto encrypted = key->encrypt(ca2, data);
585
586                 CryptoAlgorithm ca3;
587
588                 // no algo
589                 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
590                 ca3.setParam(ParamName::ALGO_TYPE, algo);
591
592                 // no iv
593                 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
594
595                 // short iv
596                 ca3.setParam(ParamName::ED_IV, RawBuffer(15));
597                 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
598                 ca3.setParam(ParamName::ED_IV, iv);
599
600                 // short key
601                 BOOST_REQUIRE_THROW(shortKey.decrypt(ca3, encrypted), Exc::Crypto::InternalError);
602         }
603 }
604
605 NEGATIVE_TEST_CASE(symmetricEncryptDecryptGcm)
606 {
607         const auto key = generateAes(128);
608         const auto data = createRandom(128);
609         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
610         const auto aad = createRandom(42);
611         CryptoAlgorithm ca;
612
613         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
614
615         // no iv
616         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
617
618         ca.setParam(ParamName::ED_IV, iv);
619
620         // short key
621         SKey shortKey(CryptoBackend::OpenSSL, createRandom(15), DataType::KEY_AES);
622         BOOST_REQUIRE_THROW(shortKey.encrypt(ca, data), Exc::Crypto::InternalError);
623
624         // wrong tag length
625         for (int tagLen : { 0, 16, 31, 48, 127, 256, 129 }) {
626                 ca.setParam(ParamName::ED_TAG_LEN, tagLen);
627                 BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
628         }
629         ca.setParam(ParamName::ED_TAG_LEN, 128);
630
631         // proper encrypt
632         ca.setParam(ParamName::ED_AAD, aad);
633         auto encrypted = key->encrypt(ca, data);
634
635         CryptoAlgorithm ca2;
636
637         // no algo
638         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
639         ca2.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
640         ca2.setParam(ParamName::ED_AAD, aad);
641
642         // no iv
643         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
644
645         ca2.setParam(ParamName::ED_IV, iv);
646
647         // short key
648         BOOST_REQUIRE_THROW(shortKey.decrypt(ca2, encrypted), Exc::Crypto::InternalError);
649
650         // wrong key
651         auto wrongBuffer = key->getBinary();
652         wrongBuffer[0] ^= 0x1;
653         SKey wrongKey(CryptoBackend::OpenSSL, std::move(wrongBuffer), DataType::KEY_AES);
654
655         BOOST_REQUIRE_THROW(wrongKey.decrypt(ca2, encrypted), Exc::Crypto::InputParam);
656
657         // wrong iv
658         auto wrongIv = iv;
659         wrongIv[iv.size() - 1] ^= 0x1;
660         ca2.setParam(ParamName::ED_IV, wrongIv);
661         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
662
663         // shortened iv
664         auto shortenedIv = iv;
665         static_assert(Params::DEFAULT_AES_GCM_IV_LEN < Params::DEFAULT_AES_IV_LEN);
666         shortenedIv.resize(Params::DEFAULT_AES_GCM_IV_LEN);
667         ca2.setParam(ParamName::ED_IV, shortenedIv);
668         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
669
670         ca2.setParam(ParamName::ED_IV, iv);
671
672         // wrong ciphertext
673         auto wrongCiphertext = encrypted;
674         wrongCiphertext[0] ^= 0x1;
675         BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
676
677         // wrong tag (tag is appended to ciphertext)
678         wrongCiphertext = encrypted;
679         wrongCiphertext.back() ^= 0x1;
680         BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
681
682         // wrong aad
683         auto wrongAad = aad;
684         wrongAad[0] ^= 0x1;
685         ca2.setParam(ParamName::ED_AAD, wrongAad);
686         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
687 }
688
689 POSITIVE_TEST_CASE(gcmIvLengthScrewUpWorkaround)
690 {
691         const auto key = generateAes(128);
692         const auto data = createRandom(128);
693         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
694         CryptoAlgorithm ca;
695         RawBuffer encrypted, decrypted;
696         auto shortIv = iv;
697         shortIv.resize(Params::DEFAULT_AES_GCM_IV_LEN);
698
699         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
700         ca.setParam(ParamName::ED_IV, shortIv);
701         ca.setParam(ParamName::ED_TAG_LEN, 128);
702
703         // encrypt with 12B IV
704         BOOST_REQUIRE_NO_THROW(encrypted = key->encrypt(ca, data));
705
706         // decrypt with 12B IV
707         BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
708         BOOST_REQUIRE(decrypted == data);
709
710         // decrypt with 16B IV should also succeed (workaround)
711         ca.setParam(ParamName::ED_IV, iv);
712         BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
713         BOOST_REQUIRE(decrypted == data);
714
715         // encrypt with 16B IV
716         BOOST_REQUIRE_NO_THROW(encrypted = key->encrypt(ca, data));
717
718         // decrypt with 16B IV
719         BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
720         BOOST_REQUIRE(decrypted == data);
721
722         // decrypt with 12B IV should fail
723         ca.setParam(ParamName::ED_IV, shortIv);
724         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
725 }
726
727 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCtr)
728 {
729         const auto key = generateAes(128);
730         const auto data = createRandom(128);
731         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
732         CryptoAlgorithm ca;
733
734         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
735         ca.setParam(ParamName::ED_IV, iv);
736
737         // wrong ctr len
738         ca.setParam(ParamName::ED_CTR_LEN, 0);
739         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
740         ca.setParam(ParamName::ED_CTR_LEN, 127);
741         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
742         ca.setParam(ParamName::ED_CTR_LEN, 129);
743         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
744
745         ca.setParam(ParamName::ED_CTR_LEN, 128);
746         auto encrypted = key->encrypt(ca, data);
747
748         // wrong ctr len
749         ca.setParam(ParamName::ED_CTR_LEN, 0);
750         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
751         ca.setParam(ParamName::ED_CTR_LEN, 127);
752         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
753         ca.setParam(ParamName::ED_CTR_LEN, 129);
754         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
755 }
756
757 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCbc)
758 {
759         const auto key = generateAes(128);
760         const auto data = createRandom(128);
761         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
762         CryptoAlgorithm ca;
763
764         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
765         ca.setParam(ParamName::ED_IV, iv);
766
767         auto encrypted = key->encrypt(ca, data);
768
769         // broken padding
770         encrypted.back() ^= 0x1;
771         try {
772                 auto decrypted = key->decrypt(ca, encrypted);
773
774                 /*
775                  * There's a high chance that the above ^= 0x1 will produce a 0x01 trailing byte which
776                  * happens to be a valid padding. In such case make sure that the length of the
777                  * decrypted data is different.
778                  */
779
780                 BOOST_REQUIRE(decrypted.size() != data.size());
781         } catch (const Exc::Crypto::InputParam&) {
782                 // This is fine
783         } catch (...) {
784                 BOOST_FAIL("Exc::Crypto::InputParam expected");
785         }
786 }
787
788 POSITIVE_TEST_CASE(asymmetricEncryptDecrypt)
789 {
790         constexpr int KEY_BIT_LEN = 2048;
791         auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
792
793         CryptoAlgorithm enc;
794         enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
795
796         RawBuffer encrypted;
797         RawBuffer decrypted;
798
799         auto encryptDecrypt = [&](const RawBuffer& input)
800         {
801                 BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, input));
802                 BOOST_REQUIRE(encrypted.size() == KEY_BIT_LEN / 8);
803
804                 BOOST_REQUIRE_NO_THROW(decrypted = rsaKeys.prv->decrypt(enc, encrypted));
805                 BOOST_REQUIRE(decrypted == input);
806         };
807
808         encryptDecrypt(createRandom(oaepMaxSize(KEY_BIT_LEN, HashAlgorithm::SHA1)));
809         encryptDecrypt(createRandom(oaepMaxSize(KEY_BIT_LEN, HashAlgorithm::SHA1) - 1));
810         encryptDecrypt(RawBuffer());
811
812         enc.setParam(ParamName::ED_OAEP_HASH, HashAlgorithm::SHA1);
813         encryptDecrypt(createRandom(oaepMaxSize(KEY_BIT_LEN, HashAlgorithm::SHA1)));
814         enc.setParam(ParamName::ED_OAEP_HASH, HashAlgorithm::SHA256);
815         encryptDecrypt(createRandom(oaepMaxSize(KEY_BIT_LEN, HashAlgorithm::SHA256)));
816 }
817
818 NEGATIVE_TEST_CASE(asymmetricEncryptDecrypt)
819 {
820         constexpr int KEY_BIT_LEN = 1024;
821         auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
822         auto& dsaKeys = generateObjUPtrPair(AlgoType::DSA_GEN, KEY_BIT_LEN);
823         const auto data = createRandom(oaepMaxSize(KEY_BIT_LEN, HashAlgorithm::SHA1));
824         auto longData = data;
825         longData.push_back(0);
826
827         CryptoAlgorithm enc;
828         enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
829         BOOST_REQUIRE_THROW(Internals::asymmetricEncrypt(EvpShPtr(), enc, data),
830                             Exc::Crypto::InputParam);
831         BOOST_REQUIRE_THROW(dsaKeys.pub->encrypt(enc, data), Exc::Crypto::InputParam);
832         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc, longData), Exc::Crypto::InputParam);
833
834         CryptoAlgorithm enc2;
835         enc2.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
836         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc2, data), Exc::Crypto::InputParam);
837
838         CryptoAlgorithm enc3;
839         enc3.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
840         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc3, data), Exc::Crypto::InputParam);
841
842         CryptoAlgorithm enc4;
843         enc4.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
844         enc4.setParam(ParamName::ED_LABEL, RawBuffer(64));
845         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc4, data), Exc::Crypto::InputParam);
846
847         CryptoAlgorithm enc5;
848         enc5.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
849         enc5.setParam(ParamName::ED_OAEP_HASH, HashAlgorithm::NONE);
850         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc5, data), Exc::Crypto::InputParam);
851         enc5.setParam(ParamName::ED_OAEP_HASH, static_cast<HashAlgorithm>(-1));
852         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc5, data), Exc::Crypto::InputParam);
853
854         RawBuffer encrypted;
855         BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, data));
856         RawBuffer shortEncrypted = encrypted;
857         shortEncrypted.pop_back();
858         RawBuffer longEncrypted = encrypted;
859         longEncrypted.push_back(0);
860
861         BOOST_REQUIRE_THROW(Internals::asymmetricDecrypt(EvpShPtr(), enc, encrypted),
862                             Exc::Crypto::InputParam);
863         BOOST_REQUIRE_THROW(rsaKeys.pub->decrypt(enc, encrypted), Exc::Crypto::InputParam);
864         BOOST_REQUIRE_THROW(dsaKeys.prv->decrypt(enc, encrypted), Exc::Crypto::InputParam);
865         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, RawBuffer()), Exc::Crypto::InputParam);
866         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, shortEncrypted), Exc::Crypto::InputParam);
867         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, longEncrypted), Exc::Crypto::InputParam);
868
869         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc2, encrypted), Exc::Crypto::InputParam);
870
871         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc3, encrypted), Exc::Crypto::InputParam);
872 }
873
874 POSITIVE_TEST_CASE(sign)
875 {
876         auto message = createRandom(1234);
877         RawBuffer signature;
878
879         auto signVerify = [&](AlgoType keyType,
880                               auto keyParam,
881                               HashAlgorithm hash,
882                               RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
883         {
884                 CryptoAlgorithm algo;
885                 algo.setParam(ParamName::SV_HASH_ALGO, hash);
886                 if (keyType == AlgoType::RSA_GEN)
887                         algo.setParam(ParamName::SV_RSA_PADDING, padding);
888
889                 auto& keys = generateObjUPtrPair(keyType, static_cast<int>(keyParam));
890                 BOOST_REQUIRE_NO_THROW(signature = keys.prv->sign(algo, message));
891                 if (keyType == AlgoType::RSA_GEN) {
892                         BOOST_REQUIRE(signature.size() * 8 == static_cast<size_t>(keyParam));
893                 } else {
894                         BOOST_REQUIRE(!signature.empty());
895                 }
896
897                 int ret = keys.pub->verify(algo, message, signature);
898                 BOOST_REQUIRE(CKM_API_SUCCESS == ret);
899         };
900
901         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
902         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA1, RSAPaddingAlgorithm::X931);
903         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA256, RSAPaddingAlgorithm::PKCS1);
904         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA384, RSAPaddingAlgorithm::PKCS1);
905         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA512, RSAPaddingAlgorithm::PKCS1);
906         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
907         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
908
909         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA1);
910         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA256);
911         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA384);
912         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA512);
913         signVerify(AlgoType::DSA_GEN, 2048, HashAlgorithm::SHA1);
914         signVerify(AlgoType::DSA_GEN, 3072, HashAlgorithm::SHA1);
915         signVerify(AlgoType::DSA_GEN, 4096, HashAlgorithm::SHA1);
916
917         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA1);
918         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA256);
919         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA384);
920         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA512);
921         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime256v1, HashAlgorithm::SHA1);
922         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::secp384r1, HashAlgorithm::SHA1);
923
924         // no hash + no padding
925         message[0] = 0; // make sure it's smaller than the modulus
926         message.resize(4096/8);
927         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::NONE);
928         message.resize(2048/8);
929         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::NONE);
930         message.resize(1024/8);
931         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE);
932
933         // no hash + padding
934         message.resize(512/8);
935         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
936         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
937         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
938 }
939
940 NEGATIVE_TEST_CASE(sign)
941 {
942         auto keysRsa = generateEvpPair(AlgoType::RSA_GEN, 1024);
943         auto keysDsa = generateEvpPair(AlgoType::DSA_GEN, 1024);
944         auto keysEcdsa = generateEvpPair(AlgoType::ECDSA_GEN,
945                                          static_cast<int>(ElipticCurve::prime192v1));
946
947         const auto longMsg = createRandom(1234);
948         auto equalMsg = longMsg;
949         equalMsg.resize(1024/8);
950         auto shortMsg = longMsg;
951         shortMsg.resize(1024/8 - 1); // padding requires 2/11 bytes
952         auto paddingMsg = longMsg;
953         paddingMsg.resize(1024/8 - 11);
954
955         CryptoAlgorithm signRsa;
956         signRsa.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
957         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
958         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::PKCS1);
959
960         CryptoAlgorithm signDsa;
961         signDsa.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_SV);
962         signDsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
963
964         CryptoAlgorithm signEcdsa;
965         signEcdsa.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_SV);
966         signEcdsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
967
968         // wrong key
969         BOOST_REQUIRE_THROW(Internals::sign(nullptr, signRsa, longMsg), Exc::Crypto::InternalError);
970         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.pub.get(), signRsa, longMsg),
971                             Exc::Crypto::InputParam);
972         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.pub.get(), signDsa, longMsg),
973                             Exc::Crypto::InputParam);
974         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.pub.get(), signEcdsa, longMsg),
975                             Exc::Crypto::InputParam);
976
977         // empty crypto
978         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.prv.get(), CryptoAlgorithm(), longMsg),
979                             Exc::Crypto::InputParam);
980         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.prv.get(), CryptoAlgorithm(), longMsg),
981                             Exc::Crypto::InputParam);
982         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.prv.get(), CryptoAlgorithm(), longMsg),
983                             Exc::Crypto::InputParam);
984
985         // wrong crypto
986         CryptoAlgorithm encrypt;
987         encrypt.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
988         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.prv.get(), encrypt, longMsg),
989                             Exc::Crypto::InputParam);
990         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.pub.get(), encrypt, longMsg),
991                             Exc::Crypto::InputParam);
992         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.prv.get(), encrypt, longMsg),
993                             Exc::Crypto::InputParam);
994         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.prv.get(), encrypt, longMsg),
995                             Exc::Crypto::InputParam);
996
997         // Obj API with wrong key type
998         AKey wrongKey(CryptoBackend::OpenSSL, createRandom(16), DataType::KEY_AES);
999         BOOST_REQUIRE_THROW(wrongKey.sign(signRsa, shortMsg), Exc::Crypto::InputParam);
1000
1001         auto invalidSign = [&](const RawBuffer& msg,
1002                                AlgoType signAlgo,
1003                                HashAlgorithm hash,
1004                                RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
1005         {
1006                 EvpPtrPair keys;
1007                 switch (signAlgo) {
1008                 case AlgoType::RSA_SV:
1009                         keys = keysRsa;
1010                         break;
1011                 case AlgoType::DSA_SV:
1012                         keys = keysDsa;
1013                         break;
1014                 case AlgoType::ECDSA_SV:
1015                         keys = keysEcdsa;
1016                         break;
1017                 default:
1018                         BOOST_FAIL("Invalid algorithm. Fix the test.");
1019                 }
1020
1021                 CryptoAlgorithm ca;
1022                 ca.setParam(ParamName::ALGO_TYPE, signAlgo);
1023                 ca.setParam(ParamName::SV_HASH_ALGO, hash);
1024                 if (padding != RSAPaddingAlgorithm::NONE)
1025                         ca.setParam(ParamName::SV_RSA_PADDING, padding);
1026
1027                 BOOST_REQUIRE_THROW(Internals::sign(keys.prv.get(), ca, msg), Exc::Crypto::InputParam);
1028         };
1029
1030         HashAlgorithm wrongHash = static_cast<HashAlgorithm>(-1);
1031
1032         // out of range hash
1033         invalidSign(paddingMsg, AlgoType::RSA_SV, wrongHash, RSAPaddingAlgorithm::PKCS1);
1034         invalidSign(shortMsg, AlgoType::DSA_SV, wrongHash);
1035         invalidSign(shortMsg, AlgoType::ECDSA_SV, wrongHash);
1036
1037         // out of range padding
1038         invalidSign(shortMsg,
1039                     AlgoType::RSA_SV,
1040                     HashAlgorithm::SHA1,
1041                     static_cast<RSAPaddingAlgorithm>(-1));
1042
1043         // no hash + padding + too long message
1044         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
1045         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
1046         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
1047         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
1048
1049         // no hash forbidden
1050         invalidSign(shortMsg, AlgoType::DSA_SV, HashAlgorithm::NONE);
1051         invalidSign(shortMsg, AlgoType::ECDSA_SV, HashAlgorithm::NONE);
1052         invalidSign(paddingMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
1053
1054         // non-none hash + no padding forbidden
1055         invalidSign(equalMsg, AlgoType::RSA_SV, HashAlgorithm::SHA256, RSAPaddingAlgorithm::NONE);
1056
1057         // no hash + no padding + invalid msg length
1058         invalidSign(paddingMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
1059         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
1060         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
1061
1062         auto signature = Internals::sign(keysRsa.prv.get(), signRsa, longMsg);
1063
1064         BOOST_REQUIRE_THROW(Internals::verify(nullptr, signRsa, longMsg, signature),
1065                             Exc::Crypto::InternalError);
1066
1067         // wrong crypto
1068         BOOST_REQUIRE_THROW(Internals::verify(keysRsa.pub.get(), CryptoAlgorithm(), longMsg, signature),
1069                             Exc::Crypto::InputParam);
1070         BOOST_REQUIRE_THROW(Internals::verify(keysRsa.pub.get(), encrypt, longMsg, signature),
1071                             Exc::Crypto::InputParam);
1072
1073         CryptoAlgorithm verifyAlgo;
1074         verifyAlgo.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
1075         auto invalidVerify = [&](HashAlgorithm hash, RSAPaddingAlgorithm padding)
1076         {
1077                 verifyAlgo.setParam(ParamName::SV_HASH_ALGO, hash);
1078                 verifyAlgo.setParam(ParamName::SV_RSA_PADDING, padding);
1079
1080                 BOOST_REQUIRE_THROW(Internals::verify(keysRsa.prv.get(), verifyAlgo, longMsg, signature),
1081                                     Exc::Crypto::InputParam);
1082         };
1083
1084         // out of range hash
1085         invalidVerify(wrongHash, RSAPaddingAlgorithm::PKCS1);
1086
1087         // out of range padding
1088         invalidVerify(HashAlgorithm::SHA1, static_cast<RSAPaddingAlgorithm>(-1));
1089
1090         // non-none hash + no padding forbidden
1091         invalidVerify(HashAlgorithm::SHA1, RSAPaddingAlgorithm::NONE);
1092
1093         auto verificationFailed = [&](EVP_PKEY* key,
1094                                       const CryptoAlgorithm& algo,
1095                                       const RawBuffer& msg,
1096                                       const RawBuffer& sgn)
1097         {
1098                 int ret = Internals::verify(key, algo, msg, sgn);
1099                 BOOST_REQUIRE(ret == CKM_API_ERROR_VERIFICATION_FAILED);
1100         };
1101
1102         auto wrongSignature = signature;
1103         wrongSignature.pop_back();
1104         verificationFailed(keysDsa.pub.get(), signDsa, longMsg, signature);
1105         verificationFailed(keysEcdsa.pub.get(), signEcdsa, longMsg, signature);
1106         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, wrongSignature);
1107         verificationFailed(keysRsa.pub.get(), signRsa, equalMsg, signature);
1108
1109         // different padding
1110         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::X931);
1111         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1112         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::NONE);
1113         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::NONE);
1114         verificationFailed(keysRsa.pub.get(), signRsa, equalMsg, signature);
1115         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::PKCS1);
1116
1117         // different hash
1118         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA256);
1119         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1120         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA384);
1121         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1122         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA512);
1123         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1124 }
1125
1126 POSITIVE_TEST_CASE(importGetObjectDestroy)
1127 {
1128         const auto buffer = createRandom(16);
1129         Data data(DataType::BINARY_DATA, buffer);
1130         EncryptionParams ep;
1131         Token token;
1132         const auto digest = makeTestDigest();
1133
1134         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1135         BOOST_REQUIRE(token.backendId == CryptoBackend::OpenSSL);
1136         BOOST_REQUIRE(token.dataType == data.type);
1137         BOOST_REQUIRE(!token.data.empty());
1138
1139         GObjUPtr obj;
1140         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, "pass"));
1141         BOOST_REQUIRE(obj);
1142         BOOST_REQUIRE(obj->getBinary() == buffer);
1143
1144         BOOST_REQUIRE_NO_THROW(STORE.destroy(token));
1145 }
1146
1147 NEGATIVE_TEST_CASE(import)
1148 {
1149         Data data(DataType::BINARY_DATA, createRandom(16));
1150         EncryptionParams ep;
1151         ep.iv = createRandom(16);
1152         const auto digest = makeTestDigest();
1153
1154         BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep, digest), Exc::Crypto::OperationNotSupported);
1155 }
1156
1157 NEGATIVE_TEST_CASE(getObject)
1158 {
1159         Data data(DataType::BINARY_DATA, createRandom(16));
1160         EncryptionParams ep;
1161         Token token;
1162         const auto digest = makeTestDigest();
1163
1164         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1165
1166         BOOST_REQUIRE_THROW(STORE.getObject(token, "wrongpass"), Exc::Crypto::AuthenticationFailed);
1167
1168         token.backendId = CryptoBackend::TrustZone;
1169         BOOST_REQUIRE_THROW(STORE.getObject(token, "pass"), Exc::Crypto::WrongBackend);
1170 }
1171
1172 POSITIVE_TEST_CASE(certImportGetObject)
1173 {
1174         CertHelper cert(X509_CERT, DataType::CERTIFICATE);
1175         EvpShPtr evp, evp2;
1176         BOOST_REQUIRE_NO_THROW(evp = cert.getEvpShPtr());
1177         BOOST_REQUIRE(evp);
1178         BOOST_REQUIRE_NO_THROW(evp2 = cert.getEvpShPtr());
1179         BOOST_REQUIRE(evp2.get() == evp.get());
1180
1181         EncryptionParams ep;
1182         Data data(DataType::CERTIFICATE, cert.getBinary());
1183         Token token;
1184         const auto digest = makeTestDigest();
1185
1186         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep, digest));
1187         BOOST_REQUIRE(token.dataType == DataType::CERTIFICATE);
1188
1189         GObjUPtr obj;
1190         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
1191         BOOST_REQUIRE(obj);
1192 }
1193
1194 NEGATIVE_TEST_CASE(cert)
1195 {
1196         RawBuffer wrongX509 = X509_CERT;
1197         wrongX509.pop_back();
1198         CertHelper cert(wrongX509, DataType::CERTIFICATE);
1199
1200         BOOST_REQUIRE_THROW(cert.getEvpShPtr(), Exc::Crypto::InternalError);
1201 }
1202
1203 POSITIVE_TEST_CASE(deriveECDH)
1204 {
1205         CryptoAlgorithm gen;
1206         gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1207         gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1208
1209         auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1210         auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1211
1212         CryptoAlgorithm derive;
1213         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1214
1215         // our part
1216         GObjUPtr peersPublic;
1217         BOOST_REQUIRE_NO_THROW(peersPublic = STORE.getObject(peers.second, ""));
1218         derive.setParam(ParamName::ECDH_PUBKEY, peersPublic->getBinary());
1219
1220         GObjUPtr oursPrivate;
1221         BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1222
1223         Token oursDerived;
1224         BOOST_REQUIRE_NO_THROW(oursDerived = oursPrivate->derive(derive, "", RawBuffer()));
1225
1226         BOOST_REQUIRE(oursDerived.backendId == CryptoBackend::OpenSSL);
1227         BOOST_REQUIRE(oursDerived.dataType == DataType::BINARY_DATA);
1228
1229         GObjUPtr oursDerivedObj;
1230         BOOST_REQUIRE_NO_THROW(oursDerivedObj = STORE.getObject(oursDerived, ""));
1231         BOOST_REQUIRE(!oursDerivedObj->getBinary().empty());
1232
1233         // peer's part
1234         GObjUPtr oursPublic;
1235         BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1236         derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1237
1238         GObjUPtr peersPrivate;
1239         BOOST_REQUIRE_NO_THROW(peersPrivate = STORE.getObject(peers.first, ""));
1240
1241         Token peersDerived;
1242         BOOST_REQUIRE_NO_THROW(peersDerived = peersPrivate->derive(derive, "", RawBuffer()));
1243
1244         BOOST_REQUIRE(peersDerived.backendId == CryptoBackend::OpenSSL);
1245         BOOST_REQUIRE(peersDerived.dataType == DataType::BINARY_DATA);
1246
1247         GObjUPtr peersDerivedObj;
1248         BOOST_REQUIRE_NO_THROW(peersDerivedObj = STORE.getObject(peersDerived, ""));
1249         BOOST_REQUIRE(oursDerivedObj->getBinary() == peersDerivedObj->getBinary());
1250 }
1251
1252 NEGATIVE_TEST_CASE(deriveECDH)
1253 {
1254         CryptoAlgorithm gen;
1255         gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1256         gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1257
1258         auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1259         auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1260
1261         GObjUPtr oursPrivate;
1262         BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1263
1264         CryptoAlgorithm derive;
1265
1266         // no algorithm
1267         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1268
1269         // wrong algorithm
1270         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1271         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1272
1273         // no pubkey
1274         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1275         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1276
1277         // empty pubkey
1278         derive.setParam(ParamName::ECDH_PUBKEY, RawBuffer());
1279         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1280
1281         // private key instead of public
1282         derive.setParam(ParamName::ECDH_PUBKEY, oursPrivate->getBinary());
1283         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1284
1285         // public key instead of private key
1286         GObjUPtr oursPublic;
1287         BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1288         derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1289         BOOST_REQUIRE_THROW(oursPublic->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1290
1291         // RSA key instead of EC
1292         gen.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
1293         gen.setParam(ParamName::GEN_KEY_LEN, 1024);
1294         auto rsa = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1295         GObjUPtr rsaPrivate;
1296         BOOST_REQUIRE_NO_THROW(rsaPrivate = STORE.getObject(rsa.first, ""));
1297         BOOST_REQUIRE_THROW(rsaPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1298 }
1299
1300 POSITIVE_TEST_CASE(deriveKBKDFHMAC)
1301 {
1302         KbkdfParamTester test;
1303
1304         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1305
1306         test.Ok(16, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1307         test.Ok(24, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1308
1309         test.Ok(32, HMAC384, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1310         test.Ok(32, HMAC512, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1311
1312         test.Ok(32, HMAC256, COUNTER, AFTER,  CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1313         test.Ok(32, HMAC256, COUNTER, MIDDLE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1314
1315         test.Ok(32, HMAC256, COUNTER, BEFORE, ONE,   LAB,   NO_BUF, NO_SIZE, NO_SIZE);
1316         test.Ok(32, HMAC256, COUNTER, BEFORE, EMPTY, LAB,   NO_BUF, NO_SIZE, NO_SIZE);
1317         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX,   ONE,   NO_BUF, NO_SIZE, NO_SIZE);
1318         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX,   EMPTY, NO_BUF, NO_SIZE, NO_SIZE);
1319         test.Ok(32, HMAC256, COUNTER, BEFORE, EMPTY, EMPTY, NO_BUF, NO_SIZE, NO_SIZE);
1320
1321         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1322         test.Ok(32, HMAC256, COUNTER, AFTER,  NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1323
1324         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, ONE,   NO_SIZE, NO_SIZE);
1325         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, EMPTY, NO_SIZE, NO_SIZE);
1326
1327         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 32, NO_SIZE);
1328         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 24, NO_SIZE);
1329         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 16, NO_SIZE);
1330         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 8,  NO_SIZE);
1331
1332         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 32);
1333         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 24);
1334         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 16);
1335         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 8);
1336         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 0);
1337
1338         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE, true);
1339         test.Ok(32, HMAC256, COUNTER, MIDDLE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE, true);
1340 }
1341
1342 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongAlgo)
1343 {
1344         Token token;
1345         BOOST_REQUIRE_NO_THROW(token = STORE.import(Data(DataType::BINARY_DATA, RawBuffer(16)),
1346                                                     "",
1347                                                     EncryptionParams(),
1348                                                     RawBuffer()));
1349
1350         GObjUPtr secret;
1351         BOOST_REQUIRE_NO_THROW(secret = STORE.getObject(token, ""));
1352
1353         CryptoAlgorithm derive;
1354
1355         // no algorithm
1356         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1357
1358         // wrong algorithm
1359         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1360         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1361 }
1362
1363 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongParams)
1364 {
1365         KbkdfParamTester test;
1366
1367         // missing parameters
1368         test.Fail(NO_SIZE, HMAC256, COUNTER, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1369         test.Fail(32,      NO_PRF,  COUNTER, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1370         test.Fail(32,      HMAC256, NO_MODE, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1371         test.Fail(32,      HMAC256, COUNTER, NO_LOC, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1372         test.Fail(32,      HMAC256, COUNTER, BEFORE, NO_BUF, LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1373         test.Fail(32,      HMAC256, COUNTER, BEFORE, CTX,    NO_BUF, NO_BUF, NO_SIZE, NO_SIZE);
1374
1375         // conflicting parameters
1376         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX,    LAB,    FIX, NO_SIZE, NO_SIZE);
1377         test.Fail(32, HMAC256, COUNTER, BEFORE, NO_BUF, LAB,    FIX, NO_SIZE, NO_SIZE);
1378         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX,    NO_BUF, FIX, NO_SIZE, NO_SIZE);
1379         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1380         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, 32);
1381         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, 0);
1382         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE, true);
1383
1384         // invalid values
1385         test.Fail(0,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1386         test.Fail(1,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1387         test.Fail(8,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1388         test.Fail(64, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1389
1390         test.Fail(32, static_cast<KdfPrf>(0), COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1391         test.Fail(32, static_cast<KdfPrf>(4), COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1392
1393         test.Fail(32, HMAC256, static_cast<KbkdfMode>(0), BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1394         test.Fail(32, HMAC256, static_cast<KbkdfMode>(2), BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1395
1396         auto wrongLocation1 = static_cast<KbkdfCounterLocation>(0);
1397         auto wrongLocation2 = static_cast<KbkdfCounterLocation>(4);
1398         test.Fail(32, HMAC256, COUNTER, wrongLocation1, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1399         test.Fail(32, HMAC256, COUNTER, wrongLocation2, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1400
1401         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 0,  NO_SIZE);
1402         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 1,  NO_SIZE);
1403         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 7,  NO_SIZE);
1404         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 64, NO_SIZE);
1405
1406         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 1);
1407         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 7);
1408         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 64);
1409 }
1410
1411 NEGATIVE_TEST_CASE(cipherAPI)
1412 {
1413         auto key = generateAes(256);
1414         auto& rsa = generateObjUPtrPair(AlgoType::RSA_GEN, 1024);
1415
1416         // no algorithm
1417         BOOST_REQUIRE_THROW(key->initContext(CryptoAlgorithm(), true), Exc::Crypto::InputParam);
1418
1419         CryptoAlgorithm ca;
1420         ca.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
1421
1422         // symmetric encryption only
1423         BOOST_REQUIRE_THROW(rsa.prv->initContext(ca, true), Exc::Crypto::OperationNotSupported);
1424         BOOST_REQUIRE_THROW(rsa.pub->initContext(ca, true), Exc::Crypto::OperationNotSupported);
1425
1426         // unsupported algorithm
1427         BOOST_REQUIRE_THROW(key->initContext(ca, true), Exc::Crypto::InputParam);
1428
1429         // no IV
1430         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
1431         BOOST_REQUIRE_THROW(key->initContext(ca, true), Exc::Crypto::InputParam);
1432
1433         auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
1434         ca.setParam(ParamName::ED_IV, iv);
1435         GCtxShPtr gcm;
1436         BOOST_REQUIRE_NO_THROW(gcm = key->initContext(ca, true));
1437
1438         // AAD missing
1439         BOOST_REQUIRE_THROW(gcm->customize(ca), Exc::Crypto::InputParam);
1440
1441         auto aad = createRandom(32);
1442         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
1443         ca.setParam(ParamName::ED_AAD, aad);
1444
1445         // no customization in CBC
1446         GCtxShPtr cbc;
1447         BOOST_REQUIRE_NO_THROW(cbc = key->initContext(ca, true));
1448         BOOST_REQUIRE_THROW(cbc->customize(ca), Exc::Crypto::InputParam);
1449
1450         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1451
1452         auto plaintext = createRandom(128);
1453         RawBuffer ciphertext;
1454         BOOST_REQUIRE_NO_THROW(ciphertext = gcm->update(plaintext));
1455
1456         // no customization after update
1457         BOOST_REQUIRE_THROW(gcm->customize(ca), Exc::Crypto::InputParam);
1458
1459         BOOST_REQUIRE_NO_THROW(ciphertext = gcm->update(plaintext));
1460         BOOST_REQUIRE_NO_THROW(ciphertext = gcm->update(plaintext));
1461
1462         // no tag should be passed for encryption
1463         auto tag = createRandom(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
1464         BOOST_REQUIRE_THROW(gcm->finalize(tag), Exc::Crypto::InputParam);
1465
1466         BOOST_REQUIRE_NO_THROW(tag = gcm->finalize(RawBuffer()));
1467
1468         // no update after finalize
1469         BOOST_REQUIRE_THROW(gcm->update(plaintext), Exc::Crypto::InputParam);
1470
1471         BOOST_REQUIRE_NO_THROW(gcm = key->initContext(ca, false));
1472         BOOST_REQUIRE_THROW(gcm->finalize(tag), Exc::Crypto::InputParam);
1473 }
1474
1475 POSITIVE_TEST_CASE(cipherAPI)
1476 {
1477         auto key = generateAes(256);
1478         RawBuffer plaintext[4] = {createRandom(128),createRandom(129),createRandom(130),createRandom(131)};
1479         RawBuffer ciphertext[4];
1480         CryptoAlgorithm ca;
1481         GCtxShPtr gcm;
1482         RawBuffer tag;
1483
1484         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
1485         auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
1486         ca.setParam(ParamName::ED_IV, iv);
1487         RawBuffer aad[4] = {createRandom(32), createRandom(33), createRandom(34), createRandom(35)};
1488         ca.setParam(ParamName::ED_AAD, aad[0]);
1489         BOOST_REQUIRE_NO_THROW(gcm = key->initContext(ca, true));
1490         iv.resize(6);
1491         ca.setParam(ParamName::ED_IV, iv);
1492         BOOST_REQUIRE_NO_THROW(gcm = key->initContext(ca, true));
1493
1494         ca.setParam(ParamName::ED_AAD, aad[1]);
1495         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1496         ca.setParam(ParamName::ED_AAD, aad[2]);
1497         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1498         ca.setParam(ParamName::ED_AAD, aad[3]);
1499         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1500
1501         for (size_t i = 0; i < 4; i++)
1502                 BOOST_REQUIRE_NO_THROW(ciphertext[i] = gcm->update(plaintext[i]));
1503
1504         BOOST_REQUIRE_NO_THROW(tag = gcm->finalize(RawBuffer()));
1505
1506         // decrypt
1507         ca.setParam(ParamName::ED_AAD, aad[0]);
1508
1509         BOOST_REQUIRE_NO_THROW(gcm = key->initContext(ca, false));
1510
1511         ca.setParam(ParamName::ED_AAD, aad[1]);
1512         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1513         ca.setParam(ParamName::ED_AAD, aad[2]);
1514         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1515         ca.setParam(ParamName::ED_AAD, aad[3]);
1516         BOOST_REQUIRE_NO_THROW(gcm->customize(ca));
1517
1518         for (size_t i = 0; i < 4; i++) {
1519                 RawBuffer decrypted;
1520                 BOOST_REQUIRE_NO_THROW(decrypted = gcm->update(ciphertext[i]));
1521                 BOOST_REQUIRE(decrypted == plaintext[i]);
1522         }
1523
1524         BOOST_REQUIRE_NO_THROW(gcm->finalize(tag));
1525 }
1526
1527 POSITIVE_TEST_CASE(backendInfo)
1528 {
1529         size_t ret;
1530         BOOST_REQUIRE_NO_THROW(ret = STORE.maxChunkSize());
1531         BOOST_REQUIRE(ret == 0);
1532 }
1533
1534 BOOST_AUTO_TEST_SUITE_END()