2 * Copyright (c) 2015-2020 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
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>
39 #include <ckm/ckm-error.h>
41 #include <dpl/log/log.h>
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>
51 #define OPENSSL_SUCCESS 1 // DO NOT CHANGE THIS VALUE
52 #define OPENSSL_FAIL 0 // DO NOT CHANGE THIS VALUE
60 typedef Uptr<EVP_PKEY_CTX_free, EVP_PKEY_CTX> EvpPkeyCtxUPtr;
62 typedef int(*I2D_CONV)(BIO *, EVP_PKEY *);
65 RawBuffer i2d(I2D_CONV fun, EVP_PKEY *pkey)
67 auto bio = uptr<BIO_free_all>(BIO_new(BIO_s_mem()));
70 ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
72 if (NULL == bio.get())
73 ThrowErr(Exc::Crypto::InternalError,
74 "Error in memory allocation! Function: BIO_new.");
76 if (1 != fun(bio.get(), pkey))
77 ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
79 RawBuffer output(8196);
81 int size = BIO_read(bio.get(), output.data(), output.size());
84 ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
90 // encryption / decryption
91 typedef ParamCheck<ParamName::ALGO_TYPE,
94 Type<AlgoType>::Equals<AlgoType::AES_CTR,
97 AlgoType::AES_CFB>> IsSymEncryption;
99 typedef ParamCheck<ParamName::ALGO_TYPE,
102 Type<AlgoType>::Equals<AlgoType::RSA_OAEP>> IsAsymEncryption;
104 typedef ParamCheck<ParamName::ED_IV,
107 Type<size_t>::Equals<Params::DEFAULT_AES_IV_LEN>,
108 BufferSizeGetter> IvSizeCheck;
110 typedef ParamCheck<ParamName::ED_CTR_LEN,
113 Type<int>::Equals<128>> CtrLenCheck;
115 typedef ParamCheck<ParamName::ED_IV,
118 DefaultValidator<RawBuffer>> GcmIvCheck;
120 typedef ParamCheck<ParamName::ED_TAG_LEN,
123 Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck;
125 typedef ParamCheck<ParamName::ED_LABEL,
128 Unsupported<RawBuffer>> RsaLabelCheck;
131 typedef ParamCheck<ParamName::ALGO_TYPE,
134 Type<AlgoType>::Equals<AlgoType::RSA_SV,
136 AlgoType::ECDSA_SV>> IsSignVerify;
138 typedef ParamCheck<ParamName::SV_HASH_ALGO,
141 Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
143 HashAlgorithm::SHA256,
144 HashAlgorithm::SHA384,
145 HashAlgorithm::SHA512>> HashAlgoCheck;
147 typedef ParamCheck<ParamName::SV_RSA_PADDING,
150 Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
151 RSAPaddingAlgorithm::PKCS1,
152 RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
155 typedef ParamCheck<ParamName::ALGO_TYPE,
158 Type<AlgoType>::Equals<AlgoType::RSA_GEN,
160 AlgoType::ECDSA_GEN>> IsAsymGeneration;
162 typedef ParamCheck<ParamName::ALGO_TYPE,
165 Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
167 typedef ParamCheck<ParamName::GEN_KEY_LEN,
170 Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
172 typedef ParamCheck<ParamName::GEN_KEY_LEN,
175 Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
177 typedef ParamCheck<ParamName::GEN_KEY_LEN,
180 Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
182 typedef ParamCheck<ParamName::GEN_EC,
185 Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
186 ElipticCurve::prime256v1,
187 ElipticCurve::secp384r1>> EcdsaEcCheck;
190 typedef ParamCheck<ParamName::ALGO_TYPE,
193 Type<AlgoType>::Equals<AlgoType::ECDH>> IsEcdh;
195 typedef ParamCheck<ParamName::ECDH_PUBKEY,
198 DefaultValidator<RawBuffer>> EcdhPubKeyCheck;
200 typedef ParamCheck<ParamName::ALGO_TYPE,
203 Type<AlgoType>::Equals<AlgoType::KBKDF>> IsKbkdf;
205 typedef ParamCheck<ParamName::KDF_PRF,
208 Type<KdfPrf>::Equals<KdfPrf::HMAC_SHA256,
210 KdfPrf::HMAC_SHA512>> KdfPrfCheck;
212 typedef ParamCheck<ParamName::KBKDF_MODE,
215 Type<KbkdfMode>::Equals<KbkdfMode::COUNTER>> KbkdfModeCheck;
217 typedef ParamCheck<ParamName::KDF_LEN,
220 Type<int>::Equals<16, 24, 32>> KdfLenCheck;
222 typedef ParamCheck<ParamName::KBKDF_COUNTER_LOCATION,
223 KbkdfCounterLocation,
225 Type<KbkdfCounterLocation>::Equals<KbkdfCounterLocation::BEFORE_FIXED,
226 KbkdfCounterLocation::AFTER_FIXED,
227 KbkdfCounterLocation::MIDDLE_FIXED>> KbkdfCounterLocationCheck;
229 typedef ParamCheck<ParamName::KBKDF_RLEN,
232 Type<int>::Equals<8, 16, 24, 32>> KbkdfRlenCheck;
234 typedef ParamCheck<ParamName::KBKDF_LLEN,
237 Type<int>::Equals<0, 8, 16, 24, 32>> KbkdfLlenCheck;
239 typedef ParamCheck<ParamName::ED_OAEP_HASH,
242 Type<HashAlgorithm>::Equals<HashAlgorithm::SHA1, HashAlgorithm::SHA256>> OaepHashAlgoCheck;
244 typedef std::map<AlgoType, ValidatorVector> ValidatorMap;
245 ValidatorMap initValidators()
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,
264 KbkdfCounterLocationCheck,
266 KbkdfLlenCheck>::Build());
270 const ValidatorMap g_validators = initValidators();
272 template <typename TypeCheck>
273 void validateParams(const CryptoAlgorithm &ca)
275 // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
279 AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
281 auto it = g_validators.find(at);
283 // TypeCheck should prevent it
284 assert(it != g_validators.end());
286 for (const auto &validator : it->second)
287 validator->Check(ca);
290 typedef std::function<void(EvpCipherPtr &, const RawBuffer &key, const RawBuffer &iv)>
293 // aes mode, key length in bits, encryption
294 typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>>
297 template <typename T>
298 void initCipher(EvpCipherPtr &ptr, const RawBuffer &key, const RawBuffer &iv)
300 ptr.reset(new T(key, iv));
303 CipherTree initializeCipherTree()
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>;
341 CipherTree g_cipherTree = initializeCipherTree();
343 // key length in bytes
344 InitCipherFn selectCipher(AlgoType type, size_t key_len = 32,
345 bool encryption = true)
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), ", ",
358 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo)
362 // validateParams<IsSignVerify> should prevent it
363 assert(hashAlgo == HashAlgorithm::NONE);
366 case HashAlgorithm::SHA1:
369 case HashAlgorithm::SHA256:
372 case HashAlgorithm::SHA384:
375 case HashAlgorithm::SHA512:
380 int getRsaPadding(const RSAPaddingAlgorithm padAlgo)
384 // validateParams<IsSignVerify> should prevent it
385 assert(padAlgo == RSAPaddingAlgorithm::NONE);
386 return RSA_NO_PADDING;
388 case RSAPaddingAlgorithm::PKCS1:
389 return RSA_PKCS1_PADDING;
391 case RSAPaddingAlgorithm::X931:
392 return RSA_X931_PADDING;
396 EvpPkeyCtxUPtr newCtx(int id)
398 if (auto ctx = EVP_PKEY_CTX_new_id(id, NULL))
399 return EvpPkeyCtxUPtr(ctx);
401 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
404 EvpPkeyCtxUPtr newCtx(EVP_PKEY *pkey)
406 if (auto ctx = EVP_PKEY_CTX_new(pkey, NULL))
407 return EvpPkeyCtxUPtr(ctx);
409 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
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)
422 validateParams<IsAsymEncryption>(alg);
424 HashAlgorithm hash = HashAlgorithm::SHA1;
425 alg.getParam(ParamName::ED_OAEP_HASH, hash);
428 ThrowErr(Exc::Crypto::InputParam, "no key");
430 if (EVP_PKEY_base_id(pkey.get()) != EVP_PKEY_RSA)
431 ThrowErr(Exc::Crypto::InputParam, "Wrong key type");
433 auto ctx = newCtx(pkey.get());
435 ret = (*initFn)(ctx.get());
437 errorHandle(__FILE__, __LINE__, __func__, ret);
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");
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");
445 // TODO set label with EVP_PKEY_CTX_set0_rsa_oaep_label
447 ret = (*cryptFn)(ctx.get(), NULL, &outlen, data.data(), data.size());
449 errorHandle(__FILE__, __LINE__, __func__, ret);
451 RawBuffer output(outlen);
453 ret = (*cryptFn)(ctx.get(), output.data(), &outlen, data.data(), data.size());
455 errorHandle(__FILE__, __LINE__, __func__, ret);
457 output.resize(outlen);
461 DataPair keyPair(const EvpPkeyCtxUPtr &ctx, KeyType prv, KeyType pub)
463 EVP_PKEY *pkeyTmp = NULL;
465 OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(ctx.get(), &pkeyTmp));
467 auto pkey = uptr<EVP_PKEY_free>(pkeyTmp);
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())});
474 DataPair createKeyPairRSA(const int size)
476 // validateParams<IsAsymGeneration> should prevent it
477 assert(size == 1024 || size == 2048 || size == 4096);
479 auto ctx = newCtx(EVP_PKEY_RSA);
481 OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(ctx.get()));
483 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size));
485 return keyPair(ctx, KeyType::KEY_RSA_PRIVATE, KeyType::KEY_RSA_PUBLIC);
488 DataPair paramgenKeyPair(const EvpPkeyCtxUPtr &pctx, KeyType prv, KeyType pub)
490 /* Generate parameters */
491 EVP_PKEY *pparamTmp = NULL;
492 OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp));
494 auto pparam = uptr<EVP_PKEY_free>(pparamTmp);
496 // Start to generate key
497 auto kctx = newCtx(pparam.get());
499 OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get()));
501 return keyPair(kctx, prv, pub);
504 DataPair createKeyPairDSA(const int size)
506 // validateParams<IsAsymGeneration> should prevent it
507 assert(size == 1024 || size == 2048 || size == 3072 || size == 4096);
509 /* Create the context for generating the parameters */
510 auto pctx = newCtx(EVP_PKEY_DSA);
512 OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
514 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size));
516 return paramgenKeyPair(pctx, KeyType::KEY_DSA_PRIVATE, KeyType::KEY_DSA_PUBLIC);
519 DataPair createKeyPairECDSA(ElipticCurve type)
525 // validateParams<IsAsymGeneration> should prevent it
526 assert(type == ElipticCurve::prime192v1);
527 ecCurve = NID_X9_62_prime192v1;
530 case ElipticCurve::prime256v1:
531 ecCurve = NID_X9_62_prime256v1;
534 case ElipticCurve::secp384r1:
535 ecCurve = NID_secp384r1;
539 /* Create the context for generating the parameters */
540 auto pctx = newCtx(EVP_PKEY_EC);
542 OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
544 OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve));
546 return paramgenKeyPair(pctx, KeyType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PUBLIC);
549 Data createKeyAES(const int sizeBits)
551 // validateParams<IsSymGeneration> should prevent it
552 assert(sizeBits == 128 || sizeBits == 192 || sizeBits == 256);
555 int sizeBytes = sizeBits / 8;
557 if (!RAND_bytes(key, sizeBytes)) {
558 ThrowErr(Exc::Crypto::InternalError, "Error in AES key generation");
561 return { DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key + sizeBytes)};
564 RawBuffer signMessage(EVP_PKEY *privKey,
565 const RawBuffer &message,
566 const int rsa_padding)
568 if (EVP_PKEY_type(EVP_PKEY_id(privKey)) != EVP_PKEY_RSA)
569 ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
571 auto pctx = newCtx(privKey);
573 OPENSSL_ERROR_HANDLE(EVP_PKEY_sign_init(pctx.get()));
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));
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 */
584 OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size()));
586 /* Allocate memory for the signature based on size in slen */
589 OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), sig.data(), &slen, message.data(), message.size()));
591 // Set value to return RawData
596 RawBuffer digestSignMessage(EVP_PKEY *privKey,
597 const RawBuffer &message,
598 const EVP_MD *md_algo,
599 const int rsa_padding)
601 EVP_PKEY_CTX *pctx = NULL;
603 // Create the Message Digest Context
604 auto mdctx = uptr<EVP_MD_CTX_free>(EVP_MD_CTX_new());
606 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_new function");
608 OPENSSL_ERROR_HANDLE(EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey));
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));
614 /* Call update with the message */
615 OPENSSL_ERROR_HANDLE(EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size()));
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 */
622 OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), NULL, &slen));
624 /* Allocate memory for the signature based on size in slen */
627 /* Obtain the signature */
628 OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen));
630 // Set value to return RawData
635 int verifyMessage(EVP_PKEY *pubKey,
636 const RawBuffer &message,
637 const RawBuffer &signature,
638 const int rsa_padding)
640 if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) != EVP_PKEY_RSA)
641 ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
643 auto pctx = newCtx(pubKey);
645 OPENSSL_ERROR_HANDLE(EVP_PKEY_verify_init(pctx.get()));
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));
651 if (OPENSSL_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
652 signature.size(), message.data(), message.size()))
653 return CKM_API_SUCCESS;
655 LogError("EVP_PKEY_verify Failed");
656 return CKM_API_ERROR_VERIFICATION_FAILED;
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)
665 EVP_PKEY_CTX *pctx = NULL;
667 // Create the Message Digest Context
668 auto mdctx = uptr<EVP_MD_CTX_free>(EVP_MD_CTX_new());
670 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_new function");
672 OPENSSL_ERROR_HANDLE(EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey));
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));
677 OPENSSL_ERROR_HANDLE(EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()));
679 if (OPENSSL_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(),
680 const_cast<unsigned char *>(signature.data()), signature.size()))
681 return CKM_API_SUCCESS;
683 LogError("EVP_PKEY_verify Failed");
684 return CKM_API_ERROR_VERIFICATION_FAILED;
687 RawBuffer encryptDataAesGcmPacked(
688 const RawBuffer &key,
689 const RawBuffer &data,
692 const RawBuffer &aad)
694 auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad);
695 std::copy(pair.second.begin(), pair.second.end(),
696 std::back_inserter(pair.first));
701 RawBuffer decryptDataAesGcmPacked(
702 const RawBuffer &key,
703 const RawBuffer &data,
706 const RawBuffer &aad)
708 if (tagSize > static_cast<int>(data.size()))
709 ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
711 auto tagPos = data.data() + data.size() - tagSize;
712 return decryptDataAesGcm(
714 RawBuffer(data.data(), tagPos),
716 RawBuffer(tagPos, data.data() + data.size()),
720 EC_KEY* getEcKey(EVP_PKEY* evpKey)
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);
726 EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(evpKey);
728 ThrowErr(Exc::Crypto::InternalError, "Can't get EC key");
733 int getCurve(const EC_KEY* ecKey)
735 return EC_GROUP_get_curve_name(EC_KEY_get0_group(ecKey));
741 DataPair generateAKey(const CryptoAlgorithm &algorithm)
743 validateParams<IsAsymGeneration>(algorithm);
745 AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
747 if (keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN) {
748 int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
750 if (keyType == AlgoType::RSA_GEN)
751 return createKeyPairRSA(keyLength);
753 return createKeyPairDSA(keyLength);
754 } else { // AlgoType::ECDSA_GEN
755 ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
756 return createKeyPairECDSA(ecType);
760 Data generateSKey(const CryptoAlgorithm &algorithm)
762 validateParams<IsSymGeneration>(algorithm);
764 int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
765 return createKeyAES(keySizeBits);
768 RawBuffer encryptDataAes(
770 const RawBuffer &key,
771 const RawBuffer &data,
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));
782 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
783 const RawBuffer &key,
784 const RawBuffer &data,
787 const RawBuffer &aad)
789 RawBuffer tag(tagSize);
791 selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv);
796 RawBuffer result = enc->Append(data);
797 RawBuffer tmp = enc->Finalize();
798 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
800 enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data());
802 return std::make_pair(result, tag);
805 RawBuffer decryptDataAes(
807 const RawBuffer &key,
808 const RawBuffer &data,
812 selectCipher(type, key.size(), false)(dec, key, iv);
813 RawBuffer result = dec->Append(data);
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).");
820 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
824 RawBuffer decryptDataAesGcm(
825 const RawBuffer &key,
826 const RawBuffer &data,
828 const RawBuffer &tag,
829 const RawBuffer &aad)
832 selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
833 void *ptr = (void *)tag.data();
835 dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr);
840 RawBuffer result = dec->Append(data);
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).");
847 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
851 RawBuffer symmetricEncrypt(const RawBuffer &key,
852 const CryptoAlgorithm &alg,
853 const RawBuffer &data)
855 validateParams<IsSymEncryption>(alg);
856 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
858 if (algo == AlgoType::AES_GCM) {
859 int tagLenBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
860 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
862 alg.getParam(ParamName::ED_AAD, aad);
863 return encryptDataAesGcmPacked(key,
865 unpack<RawBuffer>(alg, ParamName::ED_IV),
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));
874 RawBuffer symmetricDecrypt(const RawBuffer &key,
875 const CryptoAlgorithm &alg,
876 const RawBuffer &data)
878 validateParams<IsSymEncryption>(alg);
879 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
881 if (algo == AlgoType::AES_GCM) {
882 int tagLenBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
883 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
885 alg.getParam(ParamName::ED_AAD, aad);
886 return decryptDataAesGcmPacked(key,
888 unpack<RawBuffer>(alg, ParamName::ED_IV),
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));
897 EvpCipherPtr initCipher(const RawBuffer &key, const CryptoAlgorithm &alg, bool encrypt, int& tagLen)
899 validateParams<IsSymEncryption>(alg);
900 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
901 auto iv = unpack<RawBuffer>(alg, ParamName::ED_IV);
905 selectCipher(algo, key.size(), encrypt)(cipher, key, iv);
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;
913 alg.getParam(ParamName::ED_AAD, aad);
915 cipher->AppendAAD(aad);
920 RawBuffer asymmetricEncrypt(const EvpShPtr &pkey,
921 const CryptoAlgorithm &alg,
922 const RawBuffer &data)
924 return asymmetricHelper(EVP_PKEY_encrypt_init, EVP_PKEY_encrypt, pkey, alg, data);
927 RawBuffer asymmetricDecrypt(const EvpShPtr &pkey,
928 const CryptoAlgorithm &alg,
929 const RawBuffer &data)
931 return asymmetricHelper(EVP_PKEY_decrypt_init, EVP_PKEY_decrypt, pkey, alg, data);
934 RawBuffer sign(EVP_PKEY *pkey,
935 const CryptoAlgorithm &alg,
936 const RawBuffer &message)
938 validateParams<IsSignVerify>(alg);
940 HashAlgorithm hashTmp = HashAlgorithm::NONE;
941 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
942 const EVP_MD *md_algo = getMdAlgo(hashTmp);
944 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
945 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
946 int rsa_padding = getRsaPadding(rsaPad);
949 // if ((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
950 // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
951 // (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
953 // LogError("Error in private key type");
954 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
957 // if (privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
958 // rsa_padding = getRsaPadding(padAlgo);
962 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
965 return signMessage(pkey, message, rsa_padding);
967 return digestSignMessage(pkey, message, md_algo, rsa_padding);
970 int verify(EVP_PKEY *pkey,
971 const CryptoAlgorithm &alg,
972 const RawBuffer &message,
973 const RawBuffer &signature)
975 validateParams<IsSignVerify>(alg);
977 HashAlgorithm hashTmp = HashAlgorithm::NONE;
978 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
979 const EVP_MD *md_algo = getMdAlgo(hashTmp);
981 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
982 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
983 int rsa_padding = getRsaPadding(rsaPad);
986 // if ((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
987 // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
988 // (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
990 // LogError("Error in private key type");
991 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
994 // if (publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
995 // rsa_padding = getRsaPadding(padAlgo);
998 // auto shrPKey = publicKey.getEvpShPtr();
1000 ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
1002 if (md_algo == NULL)
1003 return verifyMessage(pkey, message, signature, rsa_padding);
1005 return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
1008 Data deriveECDH(const EvpShPtr &pkey, const CryptoAlgorithm &alg)
1010 validateParams<IsEcdh>(alg);
1012 EC_KEY *ecKey = getEcKey(pkey.get());
1014 // get private key curve name
1015 int prvCurve = getCurve(ecKey);
1017 auto prv = EC_KEY_get0_private_key(ecKey);
1019 ThrowErr(Exc::Crypto::InputParam, "ECDH requires own private EC key");
1021 // Create the context for the shared secret derivation
1022 auto ctx = newCtx(pkey.get());
1024 ThrowErr(Exc::Crypto::InternalError, "Key context creation failed");
1026 // import peer's public key from buffer
1027 RawBuffer pubKeyBuffer;
1028 [[maybe_unused]] bool hasPubKey = alg.getParam(ParamName::ECDH_PUBKEY, pubKeyBuffer);
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();
1036 int pubCurve = getCurve(getEcKey(peerEvp));
1038 if (pubCurve != prvCurve)
1039 ThrowErr(Exc::Crypto::InputParam, "Private and public key use different ECs");
1042 if (1 != EVP_PKEY_derive_init(ctx.get()))
1043 ThrowErr(Exc::Crypto::InternalError, "EVP_PKEY_derive_init failed");
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");
1049 // determine buffer length for shared secret
1051 if(1 != EVP_PKEY_derive(ctx.get(), nullptr, &secretLen))
1052 ThrowErr(Exc::Crypto::InternalError, "Failed to determine ECDH secret length");
1054 RawBuffer secret(secretLen);
1056 // derive the shared secret
1057 if (1 != (EVP_PKEY_derive(ctx.get(), secret.data(), &secretLen)))
1058 ThrowErr(Exc::Crypto::InternalError, "ECDH failed");
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)};
1065 Data deriveKBKDF(const RawBuffer &secret, const CryptoAlgorithm &alg)
1067 validateParams<IsKbkdf>(alg);
1069 RawBuffer label, context, fixed;
1070 KbkdfCounterLocation counterLocation;
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);
1083 const EVP_MD* md = nullptr;
1085 case KdfPrf::HMAC_SHA256:
1088 case KdfPrf::HMAC_SHA384:
1091 case KdfPrf::HMAC_SHA512:
1095 assert(false); // prf is checked in validateParams above
1100 if (hasLabel || hasContext || !useSeparator || hasLLen ||
1101 counterLocation == KbkdfCounterLocation::MIDDLE_FIXED)
1102 ThrowErr(Exc::Crypto::InputParam, "Unexpected parameters for fixed input mode.");
1104 key = deriveKbkdfHmac(secret, length * 8, md, counterLocation, rlenBits, fixed);
1106 if (!hasLabel || !hasContext)
1107 ThrowErr(Exc::Crypto::InputParam, "Missing label and/or context.");
1109 key = deriveKbkdfHmac(secret,
1120 return { DataType::KEY_AES, std::move(key)};
1123 } // namespace Internals
1125 } // namespace Crypto