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