19879aeb5b02fed4caebef399b2f8561cb03f412
[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 } // namespace
348
349 BOOST_AUTO_TEST_SUITE(SW_TEST)
350
351 POSITIVE_TEST_CASE(generateAKey)
352 {
353         static const std::unordered_map<AlgoType, std::pair<KeyType, KeyType>> algo2types = {
354                 { AlgoType::RSA_GEN, { KeyType::KEY_RSA_PRIVATE, KeyType::KEY_RSA_PUBLIC } },
355                 { AlgoType::DSA_GEN, { KeyType::KEY_DSA_PRIVATE, KeyType::KEY_DSA_PUBLIC } },
356                 { AlgoType::ECDSA_GEN, { KeyType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PUBLIC } }
357         };
358
359         CryptoAlgorithm ca;
360
361         auto testAKey = [&](const Password& prvPass = "", const Password& pubPass = "")
362         {
363                 AlgoType algo;
364                 ca.getParam(ParamName::ALGO_TYPE, algo);
365                 auto& types = algo2types.at(algo);
366
367                 TokenPair tokenPair;
368
369                 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
370
371                 BOOST_REQUIRE_NO_THROW(tokenPair = STORE.generateAKey(ca, prvPass, pubPass, digestPriv, digestPub));
372                 checkKey(tokenPair.first, types.first, prvPass);
373                 checkKey(tokenPair.second, types.second, pubPass);
374         };
375
376         ca.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
377         ca.setParam(ParamName::GEN_KEY_LEN, 1024);
378         testAKey();
379         testAKey("prvpass");
380         testAKey("", "pubpass");
381         testAKey("prvpass", "pubpass");
382         ca.setParam(ParamName::GEN_KEY_LEN, 2048);
383         testAKey();
384         ca.setParam(ParamName::GEN_KEY_LEN, 4096);
385         testAKey();
386
387         ca.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
388         for (int keyLen : { 1024, 2048, 3072, 4096 }) {
389                 ca.setParam(ParamName::GEN_KEY_LEN, keyLen);
390                 testAKey();
391         }
392
393         ca.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
394         ca.setParam(ParamName::GEN_EC, ElipticCurve::prime192v1);
395         testAKey();
396         ca.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
397         testAKey();
398         ca.setParam(ParamName::GEN_EC, ElipticCurve::secp384r1);
399         testAKey();
400 }
401
402 NEGATIVE_TEST_CASE(generateAKey)
403 {
404         std::unique_ptr<CryptoAlgorithm> ca(new CryptoAlgorithm());
405
406         auto invalidGen = [&]
407         {
408                 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
409                 BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", "", digestPriv, digestPub), Exc::Crypto::InputParam);
410         };
411
412         invalidGen();
413
414         ca->setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
415         invalidGen();
416
417         for (int keyLen : { 0, 512, 1023, 1025, 3072, 4097, 8192 }) {
418                 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
419                 invalidGen();
420         }
421
422         ca->setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
423
424         for (int keyLen : { 0, 512, 1023, 1025, 4097, 8192 }) {
425                 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
426                 invalidGen();
427         }
428
429         ca->setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
430         invalidGen();
431         ca->setParam(ParamName::GEN_EC, static_cast<ElipticCurve>(-1));
432         invalidGen();
433         ca->setParam(ParamName::GEN_EC, static_cast<ElipticCurve>(3));
434         invalidGen();
435
436         ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
437         ca->setParam(ParamName::GEN_KEY_LEN, 128);
438         invalidGen();
439         ca->setParam(ParamName::GEN_KEY_LEN, 1024);
440         invalidGen();
441
442
443         ca.reset(new CryptoAlgorithm());
444         ca->setParam(ParamName::GEN_KEY_LEN, 1024);
445         ca->setParam(ParamName::GEN_EC, ElipticCurve::prime192v1);
446         invalidGen();
447         ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
448         invalidGen();
449 }
450
451 POSITIVE_TEST_CASE(generateSKey)
452 {
453         CryptoAlgorithm ca;
454
455         auto testSKey = [&](const Password& pass = "")
456         {
457                 Token token;
458                 const auto digest = makeTestDigest();
459                 BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass, digest));
460                 checkKey(token, KeyType::KEY_AES, pass);
461         };
462
463         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
464         ca.setParam(ParamName::GEN_KEY_LEN, 128);
465         testSKey();
466         testSKey("pass");
467         ca.setParam(ParamName::GEN_KEY_LEN, 192);
468         testSKey();
469         ca.setParam(ParamName::GEN_KEY_LEN, 256);
470         testSKey();
471 }
472
473 NEGATIVE_TEST_CASE(generateSKey)
474 {
475         std::unique_ptr<CryptoAlgorithm> ca(new CryptoAlgorithm());
476
477         auto invalidGen = [&]
478         {
479                 const auto digest = makeTestDigest();
480                 BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, "", digest), Exc::Crypto::InputParam);
481         };
482
483         invalidGen();
484
485         ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
486         invalidGen();
487
488         for (int keyLen : { 0, 64, 127, 129, 257, 512 }) {
489                 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
490                 invalidGen();
491         }
492
493         ca->setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
494         ca->setParam(ParamName::GEN_KEY_LEN, 128);
495         invalidGen();
496         ca->setParam(ParamName::GEN_KEY_LEN, 1024);
497         invalidGen();
498
499         ca.reset(new CryptoAlgorithm());
500         ca->setParam(ParamName::GEN_KEY_LEN, 128);
501         invalidGen();
502 }
503
504 POSITIVE_TEST_CASE(symmetricEncryptDecrypt)
505 {
506         const GObjUPtr keys[] = { generateAes(128), generateAes(192), generateAes(256) };
507         const auto data = createRandom(128);
508         CryptoAlgorithm ca;
509
510         auto encryptDecrypt = [&]
511         {
512                 for (const auto& key : keys) {
513                         RawBuffer encrypted, decrypted;
514                         BOOST_REQUIRE_NO_THROW(encrypted = key->encrypt(ca, data));
515                         BOOST_REQUIRE(encrypted.size() >= data.size());
516                         BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
517                         BOOST_REQUIRE(decrypted == data);
518                 }
519         };
520
521         ca.setParam(ParamName::ED_IV, createRandom(Params::DEFAULT_AES_IV_LEN));
522         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
523         encryptDecrypt();
524         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
525         encryptDecrypt();
526         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CFB);
527         encryptDecrypt();
528         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
529         ca.setParam(ParamName::ED_AAD, createRandom(42));
530         encryptDecrypt();
531 }
532
533 NEGATIVE_TEST_CASE(symmetricEncryptDecrypt)
534 {
535         const auto key = generateAes(128);
536         const auto data = createRandom(128);
537         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
538         CryptoAlgorithm ca;
539
540         // no algo
541         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
542
543         // wrong algo
544         ca.setParam(ParamName::ED_IV, iv);
545         ca.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
546         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
547         ca.setParam(ParamName::ALGO_TYPE, static_cast<AlgoType>(0));
548         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
549
550         for (auto algo : { AlgoType::AES_CTR, AlgoType::AES_CBC, AlgoType::AES_CFB }) {
551                 CryptoAlgorithm ca2;
552                 ca2.setParam(ParamName::ALGO_TYPE, algo);
553
554                 // no iv
555                 BOOST_REQUIRE_THROW(key->encrypt(ca2, data), Exc::Crypto::InputParam);
556
557                 // short iv
558                 ca2.setParam(ParamName::ED_IV, RawBuffer(1));
559                 BOOST_REQUIRE_THROW(key->encrypt(ca2, data), Exc::Crypto::InputParam);
560                 ca2.setParam(ParamName::ED_IV, iv);
561
562                 // short key
563                 SKey shortKey(CryptoBackend::OpenSSL, createRandom(128/8 - 1), DataType::KEY_AES);
564                 BOOST_REQUIRE_THROW(shortKey.encrypt(ca2, data), Exc::Crypto::InternalError);
565
566                 // proper encrypt
567                 auto encrypted = key->encrypt(ca2, data);
568
569                 CryptoAlgorithm ca3;
570
571                 // no algo
572                 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
573                 ca3.setParam(ParamName::ALGO_TYPE, algo);
574
575                 // no iv
576                 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
577
578                 // short iv
579                 ca3.setParam(ParamName::ED_IV, RawBuffer(15));
580                 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
581                 ca3.setParam(ParamName::ED_IV, iv);
582
583                 // short key
584                 BOOST_REQUIRE_THROW(shortKey.decrypt(ca3, encrypted), Exc::Crypto::InternalError);
585         }
586 }
587
588 NEGATIVE_TEST_CASE(symmetricEncryptDecryptGcm)
589 {
590         const auto key = generateAes(128);
591         const auto data = createRandom(128);
592         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
593         const auto aad = createRandom(42);
594         CryptoAlgorithm ca;
595
596         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
597
598         // no iv
599         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
600
601         // short iv
602         ca.setParam(ParamName::ED_IV, RawBuffer(1));
603         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InternalError);
604         ca.setParam(ParamName::ED_IV, iv);
605
606         // short key
607         SKey shortKey(CryptoBackend::OpenSSL, createRandom(15), DataType::KEY_AES);
608         BOOST_REQUIRE_THROW(shortKey.encrypt(ca, data), Exc::Crypto::InternalError);
609
610         // wrong tag length
611         for (int tagLen : { 0, 16, 31, 48, 127, 256, 129 }) {
612                 ca.setParam(ParamName::ED_TAG_LEN, tagLen);
613                 BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
614         }
615         ca.setParam(ParamName::ED_TAG_LEN, 128);
616
617         // proper encrypt
618         ca.setParam(ParamName::ED_AAD, aad);
619         auto encrypted = key->encrypt(ca, data);
620
621         CryptoAlgorithm ca2;
622
623         // no algo
624         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
625         ca2.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
626         ca2.setParam(ParamName::ED_AAD, aad);
627
628         // no iv
629         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
630
631         // short iv
632         ca2.setParam(ParamName::ED_IV, RawBuffer(1));
633         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InternalError);
634         ca2.setParam(ParamName::ED_IV, iv);
635
636         // short key
637         BOOST_REQUIRE_THROW(shortKey.decrypt(ca2, encrypted), Exc::Crypto::InternalError);
638
639         // wrong key
640         auto wrongBuffer = key->getBinary();
641         wrongBuffer[0] ^= 0x1;
642         SKey wrongKey(CryptoBackend::OpenSSL, std::move(wrongBuffer), DataType::KEY_AES);
643
644         BOOST_REQUIRE_THROW(wrongKey.decrypt(ca2, encrypted), Exc::Crypto::InputParam);
645
646         // wrong iv
647         auto wrongIv = iv;
648         wrongIv[0] ^= 0x1;
649         ca2.setParam(ParamName::ED_IV, wrongIv);
650         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
651         ca2.setParam(ParamName::ED_IV, iv);
652
653         // wrong ciphertext
654         auto wrongCiphertext = encrypted;
655         wrongCiphertext[0] ^= 0x1;
656         BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
657
658         // wrong tag (tag is appended to ciphertext)
659         wrongCiphertext = encrypted;
660         wrongCiphertext.back() ^= 0x1;
661         BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
662
663         // wrong aad
664         auto wrongAad = aad;
665         wrongAad[0] ^= 0x1;
666         ca2.setParam(ParamName::ED_AAD, wrongAad);
667         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
668 }
669
670 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCtr)
671 {
672         const auto key = generateAes(128);
673         const auto data = createRandom(128);
674         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
675         CryptoAlgorithm ca;
676
677         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
678         ca.setParam(ParamName::ED_IV, iv);
679
680         // wrong ctr len
681         ca.setParam(ParamName::ED_CTR_LEN, 0);
682         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
683         ca.setParam(ParamName::ED_CTR_LEN, 127);
684         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
685         ca.setParam(ParamName::ED_CTR_LEN, 129);
686         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
687
688         ca.setParam(ParamName::ED_CTR_LEN, 128);
689         auto encrypted = key->encrypt(ca, data);
690
691         // wrong ctr len
692         ca.setParam(ParamName::ED_CTR_LEN, 0);
693         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
694         ca.setParam(ParamName::ED_CTR_LEN, 127);
695         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
696         ca.setParam(ParamName::ED_CTR_LEN, 129);
697         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
698 }
699
700 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCbc)
701 {
702         const auto key = generateAes(128);
703         const auto data = createRandom(128);
704         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
705         CryptoAlgorithm ca;
706
707         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
708         ca.setParam(ParamName::ED_IV, iv);
709
710         auto encrypted = key->encrypt(ca, data);
711
712         // broken padding
713         encrypted.back() ^= 0x1;
714         try {
715                 auto decrypted = key->decrypt(ca, encrypted);
716
717                 /*
718                  * There's a high chance that the above ^= 0x1 will produce a 0x01 trailing byte which
719                  * happens to be a valid padding. In such case make sure that the length of the
720                  * decrypted data is different.
721                  */
722
723                 BOOST_REQUIRE(decrypted.size() != data.size());
724         } catch (const Exc::Crypto::InputParam&) {
725                 // This is fine
726         } catch (...) {
727                 BOOST_FAIL("Exc::Crypto::InputParam expected");
728         }
729 }
730
731 POSITIVE_TEST_CASE(asymmetricEncryptDecrypt)
732 {
733         constexpr int KEY_BIT_LEN = 1024;
734         auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
735
736         CryptoAlgorithm enc;
737         enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
738
739         RawBuffer encrypted;
740         RawBuffer decrypted;
741
742         auto encryptDecrypt = [&](const RawBuffer& input)
743         {
744                 BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, input));
745                 BOOST_REQUIRE(encrypted.size() == KEY_BIT_LEN / 8);
746
747                 BOOST_REQUIRE_NO_THROW(decrypted = rsaKeys.prv->decrypt(enc, encrypted));
748                 BOOST_REQUIRE(decrypted == input);
749         };
750
751         encryptDecrypt(createRandom(KEY_BIT_LEN / 8 - 42));
752         encryptDecrypt(createRandom(KEY_BIT_LEN / 8 - 42 - 1));
753         encryptDecrypt(RawBuffer());
754 }
755
756 NEGATIVE_TEST_CASE(asymmetricEncryptDecrypt)
757 {
758         constexpr int KEY_BIT_LEN = 1024;
759         auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
760         auto& dsaKeys = generateObjUPtrPair(AlgoType::DSA_GEN, KEY_BIT_LEN);
761         const auto data = createRandom(KEY_BIT_LEN / 8 - 42);
762         auto longData = data;
763         longData.push_back(0);
764
765         CryptoAlgorithm enc;
766         enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
767         BOOST_REQUIRE_THROW(Internals::asymmetricEncrypt(EvpShPtr(), enc, data),
768                             Exc::Crypto::InputParam);
769         BOOST_REQUIRE_THROW(dsaKeys.pub->encrypt(enc, data), Exc::Crypto::InputParam);
770         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc, longData), Exc::Crypto::InputParam);
771
772         CryptoAlgorithm enc2;
773         enc2.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
774         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc2, data), Exc::Crypto::InputParam);
775
776         CryptoAlgorithm enc3;
777         enc3.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
778         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc3, data), Exc::Crypto::InputParam);
779
780         CryptoAlgorithm enc4;
781         enc4.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
782         enc4.setParam(ParamName::ED_LABEL, RawBuffer(64));
783         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc4, data), Exc::Crypto::InputParam);
784
785         RawBuffer encrypted;
786         BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, data));
787         RawBuffer shortEncrypted = encrypted;
788         shortEncrypted.pop_back();
789         RawBuffer longEncrypted = encrypted;
790         longEncrypted.push_back(0);
791
792         BOOST_REQUIRE_THROW(Internals::asymmetricDecrypt(EvpShPtr(), enc, encrypted),
793                             Exc::Crypto::InputParam);
794         BOOST_REQUIRE_THROW(rsaKeys.pub->decrypt(enc, encrypted), Exc::Crypto::InputParam);
795         BOOST_REQUIRE_THROW(dsaKeys.prv->decrypt(enc, encrypted), Exc::Crypto::InputParam);
796         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, RawBuffer()), Exc::Crypto::InputParam);
797         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, shortEncrypted), Exc::Crypto::InputParam);
798         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, longEncrypted), Exc::Crypto::InputParam);
799
800         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc2, encrypted), Exc::Crypto::InputParam);
801
802         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc3, encrypted), Exc::Crypto::InputParam);
803 }
804
805 POSITIVE_TEST_CASE(sign)
806 {
807         auto message = createRandom(1234);
808         RawBuffer signature;
809
810         auto signVerify = [&](AlgoType keyType,
811                               auto keyParam,
812                               HashAlgorithm hash,
813                               RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
814         {
815                 CryptoAlgorithm algo;
816                 algo.setParam(ParamName::SV_HASH_ALGO, hash);
817                 if (keyType == AlgoType::RSA_GEN)
818                         algo.setParam(ParamName::SV_RSA_PADDING, padding);
819
820                 auto& keys = generateObjUPtrPair(keyType, static_cast<int>(keyParam));
821                 BOOST_REQUIRE_NO_THROW(signature = keys.prv->sign(algo, message));
822                 if (keyType == AlgoType::RSA_GEN) {
823                         BOOST_REQUIRE(signature.size() * 8 == static_cast<size_t>(keyParam));
824                 } else {
825                         BOOST_REQUIRE(!signature.empty());
826                 }
827
828                 int ret = keys.pub->verify(algo, message, signature);
829                 BOOST_REQUIRE(CKM_API_SUCCESS == ret);
830         };
831
832         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
833         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA1, RSAPaddingAlgorithm::X931);
834         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA256, RSAPaddingAlgorithm::PKCS1);
835         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA384, RSAPaddingAlgorithm::PKCS1);
836         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA512, RSAPaddingAlgorithm::PKCS1);
837         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
838         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
839
840         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA1);
841         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA256);
842         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA384);
843         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA512);
844         signVerify(AlgoType::DSA_GEN, 2048, HashAlgorithm::SHA1);
845         signVerify(AlgoType::DSA_GEN, 3072, HashAlgorithm::SHA1);
846         signVerify(AlgoType::DSA_GEN, 4096, HashAlgorithm::SHA1);
847
848         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA1);
849         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA256);
850         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA384);
851         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA512);
852         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime256v1, HashAlgorithm::SHA1);
853         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::secp384r1, HashAlgorithm::SHA1);
854
855         // no hash + no padding
856         message[0] = 0; // make sure it's smaller than the modulus
857         message.resize(4096/8);
858         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::NONE);
859         message.resize(2048/8);
860         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::NONE);
861         message.resize(1024/8);
862         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE);
863
864         // no hash + padding
865         message.resize(512/8);
866         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
867         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
868         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
869         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
870 }
871
872 NEGATIVE_TEST_CASE(sign)
873 {
874         auto keysRsa = generateEvpPair(AlgoType::RSA_GEN, 1024);
875         auto keysDsa = generateEvpPair(AlgoType::DSA_GEN, 1024);
876         auto keysEcdsa = generateEvpPair(AlgoType::ECDSA_GEN,
877                                          static_cast<int>(ElipticCurve::prime192v1));
878
879         const auto longMsg = createRandom(1234);
880         auto equalMsg = longMsg;
881         equalMsg.resize(1024/8);
882         auto shortMsg = longMsg;
883         shortMsg.resize(1024/8 - 1); // padding requires 2/11 bytes
884         auto paddingMsg = longMsg;
885         paddingMsg.resize(1024/8 - 11);
886
887         CryptoAlgorithm signRsa;
888         signRsa.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
889         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
890         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::PKCS1);
891
892         CryptoAlgorithm signDsa;
893         signDsa.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_SV);
894         signDsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
895
896         CryptoAlgorithm signEcdsa;
897         signEcdsa.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_SV);
898         signEcdsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
899
900         // wrong key
901         BOOST_REQUIRE_THROW(Internals::sign(nullptr, signRsa, longMsg), Exc::Crypto::InternalError);
902         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.pub.get(), signRsa, longMsg),
903                             Exc::Crypto::InputParam);
904         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.pub.get(), signDsa, longMsg),
905                             Exc::Crypto::InputParam);
906         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.pub.get(), signEcdsa, longMsg),
907                             Exc::Crypto::InputParam);
908
909         // empty crypto
910         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.prv.get(), CryptoAlgorithm(), longMsg),
911                             Exc::Crypto::InputParam);
912         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.prv.get(), CryptoAlgorithm(), longMsg),
913                             Exc::Crypto::InputParam);
914         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.prv.get(), CryptoAlgorithm(), longMsg),
915                             Exc::Crypto::InputParam);
916
917         // wrong crypto
918         CryptoAlgorithm encrypt;
919         encrypt.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
920         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.prv.get(), encrypt, longMsg),
921                             Exc::Crypto::InputParam);
922         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.pub.get(), encrypt, longMsg),
923                             Exc::Crypto::InputParam);
924         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.prv.get(), encrypt, longMsg),
925                             Exc::Crypto::InputParam);
926         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.prv.get(), encrypt, longMsg),
927                             Exc::Crypto::InputParam);
928
929         // Obj API with wrong key type
930         AKey wrongKey(CryptoBackend::OpenSSL, createRandom(16), DataType::KEY_AES);
931         BOOST_REQUIRE_THROW(wrongKey.sign(signRsa, shortMsg), Exc::Crypto::InputParam);
932
933         auto invalidSign = [&](const RawBuffer& msg,
934                                AlgoType signAlgo,
935                                HashAlgorithm hash,
936                                RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
937         {
938                 EvpPtrPair keys;
939                 switch (signAlgo) {
940                 case AlgoType::RSA_SV:
941                         keys = keysRsa;
942                         break;
943                 case AlgoType::DSA_SV:
944                         keys = keysDsa;
945                         break;
946                 case AlgoType::ECDSA_SV:
947                         keys = keysEcdsa;
948                         break;
949                 default:
950                         BOOST_FAIL("Invalid algorithm. Fix the test.");
951                 }
952
953                 CryptoAlgorithm ca;
954                 ca.setParam(ParamName::ALGO_TYPE, signAlgo);
955                 ca.setParam(ParamName::SV_HASH_ALGO, hash);
956                 if (padding != RSAPaddingAlgorithm::NONE)
957                         ca.setParam(ParamName::SV_RSA_PADDING, padding);
958
959                 BOOST_REQUIRE_THROW(Internals::sign(keys.prv.get(), ca, msg), Exc::Crypto::InputParam);
960         };
961
962         HashAlgorithm wrongHash = static_cast<HashAlgorithm>(-1);
963
964         // out of range hash
965         invalidSign(paddingMsg, AlgoType::RSA_SV, wrongHash, RSAPaddingAlgorithm::PKCS1);
966         invalidSign(shortMsg, AlgoType::DSA_SV, wrongHash);
967         invalidSign(shortMsg, AlgoType::ECDSA_SV, wrongHash);
968
969         // out of range padding
970         invalidSign(shortMsg,
971                     AlgoType::RSA_SV,
972                     HashAlgorithm::SHA1,
973                     static_cast<RSAPaddingAlgorithm>(-1));
974
975         // no hash + padding + too long message
976         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
977         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
978         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
979         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
980
981         // no hash forbidden
982         invalidSign(shortMsg, AlgoType::DSA_SV, HashAlgorithm::NONE);
983         invalidSign(shortMsg, AlgoType::ECDSA_SV, HashAlgorithm::NONE);
984
985         // non-none hash + no padding forbidden
986         invalidSign(equalMsg, AlgoType::RSA_SV, HashAlgorithm::SHA256, RSAPaddingAlgorithm::NONE);
987
988         // no hash + no padding + invalid msg length
989         invalidSign(paddingMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
990         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
991         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
992
993         auto signature = Internals::sign(keysRsa.prv.get(), signRsa, longMsg);
994
995         BOOST_REQUIRE_THROW(Internals::verify(nullptr, signRsa, longMsg, signature),
996                             Exc::Crypto::InternalError);
997
998         // wrong crypto
999         BOOST_REQUIRE_THROW(Internals::verify(keysRsa.pub.get(), CryptoAlgorithm(), longMsg, signature),
1000                             Exc::Crypto::InputParam);
1001         BOOST_REQUIRE_THROW(Internals::verify(keysRsa.pub.get(), encrypt, longMsg, signature),
1002                             Exc::Crypto::InputParam);
1003
1004         CryptoAlgorithm verifyAlgo;
1005         verifyAlgo.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
1006         auto invalidVerify = [&](HashAlgorithm hash, RSAPaddingAlgorithm padding)
1007         {
1008                 verifyAlgo.setParam(ParamName::SV_HASH_ALGO, hash);
1009                 verifyAlgo.setParam(ParamName::SV_RSA_PADDING, padding);
1010
1011                 BOOST_REQUIRE_THROW(Internals::verify(keysRsa.prv.get(), verifyAlgo, longMsg, signature),
1012                                     Exc::Crypto::InputParam);
1013         };
1014
1015         // out of range hash
1016         invalidVerify(wrongHash, RSAPaddingAlgorithm::PKCS1);
1017
1018         // out of range padding
1019         invalidVerify(HashAlgorithm::SHA1, static_cast<RSAPaddingAlgorithm>(-1));
1020
1021         // non-none hash + no padding forbidden
1022         invalidVerify(HashAlgorithm::SHA1, RSAPaddingAlgorithm::NONE);
1023
1024         auto verificationFailed = [&](EVP_PKEY* key,
1025                                       const CryptoAlgorithm& algo,
1026                                       const RawBuffer& msg,
1027                                       const RawBuffer& sgn)
1028         {
1029                 int ret = Internals::verify(key, algo, msg, sgn);
1030                 BOOST_REQUIRE(ret == CKM_API_ERROR_VERIFICATION_FAILED);
1031         };
1032
1033         auto wrongSignature = signature;
1034         wrongSignature.pop_back();
1035         verificationFailed(keysDsa.pub.get(), signDsa, longMsg, signature);
1036         verificationFailed(keysEcdsa.pub.get(), signEcdsa, longMsg, signature);
1037         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, wrongSignature);
1038         verificationFailed(keysRsa.pub.get(), signRsa, equalMsg, signature);
1039
1040         // different padding
1041         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::X931);
1042         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1043         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::NONE);
1044         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::NONE);
1045         verificationFailed(keysRsa.pub.get(), signRsa, equalMsg, signature);
1046         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::PKCS1);
1047
1048         // different hash
1049         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA256);
1050         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1051         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA384);
1052         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1053         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA512);
1054         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1055 }
1056
1057 POSITIVE_TEST_CASE(importGetObjectDestroy)
1058 {
1059         const auto buffer = createRandom(16);
1060         Data data(DataType::BINARY_DATA, buffer);
1061         EncryptionParams ep;
1062         Token token;
1063         const auto digest = makeTestDigest();
1064
1065         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1066         BOOST_REQUIRE(token.backendId == CryptoBackend::OpenSSL);
1067         BOOST_REQUIRE(token.dataType == data.type);
1068         BOOST_REQUIRE(!token.data.empty());
1069
1070         GObjUPtr obj;
1071         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, "pass"));
1072         BOOST_REQUIRE(obj);
1073         BOOST_REQUIRE(obj->getBinary() == buffer);
1074
1075         BOOST_REQUIRE_NO_THROW(STORE.destroy(token));
1076 }
1077
1078 NEGATIVE_TEST_CASE(import)
1079 {
1080         Data data(DataType::BINARY_DATA, createRandom(16));
1081         EncryptionParams ep;
1082         ep.iv = createRandom(16);
1083         const auto digest = makeTestDigest();
1084
1085         BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep, digest), Exc::Crypto::OperationNotSupported);
1086 }
1087
1088 NEGATIVE_TEST_CASE(getObject)
1089 {
1090         Data data(DataType::BINARY_DATA, createRandom(16));
1091         EncryptionParams ep;
1092         Token token;
1093         const auto digest = makeTestDigest();
1094
1095         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1096
1097         BOOST_REQUIRE_THROW(STORE.getObject(token, "wrongpass"), Exc::Crypto::AuthenticationFailed);
1098
1099         token.backendId = CryptoBackend::TrustZone;
1100         BOOST_REQUIRE_THROW(STORE.getObject(token, "pass"), Exc::Crypto::WrongBackend);
1101 }
1102
1103 POSITIVE_TEST_CASE(certImportGetObject)
1104 {
1105         CertHelper cert(X509_CERT, DataType::CERTIFICATE);
1106         EvpShPtr evp, evp2;
1107         BOOST_REQUIRE_NO_THROW(evp = cert.getEvpShPtr());
1108         BOOST_REQUIRE(evp);
1109         BOOST_REQUIRE_NO_THROW(evp2 = cert.getEvpShPtr());
1110         BOOST_REQUIRE(evp2.get() == evp.get());
1111
1112         EncryptionParams ep;
1113         Data data(DataType::CERTIFICATE, cert.getBinary());
1114         Token token;
1115         const auto digest = makeTestDigest();
1116
1117         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep, digest));
1118         BOOST_REQUIRE(token.dataType == DataType::CERTIFICATE);
1119
1120         GObjUPtr obj;
1121         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
1122         BOOST_REQUIRE(obj);
1123 }
1124
1125 NEGATIVE_TEST_CASE(cert)
1126 {
1127         RawBuffer wrongX509 = X509_CERT;
1128         wrongX509.pop_back();
1129         CertHelper cert(wrongX509, DataType::CERTIFICATE);
1130
1131         BOOST_REQUIRE_THROW(cert.getEvpShPtr(), Exc::Crypto::InternalError);
1132 }
1133
1134 POSITIVE_TEST_CASE(deriveECDH)
1135 {
1136         CryptoAlgorithm gen;
1137         gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1138         gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1139
1140         auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1141         auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1142
1143         CryptoAlgorithm derive;
1144         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1145
1146         // our part
1147         GObjUPtr peersPublic;
1148         BOOST_REQUIRE_NO_THROW(peersPublic = STORE.getObject(peers.second, ""));
1149         derive.setParam(ParamName::ECDH_PUBKEY, peersPublic->getBinary());
1150
1151         GObjUPtr oursPrivate;
1152         BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1153
1154         Token oursDerived;
1155         BOOST_REQUIRE_NO_THROW(oursDerived = oursPrivate->derive(derive, "", RawBuffer()));
1156
1157         BOOST_REQUIRE(oursDerived.backendId == CryptoBackend::OpenSSL);
1158         BOOST_REQUIRE(oursDerived.dataType == DataType::BINARY_DATA);
1159
1160         GObjUPtr oursDerivedObj;
1161         BOOST_REQUIRE_NO_THROW(oursDerivedObj = STORE.getObject(oursDerived, ""));
1162         BOOST_REQUIRE(!oursDerivedObj->getBinary().empty());
1163
1164         // peer's part
1165         GObjUPtr oursPublic;
1166         BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1167         derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1168
1169         GObjUPtr peersPrivate;
1170         BOOST_REQUIRE_NO_THROW(peersPrivate = STORE.getObject(peers.first, ""));
1171
1172         Token peersDerived;
1173         BOOST_REQUIRE_NO_THROW(peersDerived = peersPrivate->derive(derive, "", RawBuffer()));
1174
1175         BOOST_REQUIRE(peersDerived.backendId == CryptoBackend::OpenSSL);
1176         BOOST_REQUIRE(peersDerived.dataType == DataType::BINARY_DATA);
1177
1178         GObjUPtr peersDerivedObj;
1179         BOOST_REQUIRE_NO_THROW(peersDerivedObj = STORE.getObject(peersDerived, ""));
1180         BOOST_REQUIRE(oursDerivedObj->getBinary() == peersDerivedObj->getBinary());
1181 }
1182
1183 NEGATIVE_TEST_CASE(deriveECDH)
1184 {
1185         CryptoAlgorithm gen;
1186         gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1187         gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1188
1189         auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1190         auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1191
1192         GObjUPtr oursPrivate;
1193         BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1194
1195         CryptoAlgorithm derive;
1196
1197         // no algorithm
1198         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1199
1200         // wrong algorithm
1201         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1202         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1203
1204         // no pubkey
1205         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1206         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1207
1208         // empty pubkey
1209         derive.setParam(ParamName::ECDH_PUBKEY, RawBuffer());
1210         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1211
1212         // private key instead of public
1213         derive.setParam(ParamName::ECDH_PUBKEY, oursPrivate->getBinary());
1214         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1215
1216         // public key instead of private key
1217         GObjUPtr oursPublic;
1218         BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1219         derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1220         BOOST_REQUIRE_THROW(oursPublic->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1221
1222         // RSA key instead of EC
1223         gen.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
1224         gen.setParam(ParamName::GEN_KEY_LEN, 1024);
1225         auto rsa = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1226         GObjUPtr rsaPrivate;
1227         BOOST_REQUIRE_NO_THROW(rsaPrivate = STORE.getObject(rsa.first, ""));
1228         BOOST_REQUIRE_THROW(rsaPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1229 }
1230
1231 POSITIVE_TEST_CASE(deriveKBKDFHMAC)
1232 {
1233         KbkdfParamTester test;
1234
1235         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1236
1237         test.Ok(16, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1238         test.Ok(24, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1239
1240         test.Ok(32, HMAC384, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1241         test.Ok(32, HMAC512, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1242
1243         test.Ok(32, HMAC256, COUNTER, AFTER,  CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1244         test.Ok(32, HMAC256, COUNTER, MIDDLE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1245
1246         test.Ok(32, HMAC256, COUNTER, BEFORE, ONE,   LAB,   NO_BUF, NO_SIZE, NO_SIZE);
1247         test.Ok(32, HMAC256, COUNTER, BEFORE, EMPTY, LAB,   NO_BUF, NO_SIZE, NO_SIZE);
1248         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX,   ONE,   NO_BUF, NO_SIZE, NO_SIZE);
1249         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX,   EMPTY, NO_BUF, NO_SIZE, NO_SIZE);
1250         test.Ok(32, HMAC256, COUNTER, BEFORE, EMPTY, EMPTY, NO_BUF, NO_SIZE, NO_SIZE);
1251
1252         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1253         test.Ok(32, HMAC256, COUNTER, AFTER,  NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1254
1255         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, ONE,   NO_SIZE, NO_SIZE);
1256         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, EMPTY, NO_SIZE, NO_SIZE);
1257
1258         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 32, NO_SIZE);
1259         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 24, NO_SIZE);
1260         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 16, NO_SIZE);
1261         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 8,  NO_SIZE);
1262
1263         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 32);
1264         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 24);
1265         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 16);
1266         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 8);
1267         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 0);
1268
1269         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE, true);
1270         test.Ok(32, HMAC256, COUNTER, MIDDLE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE, true);
1271 }
1272
1273 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongAlgo)
1274 {
1275         Token token;
1276         BOOST_REQUIRE_NO_THROW(token = STORE.import(Data(DataType::BINARY_DATA, RawBuffer(16)),
1277                                                     "",
1278                                                     EncryptionParams(),
1279                                                     RawBuffer()));
1280
1281         GObjUPtr secret;
1282         BOOST_REQUIRE_NO_THROW(secret = STORE.getObject(token, ""));
1283
1284         CryptoAlgorithm derive;
1285
1286         // no algorithm
1287         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1288
1289         // wrong algorithm
1290         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1291         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1292 }
1293
1294 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongParams)
1295 {
1296         KbkdfParamTester test;
1297
1298         // missing parameters
1299         test.Fail(NO_SIZE, HMAC256, COUNTER, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1300         test.Fail(32,      NO_PRF,  COUNTER, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1301         test.Fail(32,      HMAC256, NO_MODE, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1302         test.Fail(32,      HMAC256, COUNTER, NO_LOC, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1303         test.Fail(32,      HMAC256, COUNTER, BEFORE, NO_BUF, LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1304         test.Fail(32,      HMAC256, COUNTER, BEFORE, CTX,    NO_BUF, NO_BUF, NO_SIZE, NO_SIZE);
1305
1306         // conflicting parameters
1307         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX,    LAB,    FIX, NO_SIZE, NO_SIZE);
1308         test.Fail(32, HMAC256, COUNTER, BEFORE, NO_BUF, LAB,    FIX, NO_SIZE, NO_SIZE);
1309         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX,    NO_BUF, FIX, NO_SIZE, NO_SIZE);
1310         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1311         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, 32);
1312         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, 0);
1313         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE, true);
1314
1315         // invalid values
1316         test.Fail(0,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1317         test.Fail(1,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1318         test.Fail(8,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1319         test.Fail(64, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1320
1321         test.Fail(32, static_cast<KdfPrf>(0), COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1322         test.Fail(32, static_cast<KdfPrf>(4), COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1323
1324         test.Fail(32, HMAC256, static_cast<KbkdfMode>(0), BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1325         test.Fail(32, HMAC256, static_cast<KbkdfMode>(2), BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1326
1327         auto wrongLocation1 = static_cast<KbkdfCounterLocation>(0);
1328         auto wrongLocation2 = static_cast<KbkdfCounterLocation>(4);
1329         test.Fail(32, HMAC256, COUNTER, wrongLocation1, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1330         test.Fail(32, HMAC256, COUNTER, wrongLocation2, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1331
1332         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 0,  NO_SIZE);
1333         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 1,  NO_SIZE);
1334         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 7,  NO_SIZE);
1335         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 64, NO_SIZE);
1336
1337         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 1);
1338         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 7);
1339         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 64);
1340 }
1341
1342 BOOST_AUTO_TEST_SUITE_END()