2 * Copyright (c) 2000 - 2015 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>
38 #include <ckm/ckm-error.h>
40 #include <dpl/log/log.h>
42 #include <generic-backend/exception.h>
43 #include <generic-backend/algo-validation.h>
44 #include <sw-backend/internals.h>
45 #include <sw-backend/crypto.h>
47 #define OPENSSL_SUCCESS 1 // DO NOTCHANGE THIS VALUE
48 #define OPENSSL_FAIL 0 // DO NOTCHANGE THIS VALUE
49 #define DEV_HW_RANDOM_FILE "/dev/hwrng"
50 #define DEV_URANDOM_FILE "/dev/urandom"
58 typedef std::unique_ptr<EVP_MD_CTX, std::function<void(EVP_MD_CTX*)>> EvpMdCtxUPtr;
59 typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX*)>> EvpPkeyCtxUPtr;
60 typedef std::unique_ptr<EVP_PKEY, std::function<void(EVP_PKEY*)>> EvpPkeyUPtr;
62 typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
63 typedef int(*I2D_CONV)(BIO*, EVP_PKEY*);
65 const size_t DEFAULT_AES_GCM_TAG_LEN = 128; // tag length in bits according to W3C Crypto API
66 const size_t DEFAULT_AES_IV_LEN = 16; // default iv size in bytes for AES
68 RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
69 BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
72 ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
75 if (NULL == bio.get()) {
76 ThrowErr(Exc::Crypto::InternalError, "Error in memory allocation! Function: BIO_new.");
79 if (1 != fun(bio.get(), pkey)) {
80 ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
83 RawBuffer output(8196);
85 int size = BIO_read(bio.get(), output.data(), output.size());
88 ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
95 // encryption / decryption
96 typedef ParamCheck<ParamName::ALGO_TYPE,
99 Type<AlgoType>::Equals<AlgoType::AES_CTR,
103 AlgoType::RSA_OAEP>> IsEncryption;
105 typedef ParamCheck<ParamName::ED_IV,
108 Type<size_t>::Equals<DEFAULT_AES_IV_LEN>,
109 BufferSizeGetter> IvSizeCheck;
111 typedef ParamCheck<ParamName::ED_CTR_LEN,
114 Type<int>::Equals<128>> CtrLenCheck;
116 typedef ParamCheck<ParamName::ED_IV,
119 DefaultValidator<size_t>,
120 BufferSizeGetter> GcmIvCheck;
122 typedef ParamCheck<ParamName::ED_TAG_LEN,
125 Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck;
128 typedef ParamCheck<ParamName::ALGO_TYPE,
131 Type<AlgoType>::Equals<AlgoType::RSA_SV,
133 AlgoType::ECDSA_SV>> IsSignVerify;
135 typedef ParamCheck<ParamName::SV_HASH_ALGO,
138 Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
140 HashAlgorithm::SHA256,
141 HashAlgorithm::SHA384,
142 HashAlgorithm::SHA512>> HashAlgoCheck;
144 typedef ParamCheck<ParamName::SV_RSA_PADDING,
147 Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
148 RSAPaddingAlgorithm::PKCS1,
149 RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
152 typedef ParamCheck<ParamName::ALGO_TYPE,
155 Type<AlgoType>::Equals<AlgoType::RSA_GEN,
157 AlgoType::ECDSA_GEN>> IsAsymGeneration;
159 typedef ParamCheck<ParamName::ALGO_TYPE,
162 Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
164 typedef ParamCheck<ParamName::GEN_KEY_LEN,
167 Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
169 typedef ParamCheck<ParamName::GEN_KEY_LEN,
172 Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
174 typedef ParamCheck<ParamName::GEN_KEY_LEN,
177 Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
179 typedef ParamCheck<ParamName::GEN_EC,
182 Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
183 ElipticCurve::prime256v1,
184 ElipticCurve::secp384r1>> EcdsaEcCheck;
186 typedef std::map<AlgoType, ValidatorVector> ValidatorMap;
187 ValidatorMap initValidators() {
188 ValidatorMap validators;
189 validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
190 validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
191 validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build());
192 validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build());
193 validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build());
194 validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build());
195 validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build());
196 validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build());
197 validators.emplace(AlgoType::AES_CTR, VBuilder<IvSizeCheck, CtrLenCheck>::Build());
198 validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build());
199 validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build());
200 validators.emplace(AlgoType::AES_GCM, VBuilder<GcmIvCheck, GcmTagCheck>::Build());
203 ValidatorMap g_validators = initValidators();
205 template <typename TypeCheck>
206 void validateParams(const CryptoAlgorithm& ca)
208 // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
212 AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
213 for(const auto& validator : g_validators.at(at)) {
214 validator->Check(ca);
218 } // anonymous namespace
224 // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms
225 ERR_load_crypto_strings();
226 OpenSSL_add_all_algorithms();
228 // initialize entropy
229 std::ifstream ifile(DEV_HW_RANDOM_FILE);
230 if(ifile.is_open()) {
231 u_rand_ret= RAND_load_file(DEV_HW_RANDOM_FILE, 32);
233 if(u_rand_ret != 32 ){
234 LogError("Error in HW_RAND file load");
235 hw_rand_ret = RAND_load_file(DEV_URANDOM_FILE, 32);
237 if(hw_rand_ret != 32) {
238 ThrowErr(Exc::Crypto::InternalError, "Error in U_RAND_file_load");
242 return CKM_CRYPTO_INIT_SUCCESS;
245 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) {
246 const EVP_MD *md_algo=NULL;
248 case HashAlgorithm::NONE:
251 case HashAlgorithm::SHA1:
252 md_algo = EVP_sha1();
254 case HashAlgorithm::SHA256:
255 md_algo = EVP_sha256();
257 case HashAlgorithm::SHA384:
258 md_algo = EVP_sha384();
260 case HashAlgorithm::SHA512:
261 md_algo = EVP_sha512();
264 ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value");
269 int getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
270 int rsa_padding = -1;
272 case RSAPaddingAlgorithm::NONE:
273 rsa_padding = RSA_NO_PADDING;
275 case RSAPaddingAlgorithm::PKCS1:
276 rsa_padding = RSA_PKCS1_PADDING;
278 case RSAPaddingAlgorithm::X931:
279 rsa_padding = RSA_X931_PADDING;
282 ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value");
287 TokenPair createKeyPairRSA(CryptoBackend backendId, const int size)
291 // check the parameters of functions
292 if(size!=1024 && size!=2048 && size!=4096) {
293 ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size");
296 EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free);
298 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!");
301 if(EVP_PKEY_keygen_init(ctx.get()) <= 0) {
302 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function !!");
305 if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) {
306 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
309 EVP_PKEY *pkeyTmp = NULL;
310 if(!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) {
311 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
313 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
315 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
316 Token(backendId, DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
320 TokenPair createKeyPairDSA(CryptoBackend backendId, const int size)
325 // check the parameters of functions
326 if(size!=1024 && size!=2048 && size!=3072 && size!=4096) {
327 ThrowErr(Exc::Crypto::InputParam, "Error in DSA input size");
330 /* Create the context for generating the parameters */
331 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free);
333 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
336 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
337 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
340 if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) {
341 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function");
344 /* Generate parameters */
345 EVP_PKEY *pparamTmp = NULL;
346 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
347 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
349 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
351 // Start to generate key
352 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
354 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
357 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
358 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
361 /* Generate the key */
362 EVP_PKEY *pkeyTmp = NULL;
363 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
364 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
366 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
368 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
369 Token(backendId, DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
372 TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type)
374 int ecCurve = NOT_DEFINED;
379 case ElipticCurve::prime192v1:
380 ecCurve = NID_X9_62_prime192v1;
382 case ElipticCurve::prime256v1:
383 ecCurve = NID_X9_62_prime256v1;
385 case ElipticCurve::secp384r1:
386 ecCurve = NID_secp384r1;
389 ThrowErr(Exc::Crypto::InputParam, "Error in EC type");
392 /* Create the context for generating the parameters */
393 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free);
395 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
398 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
399 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
402 if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) {
403 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
406 /* Generate parameters */
407 EVP_PKEY *pparamTmp = NULL;
408 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
409 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
411 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
413 // Start to generate key
414 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
416 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
419 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
420 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
423 /* Generate the key */
424 EVP_PKEY *pkeyTmp = NULL;
425 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
426 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
428 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
430 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
431 Token(backendId, DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
434 Token createKeyAES(CryptoBackend backendId, const int sizeBits)
436 // check the parameters of functions
437 if(sizeBits!=128 && sizeBits!=192 && sizeBits!=256) {
438 LogError("Error in AES input size");
439 ThrowMsg(Exc::Crypto::InputParam, "Error in AES input size");
443 int sizeBytes = sizeBits/8;
444 if (!RAND_bytes(key, sizeBytes)) {
445 LogError("Error in AES key generation");
446 ThrowMsg(Exc::Crypto::InternalError, "Error in AES key generation");
449 return Token(backendId, DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes));
452 TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
454 validateParams<IsAsymGeneration>(algorithm);
456 AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
457 if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
459 int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
460 if(keyType == AlgoType::RSA_GEN)
461 return createKeyPairRSA(backendId, keyLength);
463 return createKeyPairDSA(backendId, keyLength);
465 else // AlgoType::ECDSA_GEN
467 ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
468 return createKeyPairECDSA(backendId, ecType);
472 Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
474 validateParams<IsSymGeneration>(algorithm);
476 int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
477 return createKeyAES(backendId, keySizeBits);
480 RawBuffer encryptDataAesCbc(
481 const RawBuffer &key,
482 const RawBuffer &data,
485 Crypto::SW::Cipher::AesCbcEncryption enc(key, iv);
486 RawBuffer result = enc.Append(data);
487 RawBuffer tmp = enc.Finalize();
488 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
492 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
493 const RawBuffer &key,
494 const RawBuffer &data,
498 RawBuffer tag(tagSize);
499 Crypto::SW::Cipher::AesGcmEncryption enc(key, iv);
500 RawBuffer result = enc.Append(data);
501 RawBuffer tmp = enc.Finalize();
502 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
503 if (0 == enc.Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) {
504 ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Get tag failed.");
506 return std::make_pair(result, tag);
509 RawBuffer encryptDataAesGcmPacked(
510 const RawBuffer &key,
511 const RawBuffer &data,
515 auto pair = encryptDataAesGcm(key, data, iv, tagSize);
516 std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first));
520 RawBuffer decryptDataAesCbc(
521 const RawBuffer &key,
522 const RawBuffer &data,
525 Crypto::SW::Cipher::AesCbcDecryption dec(key, iv);
526 RawBuffer result = dec.Append(data);
527 RawBuffer tmp = dec.Finalize();
528 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
532 RawBuffer decryptDataAesGcm(
533 const RawBuffer &key,
534 const RawBuffer &data,
536 const RawBuffer &tag)
538 Crypto::SW::Cipher::AesGcmDecryption dec(key, iv);
539 void *ptr = (void*)tag.data();
540 if (0 == dec.Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) {
541 ThrowErr(Exc::Crypto::InternalError,
542 "Error in AES control function. Set tag failed.");
544 RawBuffer result = dec.Append(data);
545 RawBuffer tmp = dec.Finalize();
546 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
550 RawBuffer decryptDataAesGcmPacked(
551 const RawBuffer &key,
552 const RawBuffer &data,
556 if (tagSize > static_cast<int>(data.size()))
557 ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
559 auto tagPos = data.data() + data.size() - tagSize;
560 return decryptDataAesGcm(
562 RawBuffer(data.data(), tagPos),
564 RawBuffer(tagPos, data.data() + data.size()));
567 RawBuffer symmetricEncrypt(const RawBuffer &key,
568 const CryptoAlgorithm &alg,
569 const RawBuffer &data)
571 validateParams<IsEncryption>(alg);
572 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
576 case AlgoType::AES_CBC:
577 return encryptDataAesCbc(key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
578 case AlgoType::AES_GCM:
580 int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
581 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
582 return encryptDataAesGcmPacked(key,
584 unpack<RawBuffer>(alg, ParamName::ED_IV),
590 ThrowErr(Exc::Crypto::OperationNotSupported,
591 "symmetric enc error: algorithm not recognized");
594 RawBuffer symmetricDecrypt(const RawBuffer &key,
595 const CryptoAlgorithm &alg,
596 const RawBuffer &data)
598 validateParams<IsEncryption>(alg);
599 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
603 case AlgoType::AES_CBC:
604 return decryptDataAesCbc(key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
605 case AlgoType::AES_GCM:
607 int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
608 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
609 return decryptDataAesGcmPacked(key,
611 unpack<RawBuffer>(alg, ParamName::ED_IV),
617 ThrowErr(Exc::Crypto::InputParam, "symmetric dec error: algorithm not recognized");
620 RawBuffer sign(EVP_PKEY *pkey,
621 const CryptoAlgorithm &alg,
622 const RawBuffer &message)
624 validateParams<IsSignVerify>(alg);
626 int rsa_padding = NOT_DEFINED;
627 const EVP_MD *md_algo = NULL;
629 HashAlgorithm hashTmp = HashAlgorithm::NONE;
630 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
631 md_algo = getMdAlgo(hashTmp);
633 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
634 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
635 rsa_padding = getRsaPadding(rsaPad);
638 // if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
639 // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
640 // (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
642 // LogError("Error in private key type");
643 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
646 // if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
647 // rsa_padding = getRsaPadding(padAlgo);
651 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
654 if(md_algo == NULL) {
655 return signMessage(pkey, message, rsa_padding);
658 return digestSignMessage(pkey,message, md_algo, rsa_padding);
661 RawBuffer signMessage(EVP_PKEY *privKey,
662 const RawBuffer &message,
663 const int rsa_padding)
665 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
668 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
671 if(EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) {
672 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
675 /* Set padding algorithm */
676 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
677 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
678 ThrowErr(Exc::Crypto::InternalError,
679 "Error in EVP_PKEY_CTX_set_rsa_padding function");
683 /* Finalize the Sign operation */
684 /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
685 * signature. Length is returned in slen */
687 if(EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())) {
688 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function");
691 /* Allocate memory for the signature based on size in slen */
694 if(EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
700 // Set value to return RawData
705 ThrowErr(Exc::Crypto::InputParam, "Error in EVP_PKEY_sign function. Input param error.");
708 RawBuffer digestSignMessage(EVP_PKEY *privKey,
709 const RawBuffer &message,
710 const EVP_MD *md_algo,
711 const int rsa_padding)
713 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
715 EVP_PKEY_CTX *pctx = NULL;
717 // Create the Message Digest Context
719 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
722 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) {
723 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
726 /* Set padding algorithm */
727 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
728 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
729 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
733 /* Call update with the message */
734 if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())) {
735 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function");
738 /* Finalize the DigestSign operation */
739 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
740 * signature. Length is returned in slen */
742 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) {
743 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
746 /* Allocate memory for the signature based on size in slen */
749 /* Obtain the signature */
750 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) {
751 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
754 // Set value to return RawData
759 int verify(EVP_PKEY *pkey,
760 const CryptoAlgorithm &alg,
761 const RawBuffer &message,
762 const RawBuffer &signature)
764 validateParams<IsSignVerify>(alg);
766 int rsa_padding = NOT_DEFINED;
767 const EVP_MD *md_algo = NULL;
769 HashAlgorithm hashTmp = HashAlgorithm::NONE;
770 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
771 md_algo = getMdAlgo(hashTmp);
773 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
774 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
775 rsa_padding = getRsaPadding(rsaPad);
778 // if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
779 // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
780 // (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
782 // LogError("Error in private key type");
783 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
786 // if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
787 // rsa_padding = getRsaPadding(padAlgo);
790 // auto shrPKey = publicKey.getEvpShPtr();
792 ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
795 if (md_algo == NULL) {
796 return verifyMessage(pkey, message, signature, rsa_padding);
799 return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
802 int verifyMessage(EVP_PKEY *pubKey,
803 const RawBuffer &message,
804 const RawBuffer &signature,
805 const int rsa_padding)
807 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
810 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
813 if(EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) {
814 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
817 /* Set padding algorithm */
818 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
819 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
820 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
824 if(EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) {
825 return CKM_API_SUCCESS;
828 LogError("EVP_PKEY_verify Failed");
829 return CKM_API_ERROR_VERIFICATION_FAILED;
832 int digestVerifyMessage(EVP_PKEY *pubKey,
833 const RawBuffer &message,
834 const RawBuffer &signature,
835 const EVP_MD *md_algo,
836 const int rsa_padding)
838 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
839 EVP_PKEY_CTX *pctx = NULL;
841 /* Create the Message Digest Context */
843 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
846 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) {
847 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
850 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
851 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
852 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
856 if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()) ) {
857 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyUpdate function");
860 if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size()) ) {
861 return CKM_API_SUCCESS;
864 LogError("EVP_PKEY_verify Failed");
865 return CKM_API_ERROR_VERIFICATION_FAILED;
868 } // namespace Internals
870 } // namespace Crypto