Test proper GCM IV length handling
[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[iv.size() - 1] ^= 0x1;
649         ca2.setParam(ParamName::ED_IV, wrongIv);
650         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
651
652         // shortened iv
653         auto shortenedIv = iv;
654         static_assert(Params::DEFAULT_AES_GCM_IV_LEN < Params::DEFAULT_AES_IV_LEN);
655         shortenedIv.resize(Params::DEFAULT_AES_GCM_IV_LEN);
656         ca2.setParam(ParamName::ED_IV, shortenedIv);
657         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
658
659         ca2.setParam(ParamName::ED_IV, iv);
660
661         // wrong ciphertext
662         auto wrongCiphertext = encrypted;
663         wrongCiphertext[0] ^= 0x1;
664         BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
665
666         // wrong tag (tag is appended to ciphertext)
667         wrongCiphertext = encrypted;
668         wrongCiphertext.back() ^= 0x1;
669         BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
670
671         // wrong aad
672         auto wrongAad = aad;
673         wrongAad[0] ^= 0x1;
674         ca2.setParam(ParamName::ED_AAD, wrongAad);
675         BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
676 }
677
678 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCtr)
679 {
680         const auto key = generateAes(128);
681         const auto data = createRandom(128);
682         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
683         CryptoAlgorithm ca;
684
685         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
686         ca.setParam(ParamName::ED_IV, iv);
687
688         // wrong ctr len
689         ca.setParam(ParamName::ED_CTR_LEN, 0);
690         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
691         ca.setParam(ParamName::ED_CTR_LEN, 127);
692         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
693         ca.setParam(ParamName::ED_CTR_LEN, 129);
694         BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
695
696         ca.setParam(ParamName::ED_CTR_LEN, 128);
697         auto encrypted = key->encrypt(ca, data);
698
699         // wrong ctr len
700         ca.setParam(ParamName::ED_CTR_LEN, 0);
701         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
702         ca.setParam(ParamName::ED_CTR_LEN, 127);
703         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
704         ca.setParam(ParamName::ED_CTR_LEN, 129);
705         BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
706 }
707
708 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCbc)
709 {
710         const auto key = generateAes(128);
711         const auto data = createRandom(128);
712         const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
713         CryptoAlgorithm ca;
714
715         ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
716         ca.setParam(ParamName::ED_IV, iv);
717
718         auto encrypted = key->encrypt(ca, data);
719
720         // broken padding
721         encrypted.back() ^= 0x1;
722         try {
723                 auto decrypted = key->decrypt(ca, encrypted);
724
725                 /*
726                  * There's a high chance that the above ^= 0x1 will produce a 0x01 trailing byte which
727                  * happens to be a valid padding. In such case make sure that the length of the
728                  * decrypted data is different.
729                  */
730
731                 BOOST_REQUIRE(decrypted.size() != data.size());
732         } catch (const Exc::Crypto::InputParam&) {
733                 // This is fine
734         } catch (...) {
735                 BOOST_FAIL("Exc::Crypto::InputParam expected");
736         }
737 }
738
739 POSITIVE_TEST_CASE(asymmetricEncryptDecrypt)
740 {
741         constexpr int KEY_BIT_LEN = 1024;
742         auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
743
744         CryptoAlgorithm enc;
745         enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
746
747         RawBuffer encrypted;
748         RawBuffer decrypted;
749
750         auto encryptDecrypt = [&](const RawBuffer& input)
751         {
752                 BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, input));
753                 BOOST_REQUIRE(encrypted.size() == KEY_BIT_LEN / 8);
754
755                 BOOST_REQUIRE_NO_THROW(decrypted = rsaKeys.prv->decrypt(enc, encrypted));
756                 BOOST_REQUIRE(decrypted == input);
757         };
758
759         encryptDecrypt(createRandom(KEY_BIT_LEN / 8 - 42));
760         encryptDecrypt(createRandom(KEY_BIT_LEN / 8 - 42 - 1));
761         encryptDecrypt(RawBuffer());
762 }
763
764 NEGATIVE_TEST_CASE(asymmetricEncryptDecrypt)
765 {
766         constexpr int KEY_BIT_LEN = 1024;
767         auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
768         auto& dsaKeys = generateObjUPtrPair(AlgoType::DSA_GEN, KEY_BIT_LEN);
769         const auto data = createRandom(KEY_BIT_LEN / 8 - 42);
770         auto longData = data;
771         longData.push_back(0);
772
773         CryptoAlgorithm enc;
774         enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
775         BOOST_REQUIRE_THROW(Internals::asymmetricEncrypt(EvpShPtr(), enc, data),
776                             Exc::Crypto::InputParam);
777         BOOST_REQUIRE_THROW(dsaKeys.pub->encrypt(enc, data), Exc::Crypto::InputParam);
778         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc, longData), Exc::Crypto::InputParam);
779
780         CryptoAlgorithm enc2;
781         enc2.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
782         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc2, data), Exc::Crypto::InputParam);
783
784         CryptoAlgorithm enc3;
785         enc3.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
786         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc3, data), Exc::Crypto::InputParam);
787
788         CryptoAlgorithm enc4;
789         enc4.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
790         enc4.setParam(ParamName::ED_LABEL, RawBuffer(64));
791         BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc4, data), Exc::Crypto::InputParam);
792
793         RawBuffer encrypted;
794         BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, data));
795         RawBuffer shortEncrypted = encrypted;
796         shortEncrypted.pop_back();
797         RawBuffer longEncrypted = encrypted;
798         longEncrypted.push_back(0);
799
800         BOOST_REQUIRE_THROW(Internals::asymmetricDecrypt(EvpShPtr(), enc, encrypted),
801                             Exc::Crypto::InputParam);
802         BOOST_REQUIRE_THROW(rsaKeys.pub->decrypt(enc, encrypted), Exc::Crypto::InputParam);
803         BOOST_REQUIRE_THROW(dsaKeys.prv->decrypt(enc, encrypted), Exc::Crypto::InputParam);
804         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, RawBuffer()), Exc::Crypto::InputParam);
805         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, shortEncrypted), Exc::Crypto::InputParam);
806         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc, longEncrypted), Exc::Crypto::InputParam);
807
808         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc2, encrypted), Exc::Crypto::InputParam);
809
810         BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc3, encrypted), Exc::Crypto::InputParam);
811 }
812
813 POSITIVE_TEST_CASE(sign)
814 {
815         auto message = createRandom(1234);
816         RawBuffer signature;
817
818         auto signVerify = [&](AlgoType keyType,
819                               auto keyParam,
820                               HashAlgorithm hash,
821                               RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
822         {
823                 CryptoAlgorithm algo;
824                 algo.setParam(ParamName::SV_HASH_ALGO, hash);
825                 if (keyType == AlgoType::RSA_GEN)
826                         algo.setParam(ParamName::SV_RSA_PADDING, padding);
827
828                 auto& keys = generateObjUPtrPair(keyType, static_cast<int>(keyParam));
829                 BOOST_REQUIRE_NO_THROW(signature = keys.prv->sign(algo, message));
830                 if (keyType == AlgoType::RSA_GEN) {
831                         BOOST_REQUIRE(signature.size() * 8 == static_cast<size_t>(keyParam));
832                 } else {
833                         BOOST_REQUIRE(!signature.empty());
834                 }
835
836                 int ret = keys.pub->verify(algo, message, signature);
837                 BOOST_REQUIRE(CKM_API_SUCCESS == ret);
838         };
839
840         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
841         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA1, RSAPaddingAlgorithm::X931);
842         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA256, RSAPaddingAlgorithm::PKCS1);
843         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA384, RSAPaddingAlgorithm::PKCS1);
844         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::SHA512, RSAPaddingAlgorithm::PKCS1);
845         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
846         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::SHA1, RSAPaddingAlgorithm::PKCS1);
847
848         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA1);
849         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA256);
850         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA384);
851         signVerify(AlgoType::DSA_GEN, 1024, HashAlgorithm::SHA512);
852         signVerify(AlgoType::DSA_GEN, 2048, HashAlgorithm::SHA1);
853         signVerify(AlgoType::DSA_GEN, 3072, HashAlgorithm::SHA1);
854         signVerify(AlgoType::DSA_GEN, 4096, HashAlgorithm::SHA1);
855
856         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA1);
857         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA256);
858         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA384);
859         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime192v1, HashAlgorithm::SHA512);
860         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::prime256v1, HashAlgorithm::SHA1);
861         signVerify(AlgoType::ECDSA_GEN, ElipticCurve::secp384r1, HashAlgorithm::SHA1);
862
863         // no hash + no padding
864         message[0] = 0; // make sure it's smaller than the modulus
865         message.resize(4096/8);
866         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::NONE);
867         message.resize(2048/8);
868         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::NONE);
869         message.resize(1024/8);
870         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE);
871
872         // no hash + padding
873         message.resize(512/8);
874         signVerify(AlgoType::RSA_GEN, 4096, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
875         signVerify(AlgoType::RSA_GEN, 2048, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
876         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
877         signVerify(AlgoType::RSA_GEN, 1024, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
878 }
879
880 NEGATIVE_TEST_CASE(sign)
881 {
882         auto keysRsa = generateEvpPair(AlgoType::RSA_GEN, 1024);
883         auto keysDsa = generateEvpPair(AlgoType::DSA_GEN, 1024);
884         auto keysEcdsa = generateEvpPair(AlgoType::ECDSA_GEN,
885                                          static_cast<int>(ElipticCurve::prime192v1));
886
887         const auto longMsg = createRandom(1234);
888         auto equalMsg = longMsg;
889         equalMsg.resize(1024/8);
890         auto shortMsg = longMsg;
891         shortMsg.resize(1024/8 - 1); // padding requires 2/11 bytes
892         auto paddingMsg = longMsg;
893         paddingMsg.resize(1024/8 - 11);
894
895         CryptoAlgorithm signRsa;
896         signRsa.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
897         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
898         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::PKCS1);
899
900         CryptoAlgorithm signDsa;
901         signDsa.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_SV);
902         signDsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
903
904         CryptoAlgorithm signEcdsa;
905         signEcdsa.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_SV);
906         signEcdsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
907
908         // wrong key
909         BOOST_REQUIRE_THROW(Internals::sign(nullptr, signRsa, longMsg), Exc::Crypto::InternalError);
910         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.pub.get(), signRsa, longMsg),
911                             Exc::Crypto::InputParam);
912         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.pub.get(), signDsa, longMsg),
913                             Exc::Crypto::InputParam);
914         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.pub.get(), signEcdsa, longMsg),
915                             Exc::Crypto::InputParam);
916
917         // empty crypto
918         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.prv.get(), CryptoAlgorithm(), longMsg),
919                             Exc::Crypto::InputParam);
920         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.prv.get(), CryptoAlgorithm(), longMsg),
921                             Exc::Crypto::InputParam);
922         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.prv.get(), CryptoAlgorithm(), longMsg),
923                             Exc::Crypto::InputParam);
924
925         // wrong crypto
926         CryptoAlgorithm encrypt;
927         encrypt.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
928         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.prv.get(), encrypt, longMsg),
929                             Exc::Crypto::InputParam);
930         BOOST_REQUIRE_THROW(Internals::sign(keysRsa.pub.get(), encrypt, longMsg),
931                             Exc::Crypto::InputParam);
932         BOOST_REQUIRE_THROW(Internals::sign(keysDsa.prv.get(), encrypt, longMsg),
933                             Exc::Crypto::InputParam);
934         BOOST_REQUIRE_THROW(Internals::sign(keysEcdsa.prv.get(), encrypt, longMsg),
935                             Exc::Crypto::InputParam);
936
937         // Obj API with wrong key type
938         AKey wrongKey(CryptoBackend::OpenSSL, createRandom(16), DataType::KEY_AES);
939         BOOST_REQUIRE_THROW(wrongKey.sign(signRsa, shortMsg), Exc::Crypto::InputParam);
940
941         auto invalidSign = [&](const RawBuffer& msg,
942                                AlgoType signAlgo,
943                                HashAlgorithm hash,
944                                RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
945         {
946                 EvpPtrPair keys;
947                 switch (signAlgo) {
948                 case AlgoType::RSA_SV:
949                         keys = keysRsa;
950                         break;
951                 case AlgoType::DSA_SV:
952                         keys = keysDsa;
953                         break;
954                 case AlgoType::ECDSA_SV:
955                         keys = keysEcdsa;
956                         break;
957                 default:
958                         BOOST_FAIL("Invalid algorithm. Fix the test.");
959                 }
960
961                 CryptoAlgorithm ca;
962                 ca.setParam(ParamName::ALGO_TYPE, signAlgo);
963                 ca.setParam(ParamName::SV_HASH_ALGO, hash);
964                 if (padding != RSAPaddingAlgorithm::NONE)
965                         ca.setParam(ParamName::SV_RSA_PADDING, padding);
966
967                 BOOST_REQUIRE_THROW(Internals::sign(keys.prv.get(), ca, msg), Exc::Crypto::InputParam);
968         };
969
970         HashAlgorithm wrongHash = static_cast<HashAlgorithm>(-1);
971
972         // out of range hash
973         invalidSign(paddingMsg, AlgoType::RSA_SV, wrongHash, RSAPaddingAlgorithm::PKCS1);
974         invalidSign(shortMsg, AlgoType::DSA_SV, wrongHash);
975         invalidSign(shortMsg, AlgoType::ECDSA_SV, wrongHash);
976
977         // out of range padding
978         invalidSign(shortMsg,
979                     AlgoType::RSA_SV,
980                     HashAlgorithm::SHA1,
981                     static_cast<RSAPaddingAlgorithm>(-1));
982
983         // no hash + padding + too long message
984         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
985         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
986         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::PKCS1);
987         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::X931);
988
989         // no hash forbidden
990         invalidSign(shortMsg, AlgoType::DSA_SV, HashAlgorithm::NONE);
991         invalidSign(shortMsg, AlgoType::ECDSA_SV, HashAlgorithm::NONE);
992
993         // non-none hash + no padding forbidden
994         invalidSign(equalMsg, AlgoType::RSA_SV, HashAlgorithm::SHA256, RSAPaddingAlgorithm::NONE);
995
996         // no hash + no padding + invalid msg length
997         invalidSign(paddingMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
998         invalidSign(shortMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
999         invalidSign(longMsg, AlgoType::RSA_SV, HashAlgorithm::NONE, RSAPaddingAlgorithm::NONE);
1000
1001         auto signature = Internals::sign(keysRsa.prv.get(), signRsa, longMsg);
1002
1003         BOOST_REQUIRE_THROW(Internals::verify(nullptr, signRsa, longMsg, signature),
1004                             Exc::Crypto::InternalError);
1005
1006         // wrong crypto
1007         BOOST_REQUIRE_THROW(Internals::verify(keysRsa.pub.get(), CryptoAlgorithm(), longMsg, signature),
1008                             Exc::Crypto::InputParam);
1009         BOOST_REQUIRE_THROW(Internals::verify(keysRsa.pub.get(), encrypt, longMsg, signature),
1010                             Exc::Crypto::InputParam);
1011
1012         CryptoAlgorithm verifyAlgo;
1013         verifyAlgo.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
1014         auto invalidVerify = [&](HashAlgorithm hash, RSAPaddingAlgorithm padding)
1015         {
1016                 verifyAlgo.setParam(ParamName::SV_HASH_ALGO, hash);
1017                 verifyAlgo.setParam(ParamName::SV_RSA_PADDING, padding);
1018
1019                 BOOST_REQUIRE_THROW(Internals::verify(keysRsa.prv.get(), verifyAlgo, longMsg, signature),
1020                                     Exc::Crypto::InputParam);
1021         };
1022
1023         // out of range hash
1024         invalidVerify(wrongHash, RSAPaddingAlgorithm::PKCS1);
1025
1026         // out of range padding
1027         invalidVerify(HashAlgorithm::SHA1, static_cast<RSAPaddingAlgorithm>(-1));
1028
1029         // non-none hash + no padding forbidden
1030         invalidVerify(HashAlgorithm::SHA1, RSAPaddingAlgorithm::NONE);
1031
1032         auto verificationFailed = [&](EVP_PKEY* key,
1033                                       const CryptoAlgorithm& algo,
1034                                       const RawBuffer& msg,
1035                                       const RawBuffer& sgn)
1036         {
1037                 int ret = Internals::verify(key, algo, msg, sgn);
1038                 BOOST_REQUIRE(ret == CKM_API_ERROR_VERIFICATION_FAILED);
1039         };
1040
1041         auto wrongSignature = signature;
1042         wrongSignature.pop_back();
1043         verificationFailed(keysDsa.pub.get(), signDsa, longMsg, signature);
1044         verificationFailed(keysEcdsa.pub.get(), signEcdsa, longMsg, signature);
1045         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, wrongSignature);
1046         verificationFailed(keysRsa.pub.get(), signRsa, equalMsg, signature);
1047
1048         // different padding
1049         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::X931);
1050         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1051         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::NONE);
1052         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::NONE);
1053         verificationFailed(keysRsa.pub.get(), signRsa, equalMsg, signature);
1054         signRsa.setParam(ParamName::SV_RSA_PADDING, RSAPaddingAlgorithm::PKCS1);
1055
1056         // different hash
1057         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA256);
1058         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1059         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA384);
1060         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1061         signRsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA512);
1062         verificationFailed(keysRsa.pub.get(), signRsa, longMsg, signature);
1063 }
1064
1065 POSITIVE_TEST_CASE(importGetObjectDestroy)
1066 {
1067         const auto buffer = createRandom(16);
1068         Data data(DataType::BINARY_DATA, buffer);
1069         EncryptionParams ep;
1070         Token token;
1071         const auto digest = makeTestDigest();
1072
1073         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1074         BOOST_REQUIRE(token.backendId == CryptoBackend::OpenSSL);
1075         BOOST_REQUIRE(token.dataType == data.type);
1076         BOOST_REQUIRE(!token.data.empty());
1077
1078         GObjUPtr obj;
1079         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, "pass"));
1080         BOOST_REQUIRE(obj);
1081         BOOST_REQUIRE(obj->getBinary() == buffer);
1082
1083         BOOST_REQUIRE_NO_THROW(STORE.destroy(token));
1084 }
1085
1086 NEGATIVE_TEST_CASE(import)
1087 {
1088         Data data(DataType::BINARY_DATA, createRandom(16));
1089         EncryptionParams ep;
1090         ep.iv = createRandom(16);
1091         const auto digest = makeTestDigest();
1092
1093         BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep, digest), Exc::Crypto::OperationNotSupported);
1094 }
1095
1096 NEGATIVE_TEST_CASE(getObject)
1097 {
1098         Data data(DataType::BINARY_DATA, createRandom(16));
1099         EncryptionParams ep;
1100         Token token;
1101         const auto digest = makeTestDigest();
1102
1103         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1104
1105         BOOST_REQUIRE_THROW(STORE.getObject(token, "wrongpass"), Exc::Crypto::AuthenticationFailed);
1106
1107         token.backendId = CryptoBackend::TrustZone;
1108         BOOST_REQUIRE_THROW(STORE.getObject(token, "pass"), Exc::Crypto::WrongBackend);
1109 }
1110
1111 POSITIVE_TEST_CASE(certImportGetObject)
1112 {
1113         CertHelper cert(X509_CERT, DataType::CERTIFICATE);
1114         EvpShPtr evp, evp2;
1115         BOOST_REQUIRE_NO_THROW(evp = cert.getEvpShPtr());
1116         BOOST_REQUIRE(evp);
1117         BOOST_REQUIRE_NO_THROW(evp2 = cert.getEvpShPtr());
1118         BOOST_REQUIRE(evp2.get() == evp.get());
1119
1120         EncryptionParams ep;
1121         Data data(DataType::CERTIFICATE, cert.getBinary());
1122         Token token;
1123         const auto digest = makeTestDigest();
1124
1125         BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep, digest));
1126         BOOST_REQUIRE(token.dataType == DataType::CERTIFICATE);
1127
1128         GObjUPtr obj;
1129         BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
1130         BOOST_REQUIRE(obj);
1131 }
1132
1133 NEGATIVE_TEST_CASE(cert)
1134 {
1135         RawBuffer wrongX509 = X509_CERT;
1136         wrongX509.pop_back();
1137         CertHelper cert(wrongX509, DataType::CERTIFICATE);
1138
1139         BOOST_REQUIRE_THROW(cert.getEvpShPtr(), Exc::Crypto::InternalError);
1140 }
1141
1142 POSITIVE_TEST_CASE(deriveECDH)
1143 {
1144         CryptoAlgorithm gen;
1145         gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1146         gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1147
1148         auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1149         auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1150
1151         CryptoAlgorithm derive;
1152         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1153
1154         // our part
1155         GObjUPtr peersPublic;
1156         BOOST_REQUIRE_NO_THROW(peersPublic = STORE.getObject(peers.second, ""));
1157         derive.setParam(ParamName::ECDH_PUBKEY, peersPublic->getBinary());
1158
1159         GObjUPtr oursPrivate;
1160         BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1161
1162         Token oursDerived;
1163         BOOST_REQUIRE_NO_THROW(oursDerived = oursPrivate->derive(derive, "", RawBuffer()));
1164
1165         BOOST_REQUIRE(oursDerived.backendId == CryptoBackend::OpenSSL);
1166         BOOST_REQUIRE(oursDerived.dataType == DataType::BINARY_DATA);
1167
1168         GObjUPtr oursDerivedObj;
1169         BOOST_REQUIRE_NO_THROW(oursDerivedObj = STORE.getObject(oursDerived, ""));
1170         BOOST_REQUIRE(!oursDerivedObj->getBinary().empty());
1171
1172         // peer's part
1173         GObjUPtr oursPublic;
1174         BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1175         derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1176
1177         GObjUPtr peersPrivate;
1178         BOOST_REQUIRE_NO_THROW(peersPrivate = STORE.getObject(peers.first, ""));
1179
1180         Token peersDerived;
1181         BOOST_REQUIRE_NO_THROW(peersDerived = peersPrivate->derive(derive, "", RawBuffer()));
1182
1183         BOOST_REQUIRE(peersDerived.backendId == CryptoBackend::OpenSSL);
1184         BOOST_REQUIRE(peersDerived.dataType == DataType::BINARY_DATA);
1185
1186         GObjUPtr peersDerivedObj;
1187         BOOST_REQUIRE_NO_THROW(peersDerivedObj = STORE.getObject(peersDerived, ""));
1188         BOOST_REQUIRE(oursDerivedObj->getBinary() == peersDerivedObj->getBinary());
1189 }
1190
1191 NEGATIVE_TEST_CASE(deriveECDH)
1192 {
1193         CryptoAlgorithm gen;
1194         gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1195         gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1196
1197         auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1198         auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1199
1200         GObjUPtr oursPrivate;
1201         BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1202
1203         CryptoAlgorithm derive;
1204
1205         // no algorithm
1206         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1207
1208         // wrong algorithm
1209         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1210         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1211
1212         // no pubkey
1213         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1214         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1215
1216         // empty pubkey
1217         derive.setParam(ParamName::ECDH_PUBKEY, RawBuffer());
1218         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1219
1220         // private key instead of public
1221         derive.setParam(ParamName::ECDH_PUBKEY, oursPrivate->getBinary());
1222         BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1223
1224         // public key instead of private key
1225         GObjUPtr oursPublic;
1226         BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1227         derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1228         BOOST_REQUIRE_THROW(oursPublic->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1229
1230         // RSA key instead of EC
1231         gen.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
1232         gen.setParam(ParamName::GEN_KEY_LEN, 1024);
1233         auto rsa = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1234         GObjUPtr rsaPrivate;
1235         BOOST_REQUIRE_NO_THROW(rsaPrivate = STORE.getObject(rsa.first, ""));
1236         BOOST_REQUIRE_THROW(rsaPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1237 }
1238
1239 POSITIVE_TEST_CASE(deriveKBKDFHMAC)
1240 {
1241         KbkdfParamTester test;
1242
1243         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1244
1245         test.Ok(16, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1246         test.Ok(24, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1247
1248         test.Ok(32, HMAC384, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1249         test.Ok(32, HMAC512, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1250
1251         test.Ok(32, HMAC256, COUNTER, AFTER,  CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1252         test.Ok(32, HMAC256, COUNTER, MIDDLE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1253
1254         test.Ok(32, HMAC256, COUNTER, BEFORE, ONE,   LAB,   NO_BUF, NO_SIZE, NO_SIZE);
1255         test.Ok(32, HMAC256, COUNTER, BEFORE, EMPTY, LAB,   NO_BUF, NO_SIZE, NO_SIZE);
1256         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX,   ONE,   NO_BUF, NO_SIZE, NO_SIZE);
1257         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX,   EMPTY, NO_BUF, NO_SIZE, NO_SIZE);
1258         test.Ok(32, HMAC256, COUNTER, BEFORE, EMPTY, EMPTY, NO_BUF, NO_SIZE, NO_SIZE);
1259
1260         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1261         test.Ok(32, HMAC256, COUNTER, AFTER,  NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1262
1263         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, ONE,   NO_SIZE, NO_SIZE);
1264         test.Ok(32, HMAC256, COUNTER, BEFORE, NO_BUF, NO_BUF, EMPTY, NO_SIZE, NO_SIZE);
1265
1266         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 32, NO_SIZE);
1267         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 24, NO_SIZE);
1268         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 16, NO_SIZE);
1269         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 8,  NO_SIZE);
1270
1271         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 32);
1272         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 24);
1273         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 16);
1274         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 8);
1275         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 0);
1276
1277         test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE, true);
1278         test.Ok(32, HMAC256, COUNTER, MIDDLE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE, true);
1279 }
1280
1281 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongAlgo)
1282 {
1283         Token token;
1284         BOOST_REQUIRE_NO_THROW(token = STORE.import(Data(DataType::BINARY_DATA, RawBuffer(16)),
1285                                                     "",
1286                                                     EncryptionParams(),
1287                                                     RawBuffer()));
1288
1289         GObjUPtr secret;
1290         BOOST_REQUIRE_NO_THROW(secret = STORE.getObject(token, ""));
1291
1292         CryptoAlgorithm derive;
1293
1294         // no algorithm
1295         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1296
1297         // wrong algorithm
1298         derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1299         BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1300 }
1301
1302 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongParams)
1303 {
1304         KbkdfParamTester test;
1305
1306         // missing parameters
1307         test.Fail(NO_SIZE, HMAC256, COUNTER, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1308         test.Fail(32,      NO_PRF,  COUNTER, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1309         test.Fail(32,      HMAC256, NO_MODE, BEFORE, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1310         test.Fail(32,      HMAC256, COUNTER, NO_LOC, CTX,    LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1311         test.Fail(32,      HMAC256, COUNTER, BEFORE, NO_BUF, LAB,    NO_BUF, NO_SIZE, NO_SIZE);
1312         test.Fail(32,      HMAC256, COUNTER, BEFORE, CTX,    NO_BUF, NO_BUF, NO_SIZE, NO_SIZE);
1313
1314         // conflicting parameters
1315         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX,    LAB,    FIX, NO_SIZE, NO_SIZE);
1316         test.Fail(32, HMAC256, COUNTER, BEFORE, NO_BUF, LAB,    FIX, NO_SIZE, NO_SIZE);
1317         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX,    NO_BUF, FIX, NO_SIZE, NO_SIZE);
1318         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE);
1319         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, 32);
1320         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, 0);
1321         test.Fail(32, HMAC256, COUNTER, MIDDLE, NO_BUF, NO_BUF, FIX, NO_SIZE, NO_SIZE, true);
1322
1323         // invalid values
1324         test.Fail(0,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1325         test.Fail(1,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1326         test.Fail(8,  HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1327         test.Fail(64, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1328
1329         test.Fail(32, static_cast<KdfPrf>(0), COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1330         test.Fail(32, static_cast<KdfPrf>(4), COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1331
1332         test.Fail(32, HMAC256, static_cast<KbkdfMode>(0), BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1333         test.Fail(32, HMAC256, static_cast<KbkdfMode>(2), BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1334
1335         auto wrongLocation1 = static_cast<KbkdfCounterLocation>(0);
1336         auto wrongLocation2 = static_cast<KbkdfCounterLocation>(4);
1337         test.Fail(32, HMAC256, COUNTER, wrongLocation1, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1338         test.Fail(32, HMAC256, COUNTER, wrongLocation2, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
1339
1340         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 0,  NO_SIZE);
1341         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 1,  NO_SIZE);
1342         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 7,  NO_SIZE);
1343         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, 64, NO_SIZE);
1344
1345         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 1);
1346         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 7);
1347         test.Fail(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, 64);
1348 }
1349
1350 BOOST_AUTO_TEST_SUITE_END()