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