2 * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 #include <unordered_map>
23 #include <boost_macros_wrapper.h>
24 #include <test_common.h>
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>
37 using namespace CKM::Crypto;
38 using namespace CKM::Crypto::SW;
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;
47 Store STORE(CryptoBackend::OpenSSL);
49 RawBuffer makeTestDigest()
51 auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID);
52 BOOST_REQUIRE(!digest.empty());
56 std::pair<RawBuffer, RawBuffer> makePubPrivTestDigest()
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));
64 void checkKey(const Token& token, KeyType keyType, const Password& pass)
66 DataType dataType(keyType);
67 BOOST_REQUIRE(token.dataType == dataType);
70 BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, pass));
73 RawBuffer data = obj->getBinary();
74 BOOST_REQUIRE(!data.empty());
77 if (dataType.isSKey())
78 key = CKM::Key::createAES(data);
80 key = CKM::Key::create(data);
83 BOOST_REQUIRE(!key->empty());
84 BOOST_REQUIRE(!key->getDER().empty());
85 BOOST_REQUIRE(key->getType() == keyType);
93 const GObjUPtrPair& generateObjUPtrPair(AlgoType algo, int param)
95 static std::unordered_map<AlgoType, std::unordered_map<int, GObjUPtrPair>> keyMap;
97 auto& algoMap = keyMap[algo];
98 auto it = algoMap.find(param);
99 if (it != algoMap.end())
103 gen.setParam(ParamName::ALGO_TYPE, algo);
104 if (algo == AlgoType::ECDSA_GEN)
105 gen.setParam(ParamName::GEN_EC, param);
107 gen.setParam(ParamName::GEN_KEY_LEN, param);
109 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
111 auto keyPair = STORE.generateAKey(gen, "", "", digestPriv, digestPub);
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;
126 EvpPtrPair generateEvpPair(AlgoType algo, int param)
128 class AKeyHelper : public AKey {
130 AKeyHelper(RawBuffer buffer, DataType dataType) :
131 AKey(CryptoBackend::OpenSSL, std::move(buffer), dataType)
135 static EvpPtrPair getEvps(const GObjUPtrPair& objPair, DataType prvType, DataType pubType)
137 AKeyHelper prv(objPair.prv->getBinary(), prvType);
138 AKeyHelper pub(objPair.pub->getBinary(), pubType);
139 return { prv.getEvpShPtr(), pub.getEvpShPtr() };
143 auto& objs = generateObjUPtrPair(algo, param);
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);
156 GObjUPtr generateAes(int len)
159 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
160 ca.setParam(ParamName::GEN_KEY_LEN, len);
164 const auto digest = makeTestDigest();
166 BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, "", digest));
169 BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
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
225 struct CertHelper : public Cert {
226 CertHelper(RawBuffer buffer, DataType dataType) :
227 Cert(CryptoBackend::OpenSSL, std::move(buffer), dataType) {}
229 using Cert::getEvpShPtr;
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;
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;
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;
252 class KbkdfParamTester {
256 BOOST_REQUIRE_NO_THROW(token = STORE.import(Data(DataType::BINARY_DATA, RawBuffer(16)),
261 BOOST_REQUIRE_NO_THROW(secret = STORE.getObject(token, ""));
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)
275 return Test(true, len, prf, mode, location, context, label, fixed, rlen, llen, noSeparator);
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)
290 false, len, prf, mode, location, context, label, fixed, rlen, llen, noSeparator);
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)
305 CryptoAlgorithm derive;
306 derive.setParam(ParamName::ALGO_TYPE, AlgoType::KBKDF);
308 derive.setParam(ParamName::KDF_LEN, *len);
310 derive.setParam(ParamName::KDF_PRF, *prf);
312 derive.setParam(ParamName::KBKDF_MODE, *mode);
314 derive.setParam(ParamName::KBKDF_COUNTER_LOCATION, *location);
316 derive.setParam(ParamName::KBKDF_CONTEXT, *context);
318 derive.setParam(ParamName::KBKDF_LABEL, *label);
320 derive.setParam(ParamName::KBKDF_FIXED_INPUT, *fixed);
322 derive.setParam(ParamName::KBKDF_RLEN, *rlen);
324 derive.setParam(ParamName::KBKDF_LLEN, *llen);
326 derive.setParam(ParamName::KBKDF_NO_SEPARATOR, 1);
331 BOOST_REQUIRE_NO_THROW(derived = secret->derive(derive, "", RawBuffer()));
333 BOOST_REQUIRE(derived.backendId == CryptoBackend::OpenSSL);
334 BOOST_REQUIRE(derived.dataType == DataType::KEY_AES);
336 BOOST_REQUIRE_NO_THROW(key = STORE.getObject(derived, ""));
338 BOOST_REQUIRE(key->getBinary().size() == *len);
340 BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
349 BOOST_AUTO_TEST_SUITE(SW_TEST)
351 POSITIVE_TEST_CASE(generateAKey)
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 } }
361 auto testAKey = [&](const Password& prvPass = "", const Password& pubPass = "")
364 ca.getParam(ParamName::ALGO_TYPE, algo);
365 auto& types = algo2types.at(algo);
369 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
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);
376 ca.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
377 ca.setParam(ParamName::GEN_KEY_LEN, 1024);
380 testAKey("", "pubpass");
381 testAKey("prvpass", "pubpass");
382 ca.setParam(ParamName::GEN_KEY_LEN, 2048);
384 ca.setParam(ParamName::GEN_KEY_LEN, 4096);
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);
393 ca.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
394 ca.setParam(ParamName::GEN_EC, ElipticCurve::prime192v1);
396 ca.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
398 ca.setParam(ParamName::GEN_EC, ElipticCurve::secp384r1);
402 NEGATIVE_TEST_CASE(generateAKey)
404 std::unique_ptr<CryptoAlgorithm> ca(new CryptoAlgorithm());
406 auto invalidGen = [&]
408 const auto [digestPub, digestPriv] = makePubPrivTestDigest();
409 BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", "", digestPriv, digestPub), Exc::Crypto::InputParam);
414 ca->setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
417 for (int keyLen : { 0, 512, 1023, 1025, 3072, 4097, 8192 }) {
418 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
422 ca->setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
424 for (int keyLen : { 0, 512, 1023, 1025, 4097, 8192 }) {
425 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
429 ca->setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
431 ca->setParam(ParamName::GEN_EC, static_cast<ElipticCurve>(-1));
433 ca->setParam(ParamName::GEN_EC, static_cast<ElipticCurve>(3));
436 ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
437 ca->setParam(ParamName::GEN_KEY_LEN, 128);
439 ca->setParam(ParamName::GEN_KEY_LEN, 1024);
443 ca.reset(new CryptoAlgorithm());
444 ca->setParam(ParamName::GEN_KEY_LEN, 1024);
445 ca->setParam(ParamName::GEN_EC, ElipticCurve::prime192v1);
447 ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
451 POSITIVE_TEST_CASE(generateSKey)
455 auto testSKey = [&](const Password& pass = "")
458 const auto digest = makeTestDigest();
459 BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass, digest));
460 checkKey(token, KeyType::KEY_AES, pass);
463 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
464 ca.setParam(ParamName::GEN_KEY_LEN, 128);
467 ca.setParam(ParamName::GEN_KEY_LEN, 192);
469 ca.setParam(ParamName::GEN_KEY_LEN, 256);
473 NEGATIVE_TEST_CASE(generateSKey)
475 std::unique_ptr<CryptoAlgorithm> ca(new CryptoAlgorithm());
477 auto invalidGen = [&]
479 const auto digest = makeTestDigest();
480 BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, "", digest), Exc::Crypto::InputParam);
485 ca->setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
488 for (int keyLen : { 0, 64, 127, 129, 257, 512 }) {
489 ca->setParam(ParamName::GEN_KEY_LEN, keyLen);
493 ca->setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
494 ca->setParam(ParamName::GEN_KEY_LEN, 128);
496 ca->setParam(ParamName::GEN_KEY_LEN, 1024);
499 ca.reset(new CryptoAlgorithm());
500 ca->setParam(ParamName::GEN_KEY_LEN, 128);
504 POSITIVE_TEST_CASE(symmetricEncryptDecrypt)
506 const GObjUPtr keys[] = { generateAes(128), generateAes(192), generateAes(256) };
507 const auto data = createRandom(128);
510 auto encryptDecrypt = [&]
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);
521 ca.setParam(ParamName::ED_IV, createRandom(Params::DEFAULT_AES_IV_LEN));
522 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
524 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
526 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CFB);
528 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
529 ca.setParam(ParamName::ED_AAD, createRandom(42));
533 NEGATIVE_TEST_CASE(symmetricEncryptDecrypt)
535 const auto key = generateAes(128);
536 const auto data = createRandom(128);
537 const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
541 BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
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);
550 for (auto algo : { AlgoType::AES_CTR, AlgoType::AES_CBC, AlgoType::AES_CFB }) {
552 ca2.setParam(ParamName::ALGO_TYPE, algo);
555 BOOST_REQUIRE_THROW(key->encrypt(ca2, data), Exc::Crypto::InputParam);
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);
563 SKey shortKey(CryptoBackend::OpenSSL, createRandom(128/8 - 1), DataType::KEY_AES);
564 BOOST_REQUIRE_THROW(shortKey.encrypt(ca2, data), Exc::Crypto::InternalError);
567 auto encrypted = key->encrypt(ca2, data);
572 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
573 ca3.setParam(ParamName::ALGO_TYPE, algo);
576 BOOST_REQUIRE_THROW(key->decrypt(ca3, encrypted), Exc::Crypto::InputParam);
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);
584 BOOST_REQUIRE_THROW(shortKey.decrypt(ca3, encrypted), Exc::Crypto::InternalError);
588 NEGATIVE_TEST_CASE(symmetricEncryptDecryptGcm)
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);
596 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
599 BOOST_REQUIRE_THROW(key->encrypt(ca, data), Exc::Crypto::InputParam);
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);
607 SKey shortKey(CryptoBackend::OpenSSL, createRandom(15), DataType::KEY_AES);
608 BOOST_REQUIRE_THROW(shortKey.encrypt(ca, data), Exc::Crypto::InternalError);
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);
615 ca.setParam(ParamName::ED_TAG_LEN, 128);
618 ca.setParam(ParamName::ED_AAD, aad);
619 auto encrypted = key->encrypt(ca, data);
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);
629 BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
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);
637 BOOST_REQUIRE_THROW(shortKey.decrypt(ca2, encrypted), Exc::Crypto::InternalError);
640 auto wrongBuffer = key->getBinary();
641 wrongBuffer[0] ^= 0x1;
642 SKey wrongKey(CryptoBackend::OpenSSL, std::move(wrongBuffer), DataType::KEY_AES);
644 BOOST_REQUIRE_THROW(wrongKey.decrypt(ca2, encrypted), Exc::Crypto::InputParam);
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);
654 auto wrongCiphertext = encrypted;
655 wrongCiphertext[0] ^= 0x1;
656 BOOST_REQUIRE_THROW(key->decrypt(ca2, wrongCiphertext), Exc::Crypto::InputParam);
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);
666 ca2.setParam(ParamName::ED_AAD, wrongAad);
667 BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
670 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCtr)
672 const auto key = generateAes(128);
673 const auto data = createRandom(128);
674 const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
677 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CTR);
678 ca.setParam(ParamName::ED_IV, iv);
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);
688 ca.setParam(ParamName::ED_CTR_LEN, 128);
689 auto encrypted = key->encrypt(ca, data);
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);
700 NEGATIVE_TEST_CASE(symmetricEncryptDecryptCbc)
702 const auto key = generateAes(128);
703 const auto data = createRandom(128);
704 const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
707 ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
708 ca.setParam(ParamName::ED_IV, iv);
710 auto encrypted = key->encrypt(ca, data);
713 encrypted.back() ^= 0x1;
715 auto decrypted = key->decrypt(ca, encrypted);
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.
723 BOOST_REQUIRE(decrypted.size() != data.size());
724 } catch (const Exc::Crypto::InputParam&) {
727 BOOST_FAIL("Exc::Crypto::InputParam expected");
731 POSITIVE_TEST_CASE(asymmetricEncryptDecrypt)
733 constexpr int KEY_BIT_LEN = 1024;
734 auto& rsaKeys = generateObjUPtrPair(AlgoType::RSA_GEN, KEY_BIT_LEN);
737 enc.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
742 auto encryptDecrypt = [&](const RawBuffer& input)
744 BOOST_REQUIRE_NO_THROW(encrypted = rsaKeys.pub->encrypt(enc, input));
745 BOOST_REQUIRE(encrypted.size() == KEY_BIT_LEN / 8);
747 BOOST_REQUIRE_NO_THROW(decrypted = rsaKeys.prv->decrypt(enc, encrypted));
748 BOOST_REQUIRE(decrypted == input);
751 encryptDecrypt(createRandom(KEY_BIT_LEN / 8 - 42));
752 encryptDecrypt(createRandom(KEY_BIT_LEN / 8 - 42 - 1));
753 encryptDecrypt(RawBuffer());
756 NEGATIVE_TEST_CASE(asymmetricEncryptDecrypt)
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);
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);
772 CryptoAlgorithm enc2;
773 enc2.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
774 BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc2, data), Exc::Crypto::InputParam);
776 CryptoAlgorithm enc3;
777 enc3.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
778 BOOST_REQUIRE_THROW(rsaKeys.pub->encrypt(enc3, data), Exc::Crypto::InputParam);
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);
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);
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);
800 BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc2, encrypted), Exc::Crypto::InputParam);
802 BOOST_REQUIRE_THROW(rsaKeys.prv->decrypt(enc3, encrypted), Exc::Crypto::InputParam);
805 POSITIVE_TEST_CASE(sign)
807 auto message = createRandom(1234);
810 auto signVerify = [&](AlgoType keyType,
813 RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
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);
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));
825 BOOST_REQUIRE(!signature.empty());
828 int ret = keys.pub->verify(algo, message, signature);
829 BOOST_REQUIRE(CKM_API_SUCCESS == ret);
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);
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);
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);
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);
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);
872 NEGATIVE_TEST_CASE(sign)
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));
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);
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);
892 CryptoAlgorithm signDsa;
893 signDsa.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_SV);
894 signDsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
896 CryptoAlgorithm signEcdsa;
897 signEcdsa.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_SV);
898 signEcdsa.setParam(ParamName::SV_HASH_ALGO, HashAlgorithm::SHA1);
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);
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);
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);
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);
933 auto invalidSign = [&](const RawBuffer& msg,
936 RSAPaddingAlgorithm padding = RSAPaddingAlgorithm::NONE)
940 case AlgoType::RSA_SV:
943 case AlgoType::DSA_SV:
946 case AlgoType::ECDSA_SV:
950 BOOST_FAIL("Invalid algorithm. Fix the test.");
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);
959 BOOST_REQUIRE_THROW(Internals::sign(keys.prv.get(), ca, msg), Exc::Crypto::InputParam);
962 HashAlgorithm wrongHash = static_cast<HashAlgorithm>(-1);
965 invalidSign(paddingMsg, AlgoType::RSA_SV, wrongHash, RSAPaddingAlgorithm::PKCS1);
966 invalidSign(shortMsg, AlgoType::DSA_SV, wrongHash);
967 invalidSign(shortMsg, AlgoType::ECDSA_SV, wrongHash);
969 // out of range padding
970 invalidSign(shortMsg,
973 static_cast<RSAPaddingAlgorithm>(-1));
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);
982 invalidSign(shortMsg, AlgoType::DSA_SV, HashAlgorithm::NONE);
983 invalidSign(shortMsg, AlgoType::ECDSA_SV, HashAlgorithm::NONE);
985 // non-none hash + no padding forbidden
986 invalidSign(equalMsg, AlgoType::RSA_SV, HashAlgorithm::SHA256, RSAPaddingAlgorithm::NONE);
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);
993 auto signature = Internals::sign(keysRsa.prv.get(), signRsa, longMsg);
995 BOOST_REQUIRE_THROW(Internals::verify(nullptr, signRsa, longMsg, signature),
996 Exc::Crypto::InternalError);
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);
1004 CryptoAlgorithm verifyAlgo;
1005 verifyAlgo.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_SV);
1006 auto invalidVerify = [&](HashAlgorithm hash, RSAPaddingAlgorithm padding)
1008 verifyAlgo.setParam(ParamName::SV_HASH_ALGO, hash);
1009 verifyAlgo.setParam(ParamName::SV_RSA_PADDING, padding);
1011 BOOST_REQUIRE_THROW(Internals::verify(keysRsa.prv.get(), verifyAlgo, longMsg, signature),
1012 Exc::Crypto::InputParam);
1015 // out of range hash
1016 invalidVerify(wrongHash, RSAPaddingAlgorithm::PKCS1);
1018 // out of range padding
1019 invalidVerify(HashAlgorithm::SHA1, static_cast<RSAPaddingAlgorithm>(-1));
1021 // non-none hash + no padding forbidden
1022 invalidVerify(HashAlgorithm::SHA1, RSAPaddingAlgorithm::NONE);
1024 auto verificationFailed = [&](EVP_PKEY* key,
1025 const CryptoAlgorithm& algo,
1026 const RawBuffer& msg,
1027 const RawBuffer& sgn)
1029 int ret = Internals::verify(key, algo, msg, sgn);
1030 BOOST_REQUIRE(ret == CKM_API_ERROR_VERIFICATION_FAILED);
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);
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);
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);
1057 POSITIVE_TEST_CASE(importGetObjectDestroy)
1059 const auto buffer = createRandom(16);
1060 Data data(DataType::BINARY_DATA, buffer);
1061 EncryptionParams ep;
1063 const auto digest = makeTestDigest();
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());
1071 BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, "pass"));
1073 BOOST_REQUIRE(obj->getBinary() == buffer);
1075 BOOST_REQUIRE_NO_THROW(STORE.destroy(token));
1078 NEGATIVE_TEST_CASE(import)
1080 Data data(DataType::BINARY_DATA, createRandom(16));
1081 EncryptionParams ep;
1082 ep.iv = createRandom(16);
1083 const auto digest = makeTestDigest();
1085 BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep, digest), Exc::Crypto::OperationNotSupported);
1088 NEGATIVE_TEST_CASE(getObject)
1090 Data data(DataType::BINARY_DATA, createRandom(16));
1091 EncryptionParams ep;
1093 const auto digest = makeTestDigest();
1095 BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
1097 BOOST_REQUIRE_THROW(STORE.getObject(token, "wrongpass"), Exc::Crypto::AuthenticationFailed);
1099 token.backendId = CryptoBackend::TrustZone;
1100 BOOST_REQUIRE_THROW(STORE.getObject(token, "pass"), Exc::Crypto::WrongBackend);
1103 POSITIVE_TEST_CASE(certImportGetObject)
1105 CertHelper cert(X509_CERT, DataType::CERTIFICATE);
1107 BOOST_REQUIRE_NO_THROW(evp = cert.getEvpShPtr());
1109 BOOST_REQUIRE_NO_THROW(evp2 = cert.getEvpShPtr());
1110 BOOST_REQUIRE(evp2.get() == evp.get());
1112 EncryptionParams ep;
1113 Data data(DataType::CERTIFICATE, cert.getBinary());
1115 const auto digest = makeTestDigest();
1117 BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep, digest));
1118 BOOST_REQUIRE(token.dataType == DataType::CERTIFICATE);
1121 BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
1125 NEGATIVE_TEST_CASE(cert)
1127 RawBuffer wrongX509 = X509_CERT;
1128 wrongX509.pop_back();
1129 CertHelper cert(wrongX509, DataType::CERTIFICATE);
1131 BOOST_REQUIRE_THROW(cert.getEvpShPtr(), Exc::Crypto::InternalError);
1134 POSITIVE_TEST_CASE(deriveECDH)
1136 CryptoAlgorithm gen;
1137 gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1138 gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1140 auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1141 auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1143 CryptoAlgorithm derive;
1144 derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1147 GObjUPtr peersPublic;
1148 BOOST_REQUIRE_NO_THROW(peersPublic = STORE.getObject(peers.second, ""));
1149 derive.setParam(ParamName::ECDH_PUBKEY, peersPublic->getBinary());
1151 GObjUPtr oursPrivate;
1152 BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1155 BOOST_REQUIRE_NO_THROW(oursDerived = oursPrivate->derive(derive, "", RawBuffer()));
1157 BOOST_REQUIRE(oursDerived.backendId == CryptoBackend::OpenSSL);
1158 BOOST_REQUIRE(oursDerived.dataType == DataType::BINARY_DATA);
1160 GObjUPtr oursDerivedObj;
1161 BOOST_REQUIRE_NO_THROW(oursDerivedObj = STORE.getObject(oursDerived, ""));
1162 BOOST_REQUIRE(!oursDerivedObj->getBinary().empty());
1165 GObjUPtr oursPublic;
1166 BOOST_REQUIRE_NO_THROW(oursPublic = STORE.getObject(ours.second, ""));
1167 derive.setParam(ParamName::ECDH_PUBKEY, oursPublic->getBinary());
1169 GObjUPtr peersPrivate;
1170 BOOST_REQUIRE_NO_THROW(peersPrivate = STORE.getObject(peers.first, ""));
1173 BOOST_REQUIRE_NO_THROW(peersDerived = peersPrivate->derive(derive, "", RawBuffer()));
1175 BOOST_REQUIRE(peersDerived.backendId == CryptoBackend::OpenSSL);
1176 BOOST_REQUIRE(peersDerived.dataType == DataType::BINARY_DATA);
1178 GObjUPtr peersDerivedObj;
1179 BOOST_REQUIRE_NO_THROW(peersDerivedObj = STORE.getObject(peersDerived, ""));
1180 BOOST_REQUIRE(oursDerivedObj->getBinary() == peersDerivedObj->getBinary());
1183 NEGATIVE_TEST_CASE(deriveECDH)
1185 CryptoAlgorithm gen;
1186 gen.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1187 gen.setParam(ParamName::GEN_EC, ElipticCurve::prime256v1);
1189 auto ours = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1190 auto peers = STORE.generateAKey(gen, "", "", RawBuffer(), RawBuffer());
1192 GObjUPtr oursPrivate;
1193 BOOST_REQUIRE_NO_THROW(oursPrivate = STORE.getObject(ours.first, ""));
1195 CryptoAlgorithm derive;
1198 BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1201 derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
1202 BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1205 derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1206 BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1209 derive.setParam(ParamName::ECDH_PUBKEY, RawBuffer());
1210 BOOST_REQUIRE_THROW(oursPrivate->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
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);
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);
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);
1231 POSITIVE_TEST_CASE(deriveKBKDFHMAC)
1233 KbkdfParamTester test;
1235 test.Ok(32, HMAC256, COUNTER, BEFORE, CTX, LAB, NO_BUF, NO_SIZE, NO_SIZE);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1273 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongAlgo)
1276 BOOST_REQUIRE_NO_THROW(token = STORE.import(Data(DataType::BINARY_DATA, RawBuffer(16)),
1282 BOOST_REQUIRE_NO_THROW(secret = STORE.getObject(token, ""));
1284 CryptoAlgorithm derive;
1287 BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1290 derive.setParam(ParamName::ALGO_TYPE, AlgoType::ECDH);
1291 BOOST_REQUIRE_THROW(secret->derive(derive, "", RawBuffer()), Exc::Crypto::InputParam);
1294 NEGATIVE_TEST_CASE(deriveKBKDFHMACwrongParams)
1296 KbkdfParamTester test;
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);
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);
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);
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);
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);
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);
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);
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);
1342 BOOST_AUTO_TEST_SUITE_END()