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 typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr;
220 typedef std::function<void(EvpCipherPtr&, const RawBuffer& key, const RawBuffer& iv)> InitCipherFn;
222 // aes mode, key length in bits, encryption
223 typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> CipherTree;
225 template <typename T>
226 void initCipher(EvpCipherPtr& ptr, const RawBuffer& key, const RawBuffer& iv)
228 ptr.reset(new T(key, iv));
231 CipherTree initializeCipherTree()
234 tree[AlgoType::AES_CBC][128][true] = initCipher<Cipher::AesCbcEncryption128>;
235 tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>;
236 tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>;
238 tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>;
239 tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>;
240 tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>;
242 tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>;
243 tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>;
244 tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>;
246 tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>;
247 tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>;
248 tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>;
250 tree[AlgoType::AES_CTR][128][true] = initCipher<Cipher::AesCtrEncryption128>;
251 tree[AlgoType::AES_CTR][192][true] = initCipher<Cipher::AesCtrEncryption192>;
252 tree[AlgoType::AES_CTR][256][true] = initCipher<Cipher::AesCtrEncryption256>;
254 tree[AlgoType::AES_CTR][128][false] = initCipher<Cipher::AesCtrDecryption128>;
255 tree[AlgoType::AES_CTR][192][false] = initCipher<Cipher::AesCtrDecryption192>;
256 tree[AlgoType::AES_CTR][256][false] = initCipher<Cipher::AesCtrDecryption256>;
258 tree[AlgoType::AES_CFB][128][true] = initCipher<Cipher::AesCfbEncryption128>;
259 tree[AlgoType::AES_CFB][192][true] = initCipher<Cipher::AesCfbEncryption192>;
260 tree[AlgoType::AES_CFB][256][true] = initCipher<Cipher::AesCfbEncryption256>;
262 tree[AlgoType::AES_CFB][128][false] = initCipher<Cipher::AesCfbDecryption128>;
263 tree[AlgoType::AES_CFB][192][false] = initCipher<Cipher::AesCfbDecryption192>;
264 tree[AlgoType::AES_CFB][256][false] = initCipher<Cipher::AesCfbDecryption256>;
269 CipherTree g_cipherTree = initializeCipherTree();
271 // key length in bytes
272 InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = true)
275 return g_cipherTree.at(type).at(key_len*8).at(encryption);
276 } catch (const std::out_of_range&) {
277 ThrowErr(Exc::Crypto::InternalError,
278 "Unsupported cipher: ",
279 static_cast<int>(type), ", ",
285 } // anonymous namespace
291 // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms
292 ERR_load_crypto_strings();
293 OpenSSL_add_all_algorithms();
295 // initialize entropy
296 std::ifstream ifile(DEV_HW_RANDOM_FILE);
297 if(ifile.is_open()) {
298 u_rand_ret= RAND_load_file(DEV_HW_RANDOM_FILE, 32);
300 if(u_rand_ret != 32 ){
301 LogError("Error in HW_RAND file load");
302 hw_rand_ret = RAND_load_file(DEV_URANDOM_FILE, 32);
304 if(hw_rand_ret != 32) {
305 ThrowErr(Exc::Crypto::InternalError, "Error in U_RAND_file_load");
309 return CKM_CRYPTO_INIT_SUCCESS;
312 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) {
313 const EVP_MD *md_algo=NULL;
315 case HashAlgorithm::NONE:
318 case HashAlgorithm::SHA1:
319 md_algo = EVP_sha1();
321 case HashAlgorithm::SHA256:
322 md_algo = EVP_sha256();
324 case HashAlgorithm::SHA384:
325 md_algo = EVP_sha384();
327 case HashAlgorithm::SHA512:
328 md_algo = EVP_sha512();
331 ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value");
336 int getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
337 int rsa_padding = -1;
339 case RSAPaddingAlgorithm::NONE:
340 rsa_padding = RSA_NO_PADDING;
342 case RSAPaddingAlgorithm::PKCS1:
343 rsa_padding = RSA_PKCS1_PADDING;
345 case RSAPaddingAlgorithm::X931:
346 rsa_padding = RSA_X931_PADDING;
349 ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value");
354 TokenPair createKeyPairRSA(CryptoBackend backendId, const int size)
358 // check the parameters of functions
359 if(size!=1024 && size!=2048 && size!=4096) {
360 ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size");
363 EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free);
365 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!");
368 if(EVP_PKEY_keygen_init(ctx.get()) <= 0) {
369 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function !!");
372 if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) {
373 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
376 EVP_PKEY *pkeyTmp = NULL;
377 if(!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) {
378 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
380 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
382 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
383 Token(backendId, DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
387 TokenPair createKeyPairDSA(CryptoBackend backendId, const int size)
392 // check the parameters of functions
393 if(size!=1024 && size!=2048 && size!=3072 && size!=4096) {
394 ThrowErr(Exc::Crypto::InputParam, "Error in DSA input size");
397 /* Create the context for generating the parameters */
398 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free);
400 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
403 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
404 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
407 if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) {
408 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function");
411 /* Generate parameters */
412 EVP_PKEY *pparamTmp = NULL;
413 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
414 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
416 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
418 // Start to generate key
419 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
421 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
424 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
425 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
428 /* Generate the key */
429 EVP_PKEY *pkeyTmp = NULL;
430 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
431 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
433 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
435 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
436 Token(backendId, DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
439 TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type)
441 int ecCurve = NOT_DEFINED;
446 case ElipticCurve::prime192v1:
447 ecCurve = NID_X9_62_prime192v1;
449 case ElipticCurve::prime256v1:
450 ecCurve = NID_X9_62_prime256v1;
452 case ElipticCurve::secp384r1:
453 ecCurve = NID_secp384r1;
456 ThrowErr(Exc::Crypto::InputParam, "Error in EC type");
459 /* Create the context for generating the parameters */
460 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free);
462 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
465 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
466 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
469 if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) {
470 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
473 /* Generate parameters */
474 EVP_PKEY *pparamTmp = NULL;
475 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
476 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
478 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
480 // Start to generate key
481 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
483 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
486 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
487 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
490 /* Generate the key */
491 EVP_PKEY *pkeyTmp = NULL;
492 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
493 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
495 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
497 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
498 Token(backendId, DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
501 Token createKeyAES(CryptoBackend backendId, const int sizeBits)
503 // check the parameters of functions
504 if(sizeBits!=128 && sizeBits!=192 && sizeBits!=256) {
505 LogError("Error in AES input size");
506 ThrowMsg(Exc::Crypto::InputParam, "Error in AES input size");
510 int sizeBytes = sizeBits/8;
511 if (!RAND_bytes(key, sizeBytes)) {
512 LogError("Error in AES key generation");
513 ThrowMsg(Exc::Crypto::InternalError, "Error in AES key generation");
516 return Token(backendId, DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes));
519 TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
521 validateParams<IsAsymGeneration>(algorithm);
523 AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
524 if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
526 int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
527 if(keyType == AlgoType::RSA_GEN)
528 return createKeyPairRSA(backendId, keyLength);
530 return createKeyPairDSA(backendId, keyLength);
532 else // AlgoType::ECDSA_GEN
534 ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
535 return createKeyPairECDSA(backendId, ecType);
539 Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
541 validateParams<IsSymGeneration>(algorithm);
543 int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
544 return createKeyAES(backendId, keySizeBits);
547 RawBuffer encryptDataAes(
549 const RawBuffer &key,
550 const RawBuffer &data,
554 selectCipher(type, key.size())(enc, key, iv);
555 RawBuffer result = enc->Append(data);
556 RawBuffer tmp = enc->Finalize();
557 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
561 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
562 const RawBuffer &key,
563 const RawBuffer &data,
567 RawBuffer tag(tagSize);
569 selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv);
570 RawBuffer result = enc->Append(data);
571 RawBuffer tmp = enc->Finalize();
572 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
573 if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) {
574 ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Get tag failed.");
576 return std::make_pair(result, tag);
579 RawBuffer encryptDataAesGcmPacked(
580 const RawBuffer &key,
581 const RawBuffer &data,
585 auto pair = encryptDataAesGcm(key, data, iv, tagSize);
586 std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first));
590 RawBuffer decryptDataAes(
592 const RawBuffer &key,
593 const RawBuffer &data,
597 selectCipher(type, key.size(), false)(dec, key, iv);
598 RawBuffer result = dec->Append(data);
599 RawBuffer tmp = dec->Finalize();
600 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
604 RawBuffer decryptDataAesGcm(
605 const RawBuffer &key,
606 const RawBuffer &data,
608 const RawBuffer &tag)
611 selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
612 void *ptr = (void*)tag.data();
613 if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) {
614 ThrowErr(Exc::Crypto::InternalError,
615 "Error in AES control function. Set tag failed.");
617 RawBuffer result = dec->Append(data);
618 RawBuffer tmp = dec->Finalize();
619 std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
623 RawBuffer decryptDataAesGcmPacked(
624 const RawBuffer &key,
625 const RawBuffer &data,
629 if (tagSize > static_cast<int>(data.size()))
630 ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
632 auto tagPos = data.data() + data.size() - tagSize;
633 return decryptDataAesGcm(
635 RawBuffer(data.data(), tagPos),
637 RawBuffer(tagPos, data.data() + data.size()));
640 RawBuffer symmetricEncrypt(const RawBuffer &key,
641 const CryptoAlgorithm &alg,
642 const RawBuffer &data)
644 validateParams<IsEncryption>(alg);
645 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
649 case AlgoType::AES_CBC:
650 case AlgoType::AES_CTR:
651 case AlgoType::AES_CFB:
652 return encryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
653 case AlgoType::AES_GCM:
655 int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
656 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
657 return encryptDataAesGcmPacked(key,
659 unpack<RawBuffer>(alg, ParamName::ED_IV),
665 ThrowErr(Exc::Crypto::OperationNotSupported,
666 "symmetric enc error: algorithm not recognized");
669 RawBuffer symmetricDecrypt(const RawBuffer &key,
670 const CryptoAlgorithm &alg,
671 const RawBuffer &data)
673 validateParams<IsEncryption>(alg);
674 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
678 case AlgoType::AES_CBC:
679 case AlgoType::AES_CTR:
680 case AlgoType::AES_CFB:
681 return decryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
682 case AlgoType::AES_GCM:
684 int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
685 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
686 return decryptDataAesGcmPacked(key,
688 unpack<RawBuffer>(alg, ParamName::ED_IV),
694 ThrowErr(Exc::Crypto::InputParam, "symmetric dec error: algorithm not recognized");
697 RawBuffer sign(EVP_PKEY *pkey,
698 const CryptoAlgorithm &alg,
699 const RawBuffer &message)
701 validateParams<IsSignVerify>(alg);
703 int rsa_padding = NOT_DEFINED;
704 const EVP_MD *md_algo = NULL;
706 HashAlgorithm hashTmp = HashAlgorithm::NONE;
707 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
708 md_algo = getMdAlgo(hashTmp);
710 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
711 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
712 rsa_padding = getRsaPadding(rsaPad);
715 // if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
716 // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
717 // (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
719 // LogError("Error in private key type");
720 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
723 // if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
724 // rsa_padding = getRsaPadding(padAlgo);
728 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
731 if(md_algo == NULL) {
732 return signMessage(pkey, message, rsa_padding);
735 return digestSignMessage(pkey,message, md_algo, rsa_padding);
738 RawBuffer signMessage(EVP_PKEY *privKey,
739 const RawBuffer &message,
740 const int rsa_padding)
742 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
745 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
748 if(EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) {
749 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
752 /* Set padding algorithm */
753 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
754 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
755 ThrowErr(Exc::Crypto::InternalError,
756 "Error in EVP_PKEY_CTX_set_rsa_padding function");
760 /* Finalize the Sign operation */
761 /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
762 * signature. Length is returned in slen */
764 if(EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())) {
765 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function");
768 /* Allocate memory for the signature based on size in slen */
771 if(EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
777 // Set value to return RawData
782 ThrowErr(Exc::Crypto::InputParam, "Error in EVP_PKEY_sign function. Input param error.");
785 RawBuffer digestSignMessage(EVP_PKEY *privKey,
786 const RawBuffer &message,
787 const EVP_MD *md_algo,
788 const int rsa_padding)
790 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
792 EVP_PKEY_CTX *pctx = NULL;
794 // Create the Message Digest Context
796 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
799 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) {
800 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
803 /* Set padding algorithm */
804 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
805 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
806 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
810 /* Call update with the message */
811 if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())) {
812 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function");
815 /* Finalize the DigestSign operation */
816 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
817 * signature. Length is returned in slen */
819 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) {
820 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
823 /* Allocate memory for the signature based on size in slen */
826 /* Obtain the signature */
827 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) {
828 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
831 // Set value to return RawData
836 int verify(EVP_PKEY *pkey,
837 const CryptoAlgorithm &alg,
838 const RawBuffer &message,
839 const RawBuffer &signature)
841 validateParams<IsSignVerify>(alg);
843 int rsa_padding = NOT_DEFINED;
844 const EVP_MD *md_algo = NULL;
846 HashAlgorithm hashTmp = HashAlgorithm::NONE;
847 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
848 md_algo = getMdAlgo(hashTmp);
850 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
851 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
852 rsa_padding = getRsaPadding(rsaPad);
855 // if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
856 // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
857 // (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
859 // LogError("Error in private key type");
860 // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
863 // if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
864 // rsa_padding = getRsaPadding(padAlgo);
867 // auto shrPKey = publicKey.getEvpShPtr();
869 ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
872 if (md_algo == NULL) {
873 return verifyMessage(pkey, message, signature, rsa_padding);
876 return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
879 int verifyMessage(EVP_PKEY *pubKey,
880 const RawBuffer &message,
881 const RawBuffer &signature,
882 const int rsa_padding)
884 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
887 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
890 if(EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) {
891 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
894 /* Set padding algorithm */
895 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
896 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
897 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
901 if(EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) {
902 return CKM_API_SUCCESS;
905 LogError("EVP_PKEY_verify Failed");
906 return CKM_API_ERROR_VERIFICATION_FAILED;
909 int digestVerifyMessage(EVP_PKEY *pubKey,
910 const RawBuffer &message,
911 const RawBuffer &signature,
912 const EVP_MD *md_algo,
913 const int rsa_padding)
915 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
916 EVP_PKEY_CTX *pctx = NULL;
918 /* Create the Message Digest Context */
920 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
923 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) {
924 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
927 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
928 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
929 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
933 if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()) ) {
934 ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyUpdate function");
937 if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size()) ) {
938 return CKM_API_SUCCESS;
941 LogError("EVP_PKEY_verify Failed");
942 return CKM_API_ERROR_VERIFICATION_FAILED;
945 } // namespace Internals
947 } // namespace Crypto