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
25 #include <openssl/evp.h>
26 #include <openssl/obj_mac.h>
27 #include <openssl/ec.h>
28 #include <openssl/dsa.h>
29 #include <openssl/rsa.h>
30 #include <openssl/bio.h>
31 #include <openssl/rand.h>
32 #include <openssl/crypto.h>
33 #include <openssl/err.h>
34 #include <openssl/x509v3.h>
35 #include <openssl/obj_mac.h>
37 #include <ckm/ckm-error.h>
39 #include <dpl/log/log.h>
41 #include <generic-backend/exception.h>
42 #include <generic-backend/algo-validation.h>
43 #include <sw-backend/internals.h>
44 #include <sw-backend/crypto.h>
46 #define OPENSSL_SUCCESS 1 // DO NOTCHANGE THIS VALUE
47 #define OPENSSL_FAIL 0 // DO NOTCHANGE THIS VALUE
55 typedef std::unique_ptr<EVP_MD_CTX, std::function<void(EVP_MD_CTX*)>> EvpMdCtxUPtr;
56 typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX*)>> EvpPkeyCtxUPtr;
57 typedef std::unique_ptr<EVP_PKEY, std::function<void(EVP_PKEY*)>> EvpPkeyUPtr;
59 typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
60 typedef int(*I2D_CONV)(BIO*, EVP_PKEY*);
62 const size_t DEFAULT_AES_GCM_TAG_LEN = 128; // tag length in bits according to W3C Crypto API
63 const size_t DEFAULT_AES_IV_LEN = 16; // default iv size in bytes for AES
65 RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
66 BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
69 ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
72 if (NULL == bio.get()) {
73 ThrowErr(Exc::Crypto::InternalError, "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");
80 RawBuffer output(8196);
82 int size = BIO_read(bio.get(), output.data(), output.size());
85 ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
92 // encryption / decryption
93 typedef ParamCheck<ParamName::ALGO_TYPE,
96 Type<AlgoType>::Equals<AlgoType::AES_CTR,
100 AlgoType::RSA_OAEP>> IsEncryption;
102 typedef ParamCheck<ParamName::ED_IV,
105 Type<size_t>::Equals<DEFAULT_AES_IV_LEN>,
106 BufferSizeGetter> IvSizeCheck;
108 typedef ParamCheck<ParamName::ED_CTR_LEN,
111 Type<int>::Equals<128>> CtrLenCheck;
113 typedef ParamCheck<ParamName::ED_IV,
116 DefaultValidator<size_t>,
117 BufferSizeGetter> GcmIvCheck;
119 typedef ParamCheck<ParamName::ED_TAG_LEN,
122 Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck;
125 typedef ParamCheck<ParamName::ALGO_TYPE,
128 Type<AlgoType>::Equals<AlgoType::RSA_SV,
130 AlgoType::ECDSA_SV>> IsSignVerify;
132 typedef ParamCheck<ParamName::SV_HASH_ALGO,
135 Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
137 HashAlgorithm::SHA256,
138 HashAlgorithm::SHA384,
139 HashAlgorithm::SHA512>> HashAlgoCheck;
141 typedef ParamCheck<ParamName::SV_RSA_PADDING,
144 Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
145 RSAPaddingAlgorithm::PKCS1,
146 RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
149 typedef ParamCheck<ParamName::ALGO_TYPE,
152 Type<AlgoType>::Equals<AlgoType::RSA_GEN,
154 AlgoType::ECDSA_GEN>> IsAsymGeneration;
156 typedef ParamCheck<ParamName::ALGO_TYPE,
159 Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
161 typedef ParamCheck<ParamName::GEN_KEY_LEN,
164 Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
166 typedef ParamCheck<ParamName::GEN_KEY_LEN,
169 Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
171 typedef ParamCheck<ParamName::GEN_KEY_LEN,
174 Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
176 typedef ParamCheck<ParamName::GEN_EC,
179 Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
180 ElipticCurve::prime256v1,
181 ElipticCurve::secp384r1>> EcdsaEcCheck;
183 typedef std::map<AlgoType, ValidatorVector> ValidatorMap;
184 ValidatorMap initValidators() {
185 ValidatorMap validators;
186 validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
187 validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
188 validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build());
189 validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build());
190 validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build());
191 validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build());
192 validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build());
193 validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build());
194 validators.emplace(AlgoType::AES_CTR, VBuilder<IvSizeCheck, CtrLenCheck>::Build());
195 validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build());
196 validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build());
197 validators.emplace(AlgoType::AES_GCM, VBuilder<GcmIvCheck, GcmTagCheck>::Build());
200 ValidatorMap g_validators = initValidators();
202 template <typename TypeCheck>
203 void validateParams(const CryptoAlgorithm& ca)
205 // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
209 AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
210 for(const auto& validator : g_validators.at(at)) {
211 validator->Check(ca);
215 typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr;
217 typedef std::function<void(EvpCipherPtr&, const RawBuffer& key, const RawBuffer& iv)> InitCipherFn;
219 // aes mode, key length in bits, encryption
220 typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> CipherTree;
222 template <typename T>
223 void initCipher(EvpCipherPtr& ptr, const RawBuffer& key, const RawBuffer& iv)
225 ptr.reset(new T(key, iv));
228 CipherTree initializeCipherTree()
231 tree[AlgoType::AES_CBC][128][true] = initCipher<Cipher::AesCbcEncryption128>;
232 tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>;
233 tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>;
235 tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>;
236 tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>;
237 tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>;
239 tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>;
240 tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>;
241 tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>;
243 tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>;
244 tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>;
245 tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>;
247 tree[AlgoType::AES_CTR][128][true] = initCipher<Cipher::AesCtrEncryption128>;
248 tree[AlgoType::AES_CTR][192][true] = initCipher<Cipher::AesCtrEncryption192>;
249 tree[AlgoType::AES_CTR][256][true] = initCipher<Cipher::AesCtrEncryption256>;
251 tree[AlgoType::AES_CTR][128][false] = initCipher<Cipher::AesCtrDecryption128>;
252 tree[AlgoType::AES_CTR][192][false] = initCipher<Cipher::AesCtrDecryption192>;
253 tree[AlgoType::AES_CTR][256][false] = initCipher<Cipher::AesCtrDecryption256>;
255 tree[AlgoType::AES_CFB][128][true] = initCipher<Cipher::AesCfbEncryption128>;
256 tree[AlgoType::AES_CFB][192][true] = initCipher<Cipher::AesCfbEncryption192>;
257 tree[AlgoType::AES_CFB][256][true] = initCipher<Cipher::AesCfbEncryption256>;
259 tree[AlgoType::AES_CFB][128][false] = initCipher<Cipher::AesCfbDecryption128>;
260 tree[AlgoType::AES_CFB][192][false] = initCipher<Cipher::AesCfbDecryption192>;
261 tree[AlgoType::AES_CFB][256][false] = initCipher<Cipher::AesCfbDecryption256>;
266 CipherTree g_cipherTree = initializeCipherTree();
268 // key length in bytes
269 InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = true)
272 return g_cipherTree.at(type).at(key_len*8).at(encryption);
273 } catch (const std::out_of_range&) {
274 ThrowErr(Exc::Crypto::InternalError,
275 "Unsupported cipher: ",
276 static_cast<int>(type), ", ",
282 } // anonymous namespace
284 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) {
285 const EVP_MD *md_algo=NULL;
287 case HashAlgorithm::NONE:
290 case HashAlgorithm::SHA1:
291 md_algo = EVP_sha1();
293 case HashAlgorithm::SHA256:
294 md_algo = EVP_sha256();
296 case HashAlgorithm::SHA384:
297 md_algo = EVP_sha384();
299 case HashAlgorithm::SHA512:
300 md_algo = EVP_sha512();
303 ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value");
308 int getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
309 int rsa_padding = -1;
311 case RSAPaddingAlgorithm::NONE:
312 rsa_padding = RSA_NO_PADDING;
314 case RSAPaddingAlgorithm::PKCS1:
315 rsa_padding = RSA_PKCS1_PADDING;
317 case RSAPaddingAlgorithm::X931:
318 rsa_padding = RSA_X931_PADDING;
321 ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value");
326 TokenPair createKeyPairRSA(CryptoBackend backendId, const int size)
330 // check the parameters of functions
331 if(size!=1024 && size!=2048 && size!=4096) {
332 ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size");
335 EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free);
337 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!");
340 if(EVP_PKEY_keygen_init(ctx.get()) <= 0) {
341 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function !!");
344 if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) {
345 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
348 EVP_PKEY *pkeyTmp = NULL;
349 if(!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) {
350 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
352 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
354 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
355 Token(backendId, DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
359 TokenPair createKeyPairDSA(CryptoBackend backendId, const int size)
364 // check the parameters of functions
365 if(size!=1024 && size!=2048 && size!=3072 && size!=4096) {
366 ThrowErr(Exc::Crypto::InputParam, "Error in DSA input size");
369 /* Create the context for generating the parameters */
370 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free);
372 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
375 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
376 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
379 if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) {
380 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function");
383 /* Generate parameters */
384 EVP_PKEY *pparamTmp = NULL;
385 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
386 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
388 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
390 // Start to generate key
391 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
393 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
396 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
397 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
400 /* Generate the key */
401 EVP_PKEY *pkeyTmp = NULL;
402 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
403 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
405 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
407 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
408 Token(backendId, DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
411 TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type)
413 int ecCurve = NOT_DEFINED;
418 case ElipticCurve::prime192v1:
419 ecCurve = NID_X9_62_prime192v1;
421 case ElipticCurve::prime256v1:
422 ecCurve = NID_X9_62_prime256v1;
424 case ElipticCurve::secp384r1:
425 ecCurve = NID_secp384r1;
428 ThrowErr(Exc::Crypto::InputParam, "Error in EC type");
431 /* Create the context for generating the parameters */
432 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free);
434 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
437 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
438 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
441 if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) {
442 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
445 /* Generate parameters */
446 EVP_PKEY *pparamTmp = NULL;
447 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
448 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
450 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
452 // Start to generate key
453 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
455 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
458 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
459 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
462 /* Generate the key */
463 EVP_PKEY *pkeyTmp = NULL;
464 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
465 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
467 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
469 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
470 Token(backendId, DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
473 Token createKeyAES(CryptoBackend backendId, const int sizeBits)
475 // check the parameters of functions
476 if(sizeBits!=128 && sizeBits!=192 && sizeBits!=256) {
477 LogError("Error in AES input size");
478 ThrowMsg(Exc::Crypto::InputParam, "Error in AES input size");
482 int sizeBytes = sizeBits/8;
483 if (!RAND_bytes(key, sizeBytes)) {
484 LogError("Error in AES key generation");
485 ThrowMsg(Exc::Crypto::InternalError, "Error in AES key generation");
488 return Token(backendId, DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes));
491 TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
493 validateParams<IsAsymGeneration>(algorithm);
495 AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
496 if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
498 int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
499 if(keyType == AlgoType::RSA_GEN)
500 return createKeyPairRSA(backendId, keyLength);
502 return createKeyPairDSA(backendId, keyLength);
504 else // AlgoType::ECDSA_GEN
506 ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
507 return createKeyPairECDSA(backendId, ecType);
511 Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
513 validateParams<IsSymGeneration>(algorithm);
515 int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
516 return createKeyAES(backendId, keySizeBits);
519 RawBuffer encryptDataAes(
521 const RawBuffer &key,
522 const RawBuffer &data,
526 selectCipher(type, key.size())(enc, key, iv);
527 RawBuffer result = enc->Append(data);
528 RawBuffer tmp = enc->Finalize();
529 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
533 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
534 const RawBuffer &key,
535 const RawBuffer &data,
539 RawBuffer tag(tagSize);
541 selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv);
542 RawBuffer result = enc->Append(data);
543 RawBuffer tmp = enc->Finalize();
544 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
545 if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) {
546 ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Get tag failed.");
548 return std::make_pair(result, tag);
551 RawBuffer encryptDataAesGcmPacked(
552 const RawBuffer &key,
553 const RawBuffer &data,
557 auto pair = encryptDataAesGcm(key, data, iv, tagSize);
558 std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first));
562 RawBuffer decryptDataAes(
564 const RawBuffer &key,
565 const RawBuffer &data,
569 selectCipher(type, key.size(), false)(dec, key, iv);
570 RawBuffer result = dec->Append(data);
571 RawBuffer tmp = dec->Finalize();
572 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
576 RawBuffer decryptDataAesGcm(
577 const RawBuffer &key,
578 const RawBuffer &data,
580 const RawBuffer &tag)
583 selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
584 void *ptr = (void*)tag.data();
585 if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) {
586 ThrowErr(Exc::Crypto::InternalError,
587 "Error in AES control function. Set tag failed.");
589 RawBuffer result = dec->Append(data);
590 RawBuffer tmp = dec->Finalize();
591 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
595 RawBuffer decryptDataAesGcmPacked(
596 const RawBuffer &key,
597 const RawBuffer &data,
601 if (tagSize > static_cast<int>(data.size()))
602 ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
604 auto tagPos = data.data() + data.size() - tagSize;
605 return decryptDataAesGcm(
607 RawBuffer(data.data(), tagPos),
609 RawBuffer(tagPos, data.data() + data.size()));
612 RawBuffer symmetricEncrypt(const RawBuffer &key,
613 const CryptoAlgorithm &alg,
614 const RawBuffer &data)
616 validateParams<IsEncryption>(alg);
617 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
621 case AlgoType::AES_CBC:
622 case AlgoType::AES_CTR:
623 case AlgoType::AES_CFB:
624 return encryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
625 case AlgoType::AES_GCM:
627 int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
628 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
629 return encryptDataAesGcmPacked(key,
631 unpack<RawBuffer>(alg, ParamName::ED_IV),
637 ThrowErr(Exc::Crypto::OperationNotSupported,
638 "symmetric enc error: algorithm not recognized");
641 RawBuffer symmetricDecrypt(const RawBuffer &key,
642 const CryptoAlgorithm &alg,
643 const RawBuffer &data)
645 validateParams<IsEncryption>(alg);
646 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
650 case AlgoType::AES_CBC:
651 case AlgoType::AES_CTR:
652 case AlgoType::AES_CFB:
653 return decryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
654 case AlgoType::AES_GCM:
656 int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
657 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
658 return decryptDataAesGcmPacked(key,
660 unpack<RawBuffer>(alg, ParamName::ED_IV),
666 ThrowErr(Exc::Crypto::InputParam, "symmetric dec error: algorithm not recognized");
669 RawBuffer sign(EVP_PKEY *pkey,
670 const CryptoAlgorithm &alg,
671 const RawBuffer &message)
673 validateParams<IsSignVerify>(alg);
675 int rsa_padding = NOT_DEFINED;
676 const EVP_MD *md_algo = NULL;
678 HashAlgorithm hashTmp = HashAlgorithm::NONE;
679 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
680 md_algo = getMdAlgo(hashTmp);
682 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
683 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
684 rsa_padding = getRsaPadding(rsaPad);
687 // if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
688 // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
689 // (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
691 // LogError("Error in private key type");
692 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
695 // if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
696 // rsa_padding = getRsaPadding(padAlgo);
700 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
703 if(md_algo == NULL) {
704 return signMessage(pkey, message, rsa_padding);
707 return digestSignMessage(pkey,message, md_algo, rsa_padding);
710 RawBuffer signMessage(EVP_PKEY *privKey,
711 const RawBuffer &message,
712 const int rsa_padding)
714 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
717 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
720 if(EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) {
721 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
724 /* Set padding algorithm */
725 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
726 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
727 ThrowErr(Exc::Crypto::InternalError,
728 "Error in EVP_PKEY_CTX_set_rsa_padding function");
732 /* Finalize the Sign operation */
733 /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
734 * signature. Length is returned in slen */
736 if(EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())) {
737 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function");
740 /* Allocate memory for the signature based on size in slen */
743 if(EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
749 // Set value to return RawData
754 ThrowErr(Exc::Crypto::InputParam, "Error in EVP_PKEY_sign function. Input param error.");
757 RawBuffer digestSignMessage(EVP_PKEY *privKey,
758 const RawBuffer &message,
759 const EVP_MD *md_algo,
760 const int rsa_padding)
762 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
764 EVP_PKEY_CTX *pctx = NULL;
766 // Create the Message Digest Context
768 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
771 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) {
772 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
775 /* Set padding algorithm */
776 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
777 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
778 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
782 /* Call update with the message */
783 if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())) {
784 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function");
787 /* Finalize the DigestSign operation */
788 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
789 * signature. Length is returned in slen */
791 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) {
792 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
795 /* Allocate memory for the signature based on size in slen */
798 /* Obtain the signature */
799 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) {
800 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
803 // Set value to return RawData
808 int verify(EVP_PKEY *pkey,
809 const CryptoAlgorithm &alg,
810 const RawBuffer &message,
811 const RawBuffer &signature)
813 validateParams<IsSignVerify>(alg);
815 int rsa_padding = NOT_DEFINED;
816 const EVP_MD *md_algo = NULL;
818 HashAlgorithm hashTmp = HashAlgorithm::NONE;
819 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
820 md_algo = getMdAlgo(hashTmp);
822 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
823 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
824 rsa_padding = getRsaPadding(rsaPad);
827 // if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
828 // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
829 // (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
831 // LogError("Error in private key type");
832 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
835 // if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
836 // rsa_padding = getRsaPadding(padAlgo);
839 // auto shrPKey = publicKey.getEvpShPtr();
841 ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
844 if (md_algo == NULL) {
845 return verifyMessage(pkey, message, signature, rsa_padding);
848 return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
851 int verifyMessage(EVP_PKEY *pubKey,
852 const RawBuffer &message,
853 const RawBuffer &signature,
854 const int rsa_padding)
856 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
859 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
862 if(EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) {
863 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
866 /* Set padding algorithm */
867 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
868 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
869 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
873 if(EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) {
874 return CKM_API_SUCCESS;
877 LogError("EVP_PKEY_verify Failed");
878 return CKM_API_ERROR_VERIFICATION_FAILED;
881 int digestVerifyMessage(EVP_PKEY *pubKey,
882 const RawBuffer &message,
883 const RawBuffer &signature,
884 const EVP_MD *md_algo,
885 const int rsa_padding)
887 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
888 EVP_PKEY_CTX *pctx = NULL;
890 /* Create the Message Digest Context */
892 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
895 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) {
896 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
899 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
900 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
901 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
905 if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()) ) {
906 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyUpdate function");
909 if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size()) ) {
910 return CKM_API_SUCCESS;
913 LogError("EVP_PKEY_verify Failed");
914 return CKM_API_ERROR_VERIFICATION_FAILED;
917 } // namespace Internals
919 } // namespace Crypto