Implement hash selection in RSA OAEP
[platform/core/security/key-manager.git] / src / manager / crypto / sw-backend / internals.cpp
1 /*
2  *  Copyright (c) 2015-2020 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  * @file       internals.cpp
18  * @author
19  * @version    1.0
20  */
21 #include <exception>
22 #include <utility>
23 #include <algorithm>
24 #include <cassert>
25
26 #include <openssl/evp.h>
27 #include <openssl/obj_mac.h>
28 #include <openssl/ec.h>
29 #include <openssl/dsa.h>
30 #include <openssl/rsa.h>
31 #include <openssl/bio.h>
32 #include <openssl/rand.h>
33 #include <openssl/crypto.h>
34 #include <openssl/err.h>
35 #include <openssl/x509v3.h>
36 #include <openssl/obj_mac.h>
37 #include <openssl/kdf.h>
38
39 #include <ckm/ckm-error.h>
40 #include <key-impl.h>
41 #include <dpl/log/log.h>
42 #include <utils.h>
43
44 #include <generic-backend/exception.h>
45 #include <generic-backend/algo-validation.h>
46 #include <generic-backend/crypto-params.h>
47 #include <sw-backend/internals.h>
48 #include <openssl-error-handler.h>
49 #include "kbkdf.h"
50
51 #define OPENSSL_SUCCESS 1       // DO NOT CHANGE THIS VALUE
52 #define OPENSSL_FAIL    0       // DO NOT CHANGE THIS VALUE
53
54 namespace CKM {
55 namespace Crypto {
56 namespace SW {
57 namespace Internals {
58
59 namespace {
60 typedef Uptr<EVP_PKEY_CTX_free, EVP_PKEY_CTX> EvpPkeyCtxUPtr;
61
62 typedef int(*I2D_CONV)(BIO *, EVP_PKEY *);
63
64
65 RawBuffer i2d(I2D_CONV fun, EVP_PKEY *pkey)
66 {
67         auto bio = uptr<BIO_free_all>(BIO_new(BIO_s_mem()));
68
69         if (NULL == pkey)
70                 ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
71
72         if (NULL == bio.get())
73                 ThrowErr(Exc::Crypto::InternalError,
74                                  "Error in memory allocation! Function: BIO_new.");
75
76         if (1 != fun(bio.get(), pkey))
77                 ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
78
79         RawBuffer output(8196);
80
81         int size = BIO_read(bio.get(), output.data(), output.size());
82
83         if (size <= 0)
84                 ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
85
86         output.resize(size);
87         return output;
88 }
89
90 // encryption / decryption
91 typedef ParamCheck<ParamName::ALGO_TYPE,
92                 AlgoType,
93                 true,
94                 Type<AlgoType>::Equals<AlgoType::AES_CTR,
95                 AlgoType::AES_CBC,
96                 AlgoType::AES_GCM,
97                 AlgoType::AES_CFB>> IsSymEncryption;
98
99 typedef ParamCheck<ParamName::ALGO_TYPE,
100                 AlgoType,
101                 true,
102                 Type<AlgoType>::Equals<AlgoType::RSA_OAEP>> IsAsymEncryption;
103
104 typedef ParamCheck<ParamName::ED_IV,
105                 RawBuffer,
106                 true,
107                 Type<size_t>::Equals<Params::DEFAULT_AES_IV_LEN>,
108                 BufferSizeGetter> IvSizeCheck;
109
110 typedef ParamCheck<ParamName::ED_CTR_LEN,
111                 int,
112                 false,
113                 Type<int>::Equals<128>> CtrLenCheck;
114
115 typedef ParamCheck<ParamName::ED_IV,
116                 RawBuffer,
117                 true,
118                 DefaultValidator<RawBuffer>> GcmIvCheck;
119
120 typedef ParamCheck<ParamName::ED_TAG_LEN,
121                 int,
122                 false,
123                 Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck;
124
125 typedef ParamCheck<ParamName::ED_LABEL,
126                 RawBuffer,
127                 false,
128                 Unsupported<RawBuffer>> RsaLabelCheck;
129
130 // sign / verify
131 typedef ParamCheck<ParamName::ALGO_TYPE,
132                 AlgoType,
133                 false,
134                 Type<AlgoType>::Equals<AlgoType::RSA_SV,
135                 AlgoType::DSA_SV,
136                 AlgoType::ECDSA_SV>> IsSignVerify;
137
138 typedef ParamCheck<ParamName::SV_HASH_ALGO,
139                 HashAlgorithm,
140                 false,
141                 Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
142                 HashAlgorithm::SHA1,
143                 HashAlgorithm::SHA256,
144                 HashAlgorithm::SHA384,
145                 HashAlgorithm::SHA512>> HashAlgoCheck;
146
147 typedef ParamCheck<ParamName::SV_RSA_PADDING,
148                 RSAPaddingAlgorithm,
149                 false,
150                 Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
151                 RSAPaddingAlgorithm::PKCS1,
152                 RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
153
154 // key generation
155 typedef ParamCheck<ParamName::ALGO_TYPE,
156                 AlgoType,
157                 true,
158                 Type<AlgoType>::Equals<AlgoType::RSA_GEN,
159                 AlgoType::DSA_GEN,
160                 AlgoType::ECDSA_GEN>> IsAsymGeneration;
161
162 typedef ParamCheck<ParamName::ALGO_TYPE,
163                 AlgoType,
164                 true,
165                 Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
166
167 typedef ParamCheck<ParamName::GEN_KEY_LEN,
168                 int,
169                 true,
170                 Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
171
172 typedef ParamCheck<ParamName::GEN_KEY_LEN,
173                 int,
174                 true,
175                 Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
176
177 typedef ParamCheck<ParamName::GEN_KEY_LEN,
178                 int,
179                 true,
180                 Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
181
182 typedef ParamCheck<ParamName::GEN_EC,
183                 ElipticCurve,
184                 true,
185                 Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
186                 ElipticCurve::prime256v1,
187                 ElipticCurve::secp384r1>> EcdsaEcCheck;
188
189 // key derivation
190 typedef ParamCheck<ParamName::ALGO_TYPE,
191                 AlgoType,
192                 true,
193                 Type<AlgoType>::Equals<AlgoType::ECDH>> IsEcdh;
194
195 typedef ParamCheck<ParamName::ECDH_PUBKEY,
196                 RawBuffer,
197                 true,
198                 DefaultValidator<RawBuffer>> EcdhPubKeyCheck;
199
200 typedef ParamCheck<ParamName::ALGO_TYPE,
201                 AlgoType,
202                 true,
203                 Type<AlgoType>::Equals<AlgoType::KBKDF>> IsKbkdf;
204
205 typedef ParamCheck<ParamName::KDF_PRF,
206                 KdfPrf,
207                 true,
208                 Type<KdfPrf>::Equals<KdfPrf::HMAC_SHA256,
209                                                          KdfPrf::HMAC_SHA384,
210                                                          KdfPrf::HMAC_SHA512>> KdfPrfCheck;
211
212 typedef ParamCheck<ParamName::KBKDF_MODE,
213                 KbkdfMode,
214                 true,
215                 Type<KbkdfMode>::Equals<KbkdfMode::COUNTER>> KbkdfModeCheck;
216
217 typedef ParamCheck<ParamName::KDF_LEN,
218                 int,
219                 true,
220                 Type<int>::Equals<16, 24, 32>> KdfLenCheck;
221
222 typedef ParamCheck<ParamName::KBKDF_COUNTER_LOCATION,
223                 KbkdfCounterLocation,
224                 true,
225                 Type<KbkdfCounterLocation>::Equals<KbkdfCounterLocation::BEFORE_FIXED,
226                                                                                    KbkdfCounterLocation::AFTER_FIXED,
227                                                                                    KbkdfCounterLocation::MIDDLE_FIXED>> KbkdfCounterLocationCheck;
228
229 typedef ParamCheck<ParamName::KBKDF_RLEN,
230                 int,
231                 false,
232                 Type<int>::Equals<8, 16, 24, 32>> KbkdfRlenCheck;
233
234 typedef ParamCheck<ParamName::KBKDF_LLEN,
235                 int,
236                 false,
237                 Type<int>::Equals<0, 8, 16, 24, 32>> KbkdfLlenCheck;
238
239 typedef ParamCheck<ParamName::ED_OAEP_HASH,
240                 HashAlgorithm,
241                 false,
242                 Type<HashAlgorithm>::Equals<HashAlgorithm::SHA1, HashAlgorithm::SHA256>> OaepHashAlgoCheck;
243
244 typedef std::map<AlgoType, ValidatorVector> ValidatorMap;
245 ValidatorMap initValidators()
246 {
247         ValidatorMap validators;
248         validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
249         validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build());
250         validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build());
251         validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build());
252         validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build());
253         validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build());
254         validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build());
255         validators.emplace(AlgoType::AES_CTR, VBuilder<IvSizeCheck, CtrLenCheck>::Build());
256         validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build());
257         validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build());
258         validators.emplace(AlgoType::AES_GCM, VBuilder<GcmIvCheck, GcmTagCheck>::Build());
259         validators.emplace(AlgoType::RSA_OAEP, VBuilder<RsaLabelCheck, OaepHashAlgoCheck>::Build());
260         validators.emplace(AlgoType::ECDH, VBuilder<EcdhPubKeyCheck>::Build());
261         validators.emplace(AlgoType::KBKDF, VBuilder<KdfPrfCheck,
262                                                                                                  KbkdfModeCheck,
263                                                                                                  KdfLenCheck,
264                                                                                                  KbkdfCounterLocationCheck,
265                                                                                                  KbkdfRlenCheck,
266                                                                                                  KbkdfLlenCheck>::Build());
267         return validators;
268 };
269
270 const ValidatorMap g_validators = initValidators();
271
272 template <typename TypeCheck>
273 void validateParams(const CryptoAlgorithm &ca)
274 {
275         // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
276         TypeCheck tc;
277         tc.Check(ca);
278
279         AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
280
281         auto it = g_validators.find(at);
282
283         // TypeCheck should prevent it
284         assert(it != g_validators.end());
285
286         for (const auto &validator : it->second)
287                 validator->Check(ca);
288 }
289
290 typedef std::function<void(EvpCipherPtr &, const RawBuffer &key, const RawBuffer &iv)>
291 InitCipherFn;
292
293 // aes mode, key length in bits, encryption
294 typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>>
295 CipherTree;
296
297 template <typename T>
298 void initCipher(EvpCipherPtr &ptr, const RawBuffer &key, const RawBuffer &iv)
299 {
300         ptr.reset(new T(key, iv));
301 }
302
303 CipherTree initializeCipherTree()
304 {
305         CipherTree tree;
306         tree[AlgoType::AES_CBC][128][true] = initCipher<Cipher::AesCbcEncryption128>;
307         tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>;
308         tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>;
309
310         tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>;
311         tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>;
312         tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>;
313
314         tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>;
315         tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>;
316         tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>;
317
318         tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>;
319         tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>;
320         tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>;
321
322         tree[AlgoType::AES_CTR][128][true] = initCipher<Cipher::AesCtrEncryption128>;
323         tree[AlgoType::AES_CTR][192][true] = initCipher<Cipher::AesCtrEncryption192>;
324         tree[AlgoType::AES_CTR][256][true] = initCipher<Cipher::AesCtrEncryption256>;
325
326         tree[AlgoType::AES_CTR][128][false] = initCipher<Cipher::AesCtrDecryption128>;
327         tree[AlgoType::AES_CTR][192][false] = initCipher<Cipher::AesCtrDecryption192>;
328         tree[AlgoType::AES_CTR][256][false] = initCipher<Cipher::AesCtrDecryption256>;
329
330         tree[AlgoType::AES_CFB][128][true] = initCipher<Cipher::AesCfbEncryption128>;
331         tree[AlgoType::AES_CFB][192][true] = initCipher<Cipher::AesCfbEncryption192>;
332         tree[AlgoType::AES_CFB][256][true] = initCipher<Cipher::AesCfbEncryption256>;
333
334         tree[AlgoType::AES_CFB][128][false] = initCipher<Cipher::AesCfbDecryption128>;
335         tree[AlgoType::AES_CFB][192][false] = initCipher<Cipher::AesCfbDecryption192>;
336         tree[AlgoType::AES_CFB][256][false] = initCipher<Cipher::AesCfbDecryption256>;
337
338         return tree;
339 }
340
341 CipherTree g_cipherTree = initializeCipherTree();
342
343 // key length in bytes
344 InitCipherFn selectCipher(AlgoType type, size_t key_len = 32,
345                                                   bool encryption = true)
346 {
347         try {
348                 return g_cipherTree.at(type).at(key_len * 8).at(encryption);
349         } catch (const std::out_of_range &) {
350                 ThrowErr(Exc::Crypto::InternalError,
351                                  "Unsupported cipher: ",
352                                  static_cast<int>(type), ", ",
353                                  key_len, ", ",
354                                  encryption);
355         }
356 }
357
358 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo)
359 {
360         switch (hashAlgo) {
361         default:
362                 // validateParams<IsSignVerify> should prevent it
363                 assert(hashAlgo == HashAlgorithm::NONE);
364                 return NULL;
365
366         case HashAlgorithm::SHA1:
367                 return EVP_sha1();
368
369         case HashAlgorithm::SHA256:
370                 return EVP_sha256();
371
372         case HashAlgorithm::SHA384:
373                 return EVP_sha384();
374
375         case HashAlgorithm::SHA512:
376                 return EVP_sha512();
377         }
378 }
379
380 int getRsaPadding(const RSAPaddingAlgorithm padAlgo)
381 {
382         switch (padAlgo) {
383         default:
384                 // validateParams<IsSignVerify> should prevent it
385                 assert(padAlgo == RSAPaddingAlgorithm::NONE);
386                 return RSA_NO_PADDING;
387
388         case RSAPaddingAlgorithm::PKCS1:
389                 return RSA_PKCS1_PADDING;
390
391         case RSAPaddingAlgorithm::X931:
392                 return RSA_X931_PADDING;
393         }
394 }
395
396 EvpPkeyCtxUPtr newCtx(int id)
397 {
398         if (auto ctx = EVP_PKEY_CTX_new_id(id, NULL))
399                 return EvpPkeyCtxUPtr(ctx);
400
401         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
402 }
403
404 EvpPkeyCtxUPtr newCtx(EVP_PKEY *pkey)
405 {
406         if (auto ctx = EVP_PKEY_CTX_new(pkey, NULL))
407                 return EvpPkeyCtxUPtr(ctx);
408
409         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
410 }
411
412 RawBuffer asymmetricHelper(
413         int (*initFn)(EVP_PKEY_CTX *),
414         int (*cryptFn)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t),
415         const EvpShPtr &pkey,
416         const CryptoAlgorithm &alg,
417         const RawBuffer &data)
418 {
419         int ret;
420         size_t outlen;
421
422         validateParams<IsAsymEncryption>(alg);
423
424         HashAlgorithm hash = HashAlgorithm::SHA1;
425         alg.getParam(ParamName::ED_OAEP_HASH, hash);
426
427         if (!pkey)
428                 ThrowErr(Exc::Crypto::InputParam, "no key");
429
430         if (EVP_PKEY_base_id(pkey.get()) != EVP_PKEY_RSA)
431                 ThrowErr(Exc::Crypto::InputParam, "Wrong key type");
432
433         auto ctx = newCtx(pkey.get());
434
435         ret = (*initFn)(ctx.get());
436         if (ret <= 0)
437                 errorHandle(__FILE__, __LINE__, __func__, ret);
438
439         if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING) <= 0)
440                 ThrowErr(Exc::Crypto::InternalError, "EVP_PKEY_CTX_set_rsa_padding failed");
441
442         if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), getMdAlgo(hash)) <= 0)
443                 ThrowErr(Exc::Crypto::InternalError, "EVP_PKEY_CTX_set_rsa_oaep_md failed");
444
445         // TODO set label with EVP_PKEY_CTX_set0_rsa_oaep_label
446
447         ret = (*cryptFn)(ctx.get(), NULL, &outlen, data.data(), data.size());
448         if (ret <= 0)
449                 errorHandle(__FILE__, __LINE__, __func__, ret);
450
451         RawBuffer output(outlen);
452
453         ret = (*cryptFn)(ctx.get(), output.data(), &outlen, data.data(), data.size());
454         if (ret <= 0)
455                 errorHandle(__FILE__, __LINE__, __func__, ret);
456
457         output.resize(outlen);
458         return output;
459 }
460
461 DataPair keyPair(const EvpPkeyCtxUPtr &ctx, KeyType prv, KeyType pub)
462 {
463         EVP_PKEY *pkeyTmp = NULL;
464
465         OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(ctx.get(), &pkeyTmp));
466
467         auto pkey = uptr<EVP_PKEY_free>(pkeyTmp);
468
469         return std::make_pair<Data, Data>(
470                         {DataType(prv), i2d(i2d_PrivateKey_bio, pkey.get())},
471                         {DataType(pub), i2d(i2d_PUBKEY_bio, pkey.get())});
472 }
473
474 DataPair createKeyPairRSA(const int size)
475 {
476         // validateParams<IsAsymGeneration> should prevent it
477         assert(size == 1024 || size == 2048 || size == 4096);
478
479         auto ctx = newCtx(EVP_PKEY_RSA);
480
481         OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(ctx.get()));
482
483         OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size));
484
485         return keyPair(ctx, KeyType::KEY_RSA_PRIVATE, KeyType::KEY_RSA_PUBLIC);
486 }
487
488 DataPair paramgenKeyPair(const EvpPkeyCtxUPtr &pctx, KeyType prv, KeyType pub)
489 {
490         /* Generate parameters */
491         EVP_PKEY *pparamTmp = NULL;
492         OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp));
493
494         auto pparam = uptr<EVP_PKEY_free>(pparamTmp);
495
496         // Start to generate key
497         auto kctx = newCtx(pparam.get());
498
499         OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get()));
500
501         return keyPair(kctx, prv, pub);
502 }
503
504 DataPair createKeyPairDSA(const int size)
505 {
506         // validateParams<IsAsymGeneration> should prevent it
507         assert(size == 1024 || size == 2048 || size == 3072 || size == 4096);
508
509         /* Create the context for generating the parameters */
510         auto pctx = newCtx(EVP_PKEY_DSA);
511
512         OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
513
514         OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size));
515
516         return paramgenKeyPair(pctx, KeyType::KEY_DSA_PRIVATE, KeyType::KEY_DSA_PUBLIC);
517 }
518
519 DataPair createKeyPairECDSA(ElipticCurve type)
520 {
521         int ecCurve;
522
523         switch (type) {
524         default:
525                 // validateParams<IsAsymGeneration> should prevent it
526                 assert(type == ElipticCurve::prime192v1);
527                 ecCurve = NID_X9_62_prime192v1;
528                 break;
529
530         case ElipticCurve::prime256v1:
531                 ecCurve = NID_X9_62_prime256v1;
532                 break;
533
534         case ElipticCurve::secp384r1:
535                 ecCurve = NID_secp384r1;
536                 break;
537         }
538
539         /* Create the context for generating the parameters */
540         auto pctx = newCtx(EVP_PKEY_EC);
541
542         OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
543
544         OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve));
545
546         return paramgenKeyPair(pctx, KeyType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PUBLIC);
547 }
548
549 Data createKeyAES(const int sizeBits)
550 {
551         // validateParams<IsSymGeneration> should prevent it
552         assert(sizeBits == 128 || sizeBits == 192 || sizeBits == 256);
553
554         uint8_t key[32];
555         int sizeBytes = sizeBits / 8;
556
557         if (!RAND_bytes(key, sizeBytes)) {
558                 ThrowErr(Exc::Crypto::InternalError, "Error in AES key generation");
559         }
560
561         return { DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key + sizeBytes)};
562 }
563
564 RawBuffer signMessage(EVP_PKEY *privKey,
565                                           const RawBuffer &message,
566                                           const int rsa_padding)
567 {
568         if (EVP_PKEY_type(EVP_PKEY_id(privKey)) != EVP_PKEY_RSA)
569                 ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
570
571         auto pctx = newCtx(privKey);
572
573         OPENSSL_ERROR_HANDLE(EVP_PKEY_sign_init(pctx.get()));
574
575         /* Set padding algorithm */
576         if (EVP_PKEY_type(EVP_PKEY_id(privKey)) == EVP_PKEY_RSA)
577                 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
578
579         /* Finalize the Sign operation */
580         /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
581          * signature. Length is returned in slen */
582         size_t slen;
583
584         OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size()));
585
586         /* Allocate memory for the signature based on size in slen */
587         RawBuffer sig(slen);
588
589         OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), sig.data(), &slen, message.data(), message.size()));
590
591         // Set value to return RawData
592         sig.resize(slen);
593         return sig;
594 }
595
596 RawBuffer digestSignMessage(EVP_PKEY *privKey,
597                                                         const RawBuffer &message,
598                                                         const EVP_MD *md_algo,
599                                                         const int rsa_padding)
600 {
601         EVP_PKEY_CTX *pctx = NULL;
602
603         // Create the Message Digest Context
604         auto mdctx = uptr<EVP_MD_CTX_free>(EVP_MD_CTX_new());
605         if (!mdctx.get())
606                 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_new function");
607
608         OPENSSL_ERROR_HANDLE(EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey));
609
610         /* Set padding algorithm */
611         if (EVP_PKEY_type(EVP_PKEY_id(privKey)) == EVP_PKEY_RSA)
612                 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
613
614         /* Call update with the message */
615         OPENSSL_ERROR_HANDLE(EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size()));
616
617         /* Finalize the DigestSign operation */
618         /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
619          * signature. Length is returned in slen */
620         size_t slen;
621
622         OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), NULL, &slen));
623
624         /* Allocate memory for the signature based on size in slen */
625         RawBuffer sig(slen);
626
627         /* Obtain the signature */
628         OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen));
629
630         // Set value to return RawData
631         sig.resize(slen);
632         return sig;
633 }
634
635 int verifyMessage(EVP_PKEY *pubKey,
636                                   const RawBuffer &message,
637                                   const RawBuffer &signature,
638                                   const int rsa_padding)
639 {
640         if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) != EVP_PKEY_RSA)
641                 ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
642
643         auto pctx = newCtx(pubKey);
644
645         OPENSSL_ERROR_HANDLE(EVP_PKEY_verify_init(pctx.get()));
646
647         /* Set padding algorithm */
648         if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) == EVP_PKEY_RSA)
649                 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
650
651         if (OPENSSL_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
652                                                                            signature.size(), message.data(), message.size()))
653                 return CKM_API_SUCCESS;
654
655         LogError("EVP_PKEY_verify Failed");
656         return CKM_API_ERROR_VERIFICATION_FAILED;
657 }
658
659 int digestVerifyMessage(EVP_PKEY *pubKey,
660                                                 const RawBuffer &message,
661                                                 const RawBuffer &signature,
662                                                 const EVP_MD *md_algo,
663                                                 const int rsa_padding)
664 {
665         EVP_PKEY_CTX *pctx = NULL;
666
667         // Create the Message Digest Context
668         auto mdctx = uptr<EVP_MD_CTX_free>(EVP_MD_CTX_new());
669         if (!mdctx.get())
670                 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_new function");
671
672         OPENSSL_ERROR_HANDLE(EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey));
673
674         if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) == EVP_PKEY_RSA)
675                 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
676
677         OPENSSL_ERROR_HANDLE(EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()));
678
679         if (OPENSSL_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(),
680                         const_cast<unsigned char *>(signature.data()), signature.size()))
681                 return CKM_API_SUCCESS;
682
683         LogError("EVP_PKEY_verify Failed");
684         return CKM_API_ERROR_VERIFICATION_FAILED;
685 }
686
687 RawBuffer encryptDataAesGcmPacked(
688         const RawBuffer &key,
689         const RawBuffer &data,
690         const RawBuffer &iv,
691         int tagSize,
692         const RawBuffer &aad)
693 {
694         auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad);
695         std::copy(pair.second.begin(), pair.second.end(),
696                           std::back_inserter(pair.first));
697         return pair.first;
698 }
699
700
701 RawBuffer decryptDataAesGcmPacked(
702         const RawBuffer &key,
703         const RawBuffer &data,
704         const RawBuffer &iv,
705         int tagSize,
706         const RawBuffer &aad)
707 {
708         if (tagSize > static_cast<int>(data.size()))
709                 ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
710
711         auto tagPos = data.data() + data.size() - tagSize;
712         return decryptDataAesGcm(
713                            key,
714                            RawBuffer(data.data(), tagPos),
715                            iv,
716                            RawBuffer(tagPos, data.data() + data.size()),
717                            aad);
718 }
719
720 EC_KEY* getEcKey(EVP_PKEY* evpKey)
721 {
722         int subType = EVP_PKEY_type(EVP_PKEY_id(evpKey));
723         if (subType != EVP_PKEY_EC)
724                 ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType);
725
726         EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(evpKey);
727         if (!ecKey)
728                 ThrowErr(Exc::Crypto::InternalError, "Can't get EC key");
729
730         return ecKey;
731 }
732
733 int getCurve(const EC_KEY* ecKey)
734 {
735         return EC_GROUP_get_curve_name(EC_KEY_get0_group(ecKey));
736 }
737
738 } // namespace
739
740
741 DataPair generateAKey(const CryptoAlgorithm &algorithm)
742 {
743         validateParams<IsAsymGeneration>(algorithm);
744
745         AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
746
747         if (keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN) {
748                 int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
749
750                 if (keyType == AlgoType::RSA_GEN)
751                         return createKeyPairRSA(keyLength);
752                 else
753                         return createKeyPairDSA(keyLength);
754         } else { // AlgoType::ECDSA_GEN
755                 ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
756                 return createKeyPairECDSA(ecType);
757         }
758 }
759
760 Data generateSKey(const CryptoAlgorithm &algorithm)
761 {
762         validateParams<IsSymGeneration>(algorithm);
763
764         int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
765         return createKeyAES(keySizeBits);
766 }
767
768 RawBuffer encryptDataAes(
769         AlgoType type,
770         const RawBuffer &key,
771         const RawBuffer &data,
772         const RawBuffer &iv)
773 {
774         EvpCipherPtr enc;
775         selectCipher(type, key.size())(enc, key, iv);
776         RawBuffer result = enc->Append(data);
777         RawBuffer tmp = enc->Finalize();
778         std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
779         return result;
780 }
781
782 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
783         const RawBuffer &key,
784         const RawBuffer &data,
785         const RawBuffer &iv,
786         int tagSize,
787         const RawBuffer &aad)
788 {
789         RawBuffer tag(tagSize);
790         EvpCipherPtr enc;
791         selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv);
792
793         if (!aad.empty())
794                 enc->AppendAAD(aad);
795
796         RawBuffer result = enc->Append(data);
797         RawBuffer tmp = enc->Finalize();
798         std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
799
800         enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data());
801
802         return std::make_pair(result, tag);
803 }
804
805 RawBuffer decryptDataAes(
806         AlgoType type,
807         const RawBuffer &key,
808         const RawBuffer &data,
809         const RawBuffer &iv)
810 {
811         EvpCipherPtr dec;
812         selectCipher(type, key.size(), false)(dec, key, iv);
813         RawBuffer result = dec->Append(data);
814         RawBuffer tmp;
815         try {
816                 tmp = dec->Finalize();
817         } catch (const Exc::Exception &e) {
818                 ThrowErr(Exc::InputParam, "Authentication failed in AES finalize function (wrong key/data was used).");
819         }
820         std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
821         return result;
822 }
823
824 RawBuffer decryptDataAesGcm(
825         const RawBuffer &key,
826         const RawBuffer &data,
827         const RawBuffer &iv,
828         const RawBuffer &tag,
829         const RawBuffer &aad)
830 {
831         EvpCipherPtr dec;
832         selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
833         void *ptr = (void *)tag.data();
834
835         dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr);
836
837         if (!aad.empty())
838                 dec->AppendAAD(aad);
839
840         RawBuffer result = dec->Append(data);
841         RawBuffer tmp;
842         try {
843                 tmp = dec->Finalize();
844         } catch (const Exc::Exception &e) {
845                 ThrowErr(Exc::InputParam, "Tag authentication failed in AES finalize function (the tag doesn't match).");
846         }
847         std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
848         return result;
849 }
850
851 RawBuffer symmetricEncrypt(const RawBuffer &key,
852                                                    const CryptoAlgorithm &alg,
853                                                    const RawBuffer &data)
854 {
855         validateParams<IsSymEncryption>(alg);
856         AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
857
858         if (algo == AlgoType::AES_GCM) {
859                 int tagLenBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
860                 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
861                 RawBuffer aad;
862                 alg.getParam(ParamName::ED_AAD, aad);
863                 return encryptDataAesGcmPacked(key,
864                                                                            data,
865                                                                            unpack<RawBuffer>(alg, ParamName::ED_IV),
866                                                                            tagLenBits / 8,
867                                                                            aad);
868         }
869         // validateParams<IsSymEncryption> should prevent it
870         assert(algo == AlgoType::AES_CBC || algo == AlgoType::AES_CTR || algo == AlgoType::AES_CFB);
871         return encryptDataAes(algo, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
872 }
873
874 RawBuffer symmetricDecrypt(const RawBuffer &key,
875                                                    const CryptoAlgorithm &alg,
876                                                    const RawBuffer &data)
877 {
878         validateParams<IsSymEncryption>(alg);
879         AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
880
881         if (algo == AlgoType::AES_GCM) {
882                 int tagLenBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
883                 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
884                 RawBuffer aad;
885                 alg.getParam(ParamName::ED_AAD, aad);
886                 return decryptDataAesGcmPacked(key,
887                                                                            data,
888                                                                            unpack<RawBuffer>(alg, ParamName::ED_IV),
889                                                                            tagLenBits / 8,
890                                                                            aad);
891         }
892         // validateParams<IsSymEncryption> should prevent it
893         assert(algo == AlgoType::AES_CBC || algo == AlgoType::AES_CTR || algo == AlgoType::AES_CFB);
894         return decryptDataAes(algo, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
895 }
896
897 EvpCipherPtr initCipher(const RawBuffer &key, const CryptoAlgorithm &alg, bool encrypt, int& tagLen)
898 {
899         validateParams<IsSymEncryption>(alg);
900         AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
901         auto iv = unpack<RawBuffer>(alg, ParamName::ED_IV);
902         tagLen = 0;
903
904         EvpCipherPtr cipher;
905         selectCipher(algo, key.size(), encrypt)(cipher, key, iv);
906
907         if (algo == AlgoType::AES_GCM) {
908                 int tagLenBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
909                 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
910                 tagLen = tagLenBits / 8;
911
912                 RawBuffer aad;
913                 alg.getParam(ParamName::ED_AAD, aad);
914                 if (!aad.empty())
915                         cipher->AppendAAD(aad);
916         }
917         return cipher;
918 }
919
920 RawBuffer asymmetricEncrypt(const EvpShPtr &pkey,
921                                                         const CryptoAlgorithm &alg,
922                                                         const RawBuffer &data)
923 {
924         return asymmetricHelper(EVP_PKEY_encrypt_init, EVP_PKEY_encrypt, pkey, alg, data);
925 }
926
927 RawBuffer asymmetricDecrypt(const EvpShPtr &pkey,
928                                                         const CryptoAlgorithm &alg,
929                                                         const RawBuffer &data)
930 {
931         return asymmetricHelper(EVP_PKEY_decrypt_init, EVP_PKEY_decrypt, pkey, alg, data);
932 }
933
934 RawBuffer sign(EVP_PKEY *pkey,
935                            const CryptoAlgorithm &alg,
936                            const RawBuffer &message)
937 {
938         validateParams<IsSignVerify>(alg);
939
940         HashAlgorithm hashTmp = HashAlgorithm::NONE;
941         alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
942         const EVP_MD *md_algo = getMdAlgo(hashTmp);
943
944         RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
945         alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
946         int rsa_padding = getRsaPadding(rsaPad);
947
948         //
949         //    if ((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
950         //       (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
951         //       (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
952         //    {
953         //        LogError("Error in private key type");
954         //        ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
955         //    }
956         //
957         //    if (privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
958         //        rsa_padding = getRsaPadding(padAlgo);
959         //    }
960
961         if (NULL == pkey)
962                 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
963
964         if (md_algo == NULL)
965                 return signMessage(pkey, message, rsa_padding);
966
967         return digestSignMessage(pkey, message, md_algo, rsa_padding);
968 }
969
970 int verify(EVP_PKEY *pkey,
971                    const CryptoAlgorithm &alg,
972                    const RawBuffer &message,
973                    const RawBuffer &signature)
974 {
975         validateParams<IsSignVerify>(alg);
976
977         HashAlgorithm hashTmp = HashAlgorithm::NONE;
978         alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
979         const EVP_MD *md_algo = getMdAlgo(hashTmp);
980
981         RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
982         alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
983         int rsa_padding = getRsaPadding(rsaPad);
984
985         //
986         //    if ((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
987         //       (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
988         //       (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
989         //    {
990         //        LogError("Error in private key type");
991         //        ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
992         //    }
993         //
994         //    if (publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
995         //        rsa_padding = getRsaPadding(padAlgo);
996         //    }
997
998         //    auto shrPKey = publicKey.getEvpShPtr();
999         if (NULL == pkey)
1000                 ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
1001
1002         if (md_algo == NULL)
1003                 return verifyMessage(pkey, message, signature, rsa_padding);
1004
1005         return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
1006 }
1007
1008 Data deriveECDH(const EvpShPtr &pkey, const CryptoAlgorithm &alg)
1009 {
1010         validateParams<IsEcdh>(alg);
1011
1012         EC_KEY *ecKey = getEcKey(pkey.get());
1013
1014         // get private key curve name
1015         int prvCurve = getCurve(ecKey);
1016
1017         auto prv = EC_KEY_get0_private_key(ecKey);
1018         if (!prv)
1019                 ThrowErr(Exc::Crypto::InputParam, "ECDH requires own private EC key");
1020
1021         // Create the context for the shared secret derivation
1022         auto ctx = newCtx(pkey.get());
1023         if (ctx == nullptr)
1024                 ThrowErr(Exc::Crypto::InternalError, "Key context creation failed");
1025
1026         // import peer's public key from buffer
1027         RawBuffer pubKeyBuffer;
1028         [[maybe_unused]] bool hasPubKey = alg.getParam(ParamName::ECDH_PUBKEY, pubKeyBuffer);
1029         assert(hasPubKey);
1030         auto peerKey = std::make_shared<KeyImpl>(pubKeyBuffer);
1031         if (peerKey->getType() != KeyType::KEY_ECDSA_PUBLIC)
1032                 ThrowErr(Exc::Crypto::InputParam, "ECDH requires peer's public EC key");
1033         auto peerEvp = peerKey->getEvpShPtr().get();
1034         assert(peerEvp);
1035
1036         int pubCurve = getCurve(getEcKey(peerEvp));
1037
1038         if (pubCurve != prvCurve)
1039                 ThrowErr(Exc::Crypto::InputParam, "Private and public key use different ECs");
1040
1041         // initialise
1042         if (1 != EVP_PKEY_derive_init(ctx.get()))
1043                 ThrowErr(Exc::Crypto::InternalError, "EVP_PKEY_derive_init failed");
1044
1045         // provide the peer public key
1046         if (1 != EVP_PKEY_derive_set_peer(ctx.get(), peerEvp))
1047                 ThrowErr(Exc::Crypto::InternalError, "EVP_PKEY_derive_set_peer failed");
1048
1049         // determine buffer length for shared secret
1050         size_t secretLen;
1051         if(1 != EVP_PKEY_derive(ctx.get(), nullptr, &secretLen))
1052                 ThrowErr(Exc::Crypto::InternalError, "Failed to determine ECDH secret length");
1053
1054         RawBuffer secret(secretLen);
1055
1056         // derive the shared secret
1057         if (1 != (EVP_PKEY_derive(ctx.get(), secret.data(), &secretLen)))
1058                 ThrowErr(Exc::Crypto::InternalError, "ECDH failed");
1059
1060         // Never use a derived secret directly. Typically it is passed
1061         // through some hash function to produce a key
1062         return { DataType::BINARY_DATA, std::move(secret)};
1063 }
1064
1065 Data deriveKBKDF(const RawBuffer &secret, const CryptoAlgorithm &alg)
1066 {
1067         validateParams<IsKbkdf>(alg);
1068
1069         RawBuffer label, context, fixed;
1070         KbkdfCounterLocation counterLocation;
1071         KdfPrf prf;
1072         size_t length, rlenBits = 32, llenBits = 32, tmp;
1073         bool hasLabel = alg.getParam(ParamName::KBKDF_LABEL, label);
1074         bool hasContext = alg.getParam(ParamName::KBKDF_CONTEXT, context);
1075         bool hasFixed = alg.getParam(ParamName::KBKDF_FIXED_INPUT, fixed);
1076         alg.getParam(ParamName::KBKDF_COUNTER_LOCATION, counterLocation);
1077         alg.getParam(ParamName::KDF_PRF, prf);
1078         alg.getParam(ParamName::KDF_LEN, length);
1079         alg.getParam(ParamName::KBKDF_RLEN, rlenBits);
1080         bool hasLLen = alg.getParam(ParamName::KBKDF_LLEN, llenBits);
1081         bool useSeparator = !alg.getParam(ParamName::KBKDF_NO_SEPARATOR, tmp);
1082
1083         const EVP_MD* md = nullptr;
1084         switch (prf) {
1085         case KdfPrf::HMAC_SHA256:
1086                 md = EVP_sha256();
1087                 break;
1088         case KdfPrf::HMAC_SHA384:
1089                 md = EVP_sha384();
1090                 break;
1091         case KdfPrf::HMAC_SHA512:
1092                 md = EVP_sha512();
1093                 break;
1094         default:
1095                 assert(false); // prf is checked in validateParams above
1096         }
1097
1098         RawBuffer key;
1099         if (hasFixed) {
1100                 if (hasLabel || hasContext || !useSeparator || hasLLen ||
1101                         counterLocation == KbkdfCounterLocation::MIDDLE_FIXED)
1102                         ThrowErr(Exc::Crypto::InputParam, "Unexpected parameters for fixed input mode.");
1103
1104                 key = deriveKbkdfHmac(secret, length * 8, md, counterLocation, rlenBits, fixed);
1105         } else {
1106                 if (!hasLabel || !hasContext)
1107                         ThrowErr(Exc::Crypto::InputParam, "Missing label and/or context.");
1108
1109                 key = deriveKbkdfHmac(secret,
1110                                                           length * 8,
1111                                                           md,
1112                                                           counterLocation,
1113                                                           rlenBits,
1114                                                           llenBits,
1115                                                           label,
1116                                                           context,
1117                                                           useSeparator);
1118         }
1119
1120         return { DataType::KEY_AES, std::move(key)};
1121 }
1122
1123 } // namespace Internals
1124 } // namespace SW
1125 } // namespace Crypto
1126 } // namespace CKM