Add RSA OAEP support
[platform/core/security/key-manager.git] / src / manager / crypto / sw-backend / internals.cpp
1 /*
2  *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /*
17  * @file       internals.cpp
18  * @author
19  * @version    1.0
20  */
21 #include <exception>
22 #include <utility>
23 #include <algorithm>
24
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>
36
37 #include <ckm/ckm-error.h>
38 #include <assert.h>
39 #include <dpl/log/log.h>
40
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>
45
46 #define OPENSSL_SUCCESS 1       // DO NOTCHANGE THIS VALUE
47 #define OPENSSL_FAIL    0       // DO NOTCHANGE THIS VALUE
48
49 namespace CKM {
50 namespace Crypto {
51 namespace SW {
52 namespace Internals {
53
54 namespace {
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;
58
59 typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
60 typedef int(*I2D_CONV)(BIO*, EVP_PKEY*);
61
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
64
65 RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
66     BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
67
68     if (NULL == pkey) {
69         ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
70     }
71
72     if (NULL == bio.get()) {
73         ThrowErr(Exc::Crypto::InternalError, "Error in memory allocation! Function: BIO_new.");
74     }
75
76     if (1 != fun(bio.get(), pkey)) {
77         ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
78     }
79
80     RawBuffer output(8196);
81
82     int size = BIO_read(bio.get(), output.data(), output.size());
83
84     if (size <= 0) {
85         ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
86     }
87
88     output.resize(size);
89     return output;
90 }
91
92 // encryption / decryption
93 typedef ParamCheck<ParamName::ALGO_TYPE,
94                    AlgoType,
95                    true,
96                    Type<AlgoType>::Equals<AlgoType::AES_CTR,
97                                           AlgoType::AES_CBC,
98                                           AlgoType::AES_GCM,
99                                           AlgoType::AES_CFB>> IsSymEncryption;
100
101 typedef ParamCheck<ParamName::ALGO_TYPE,
102                    AlgoType,
103                    true,
104                    Type<AlgoType>::Equals<AlgoType::RSA_OAEP>> IsAsymEncryption;
105
106 typedef ParamCheck<ParamName::ED_IV,
107                    RawBuffer,
108                    true,
109                    Type<size_t>::Equals<DEFAULT_AES_IV_LEN>,
110                    BufferSizeGetter> IvSizeCheck;
111
112 typedef ParamCheck<ParamName::ED_CTR_LEN,
113                    int,
114                    false,
115                    Type<int>::Equals<128>> CtrLenCheck;
116
117 typedef ParamCheck<ParamName::ED_IV,
118                    RawBuffer,
119                    true,
120                    DefaultValidator<RawBuffer>> GcmIvCheck;
121
122 typedef ParamCheck<ParamName::ED_TAG_LEN,
123                    int,
124                    false,
125                    Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck;
126
127 typedef ParamCheck<ParamName::ED_LABEL,
128                    RawBuffer,
129                    false,
130                    Unsupported<RawBuffer>> RsaLabelCheck;
131
132 // sign / verify
133 typedef ParamCheck<ParamName::ALGO_TYPE,
134                    AlgoType,
135                    false,
136                    Type<AlgoType>::Equals<AlgoType::RSA_SV,
137                                           AlgoType::DSA_SV,
138                                           AlgoType::ECDSA_SV>> IsSignVerify;
139
140 typedef ParamCheck<ParamName::SV_HASH_ALGO,
141                    HashAlgorithm,
142                    false,
143                    Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
144                                                HashAlgorithm::SHA1,
145                                                HashAlgorithm::SHA256,
146                                                HashAlgorithm::SHA384,
147                                                HashAlgorithm::SHA512>> HashAlgoCheck;
148
149 typedef ParamCheck<ParamName::SV_RSA_PADDING,
150                    RSAPaddingAlgorithm,
151                    false,
152                    Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
153                                                      RSAPaddingAlgorithm::PKCS1,
154                                                      RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
155
156 // key generation
157 typedef ParamCheck<ParamName::ALGO_TYPE,
158                    AlgoType,
159                    true,
160                    Type<AlgoType>::Equals<AlgoType::RSA_GEN,
161                                           AlgoType::DSA_GEN,
162                                           AlgoType::ECDSA_GEN>> IsAsymGeneration;
163
164 typedef ParamCheck<ParamName::ALGO_TYPE,
165                    AlgoType,
166                    true,
167                    Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
168
169 typedef ParamCheck<ParamName::GEN_KEY_LEN,
170                    int,
171                    true,
172                    Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
173
174 typedef ParamCheck<ParamName::GEN_KEY_LEN,
175                    int,
176                    true,
177                    Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
178
179 typedef ParamCheck<ParamName::GEN_KEY_LEN,
180                    int,
181                    true,
182                    Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
183
184 typedef ParamCheck<ParamName::GEN_EC,
185                    ElipticCurve,
186                    true,
187                    Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
188                                               ElipticCurve::prime256v1,
189                                               ElipticCurve::secp384r1>> EcdsaEcCheck;
190
191 typedef std::map<AlgoType, ValidatorVector> ValidatorMap;
192 ValidatorMap initValidators() {
193     ValidatorMap validators;
194     validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
195     validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
196     validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build());
197     validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build());
198     validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build());
199     validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build());
200     validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build());
201     validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build());
202     validators.emplace(AlgoType::AES_CTR, VBuilder<IvSizeCheck, CtrLenCheck>::Build());
203     validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build());
204     validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build());
205     validators.emplace(AlgoType::AES_GCM, VBuilder<GcmIvCheck, GcmTagCheck>::Build());
206     validators.emplace(AlgoType::RSA_OAEP, VBuilder<RsaLabelCheck>::Build());
207     return validators;
208 };
209 ValidatorMap g_validators = initValidators();
210
211 template <typename TypeCheck>
212 void validateParams(const CryptoAlgorithm& ca)
213 {
214     // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
215     TypeCheck tc;
216     tc.Check(ca);
217
218     AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
219     try {
220         for(const auto& validator : g_validators.at(at))
221             validator->Check(ca);
222     } catch(const std::out_of_range&) {
223         ThrowErr(Exc::Crypto::InputParam, "Unsupported algorithm ", static_cast<int>(at));
224     }
225 }
226
227 typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr;
228
229 typedef std::function<void(EvpCipherPtr&, const RawBuffer& key, const RawBuffer& iv)> InitCipherFn;
230
231 // aes mode, key length in bits, encryption
232 typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> CipherTree;
233
234 template <typename T>
235 void initCipher(EvpCipherPtr& ptr, const RawBuffer& key, const RawBuffer& iv)
236 {
237     ptr.reset(new T(key, iv));
238 }
239
240 CipherTree initializeCipherTree()
241 {
242     CipherTree tree;
243     tree[AlgoType::AES_CBC][128][true] = initCipher<Cipher::AesCbcEncryption128>;
244     tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>;
245     tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>;
246
247     tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>;
248     tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>;
249     tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>;
250
251     tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>;
252     tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>;
253     tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>;
254
255     tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>;
256     tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>;
257     tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>;
258
259     tree[AlgoType::AES_CTR][128][true] = initCipher<Cipher::AesCtrEncryption128>;
260     tree[AlgoType::AES_CTR][192][true] = initCipher<Cipher::AesCtrEncryption192>;
261     tree[AlgoType::AES_CTR][256][true] = initCipher<Cipher::AesCtrEncryption256>;
262
263     tree[AlgoType::AES_CTR][128][false] = initCipher<Cipher::AesCtrDecryption128>;
264     tree[AlgoType::AES_CTR][192][false] = initCipher<Cipher::AesCtrDecryption192>;
265     tree[AlgoType::AES_CTR][256][false] = initCipher<Cipher::AesCtrDecryption256>;
266
267     tree[AlgoType::AES_CFB][128][true] = initCipher<Cipher::AesCfbEncryption128>;
268     tree[AlgoType::AES_CFB][192][true] = initCipher<Cipher::AesCfbEncryption192>;
269     tree[AlgoType::AES_CFB][256][true] = initCipher<Cipher::AesCfbEncryption256>;
270
271     tree[AlgoType::AES_CFB][128][false] = initCipher<Cipher::AesCfbDecryption128>;
272     tree[AlgoType::AES_CFB][192][false] = initCipher<Cipher::AesCfbDecryption192>;
273     tree[AlgoType::AES_CFB][256][false] = initCipher<Cipher::AesCfbDecryption256>;
274
275     return tree;
276 }
277
278 CipherTree g_cipherTree = initializeCipherTree();
279
280 // key length in bytes
281 InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = true)
282 {
283     try {
284         return g_cipherTree.at(type).at(key_len*8).at(encryption);
285     } catch (const std::out_of_range&) {
286         ThrowErr(Exc::Crypto::InternalError,
287                  "Unsupported cipher: ",
288                  static_cast<int>(type), ", ",
289                  key_len, ", ",
290                  encryption);
291     }
292 }
293
294
295 RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char*, unsigned char*, RSA*, int),
296                            const std::string logPrefix,
297                            const EvpShPtr &pkey,
298                            const CryptoAlgorithm &alg,
299                            const RawBuffer &data)
300 {
301     validateParams<IsAsymEncryption>(alg);
302
303     RSA* rsa = EVP_PKEY_get1_RSA(pkey.get());
304     if (!rsa)
305         ThrowErr(Exc::Crypto::InputParam, logPrefix, "invalid key");
306
307     /*
308      * RSA_padding_add_PKCS1_OAEP supports custom label but RSA_public_encrypt calls it with NULL
309      * value so for now label is not supported. Alternative is to rewrite the openssl implementation
310      * to support it: openssl-fips/crypto/rsa/rsa_eay.c
311      */
312     RawBuffer output;
313     output.resize(RSA_size(rsa));
314     int ret = cryptoFn(data.size(),
315                    data.data(),
316                    output.data(),
317                    rsa,
318                    RSA_PKCS1_OAEP_PADDING);
319     RSA_free(rsa);
320     if (ret < 0)
321         ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed");
322
323     output.resize(ret);
324     return output;
325 }
326
327 } // anonymous namespace
328
329 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) {
330     const EVP_MD *md_algo=NULL;
331     switch(hashAlgo) {
332     case HashAlgorithm::NONE:
333         md_algo = NULL;
334         break;
335     case HashAlgorithm::SHA1:
336         md_algo = EVP_sha1();
337          break;
338     case HashAlgorithm::SHA256:
339          md_algo = EVP_sha256();
340          break;
341     case HashAlgorithm::SHA384:
342          md_algo = EVP_sha384();
343          break;
344     case HashAlgorithm::SHA512:
345          md_algo = EVP_sha512();
346          break;
347     default:
348         ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value");
349     }
350     return md_algo;
351 }
352
353 int getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
354     int rsa_padding = -1;
355     switch(padAlgo) {
356     case RSAPaddingAlgorithm::NONE:
357         rsa_padding = RSA_NO_PADDING;
358         break;
359     case RSAPaddingAlgorithm::PKCS1:
360         rsa_padding = RSA_PKCS1_PADDING;
361         break;
362     case RSAPaddingAlgorithm::X931:
363         rsa_padding = RSA_X931_PADDING;
364         break;
365     default:
366         ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value");
367     }
368     return rsa_padding;
369 }
370
371 TokenPair createKeyPairRSA(CryptoBackend backendId, const int size)
372 {
373     EvpPkeyUPtr pkey;
374
375     // check the parameters of functions
376     if(size!=1024 && size!=2048 && size!=4096) {
377         ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size");
378     }
379
380     EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free);
381     if(!ctx) {
382         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!");
383     }
384
385     if(EVP_PKEY_keygen_init(ctx.get()) <= 0) {
386         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function !!");
387     }
388
389     if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) {
390         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
391     }
392
393     EVP_PKEY *pkeyTmp = NULL;
394     if(!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) {
395         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
396     }
397     pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
398
399     return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
400                                         Token(backendId, DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
401 }
402
403
404 TokenPair createKeyPairDSA(CryptoBackend backendId, const int size)
405 {
406     EvpPkeyUPtr pkey;
407     EvpPkeyUPtr pparam;
408
409     // check the parameters of functions
410     if(size!=1024 && size!=2048 && size!=3072 && size!=4096) {
411         ThrowErr(Exc::Crypto::InputParam, "Error in DSA input size");
412     }
413
414     /* Create the context for generating the parameters */
415     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free);
416     if(!pctx) {
417         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
418     }
419
420     if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
421         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
422     }
423
424     if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) {
425         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function");
426     }
427
428     /* Generate parameters */
429     EVP_PKEY *pparamTmp = NULL;
430     if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
431         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
432     }
433     pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
434
435     // Start to generate key
436     EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
437     if(!kctx) {
438         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
439     }
440
441     if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
442         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
443     }
444
445     /* Generate the key */
446     EVP_PKEY *pkeyTmp = NULL;
447     if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
448         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
449     }
450     pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
451
452     return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
453                                         Token(backendId, DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
454 }
455
456 TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type)
457 {
458     int ecCurve = NOT_DEFINED;
459     EvpPkeyUPtr pkey;
460     EvpPkeyUPtr pparam;
461
462     switch(type) {
463     case ElipticCurve::prime192v1:
464         ecCurve = NID_X9_62_prime192v1;
465         break;
466     case ElipticCurve::prime256v1:
467         ecCurve = NID_X9_62_prime256v1;
468         break;
469     case ElipticCurve::secp384r1:
470         ecCurve = NID_secp384r1;
471         break;
472     default:
473         ThrowErr(Exc::Crypto::InputParam, "Error in EC type");
474     }
475
476     /* Create the context for generating the parameters */
477     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free);
478     if(!pctx) {
479         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
480     }
481
482     if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
483         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
484     }
485
486     if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) {
487         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
488     }
489
490     /* Generate parameters */
491     EVP_PKEY *pparamTmp = NULL;
492     if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
493         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
494     }
495     pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
496
497     // Start to generate key
498     EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
499     if(!kctx) {
500         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
501     }
502
503     if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
504         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
505     }
506
507     /* Generate the key */
508     EVP_PKEY *pkeyTmp = NULL;
509     if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
510         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
511     }
512     pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
513
514     return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
515                                         Token(backendId, DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
516 }
517
518 Token createKeyAES(CryptoBackend backendId, const int sizeBits)
519 {
520     // check the parameters of functions
521     if(sizeBits!=128 && sizeBits!=192 && sizeBits!=256) {
522         LogError("Error in AES input size");
523         ThrowMsg(Exc::Crypto::InputParam, "Error in AES input size");
524     }
525
526     uint8_t key[32];
527     int sizeBytes = sizeBits/8;
528     if (!RAND_bytes(key, sizeBytes)) {
529         LogError("Error in AES key generation");
530         ThrowMsg(Exc::Crypto::InternalError, "Error in AES key generation");
531     }
532
533     return Token(backendId, DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes));
534 }
535
536 TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
537 {
538     validateParams<IsAsymGeneration>(algorithm);
539
540     AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
541     if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
542     {
543         int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
544         if(keyType == AlgoType::RSA_GEN)
545             return createKeyPairRSA(backendId, keyLength);
546         else
547             return createKeyPairDSA(backendId, keyLength);
548     }
549     else // AlgoType::ECDSA_GEN
550     {
551         ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
552         return createKeyPairECDSA(backendId, ecType);
553     }
554 }
555
556 Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
557 {
558     validateParams<IsSymGeneration>(algorithm);
559
560     int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
561     return createKeyAES(backendId, keySizeBits);
562 }
563
564 RawBuffer encryptDataAes(
565     AlgoType type,
566     const RawBuffer &key,
567     const RawBuffer &data,
568     const RawBuffer &iv)
569 {
570     EvpCipherPtr enc;
571     selectCipher(type, key.size())(enc, key, iv);
572     RawBuffer result = enc->Append(data);
573     RawBuffer tmp = enc->Finalize();
574     std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
575     return result;
576 }
577
578 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
579     const RawBuffer &key,
580     const RawBuffer &data,
581     const RawBuffer &iv,
582     int tagSize,
583     const RawBuffer &aad)
584 {
585     RawBuffer tag(tagSize);
586     EvpCipherPtr enc;
587     selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv);
588
589     if (!aad.empty())
590         enc->AppendAAD(aad);
591
592     RawBuffer result = enc->Append(data);
593     RawBuffer tmp = enc->Finalize();
594     std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
595     if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) {
596         ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Get tag failed.");
597     }
598     return std::make_pair(result, tag);
599 }
600
601 RawBuffer encryptDataAesGcmPacked(
602     const RawBuffer &key,
603     const RawBuffer &data,
604     const RawBuffer &iv,
605     int tagSize,
606     const RawBuffer &aad)
607 {
608     auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad);
609     std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first));
610     return pair.first;
611 }
612
613 RawBuffer decryptDataAes(
614     AlgoType type,
615     const RawBuffer &key,
616     const RawBuffer &data,
617     const RawBuffer &iv)
618 {
619     EvpCipherPtr dec;
620     selectCipher(type, key.size(), false)(dec, key, iv);
621     RawBuffer result = dec->Append(data);
622     RawBuffer tmp = dec->Finalize();
623     std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
624     return result;
625 }
626
627 RawBuffer decryptDataAesGcm(
628     const RawBuffer &key,
629     const RawBuffer &data,
630     const RawBuffer &iv,
631     const RawBuffer &tag,
632     const RawBuffer &aad)
633 {
634     EvpCipherPtr dec;
635     selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
636     void *ptr = (void*)tag.data();
637     if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) {
638         ThrowErr(Exc::Crypto::InternalError,
639             "Error in AES control function. Set tag failed.");
640     }
641     if (!aad.empty())
642         dec->AppendAAD(aad);
643
644     RawBuffer result = dec->Append(data);
645     RawBuffer tmp = dec->Finalize();
646     std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
647     return result;
648 }
649
650 RawBuffer decryptDataAesGcmPacked(
651     const RawBuffer &key,
652     const RawBuffer &data,
653     const RawBuffer &iv,
654     int tagSize,
655     const RawBuffer &aad)
656 {
657     if (tagSize > static_cast<int>(data.size()))
658         ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
659
660     auto tagPos = data.data() + data.size() - tagSize;
661     return decryptDataAesGcm(
662         key,
663         RawBuffer(data.data(), tagPos),
664         iv,
665         RawBuffer(tagPos, data.data() + data.size()),
666         aad);
667 }
668
669 RawBuffer symmetricEncrypt(const RawBuffer &key,
670                            const CryptoAlgorithm &alg,
671                            const RawBuffer &data)
672 {
673     validateParams<IsSymEncryption>(alg);
674     AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
675
676     switch(keyType)
677     {
678         case AlgoType::AES_CBC:
679         case AlgoType::AES_CTR:
680         case AlgoType::AES_CFB:
681             return encryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
682         case AlgoType::AES_GCM:
683         {
684             int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
685             alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
686             RawBuffer aad;
687             alg.getParam(ParamName::ED_AAD, aad);
688             return encryptDataAesGcmPacked(key,
689                                            data,
690                                            unpack<RawBuffer>(alg, ParamName::ED_IV),
691                                            tagLenBits/8,
692                                            aad);
693         }
694         default:
695             break;
696     }
697     ThrowErr(Exc::Crypto::OperationNotSupported, "symmetric enc: algorithm not recognized");
698 }
699
700 RawBuffer symmetricDecrypt(const RawBuffer &key,
701                            const CryptoAlgorithm &alg,
702                            const RawBuffer &data)
703 {
704     validateParams<IsSymEncryption>(alg);
705     AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
706
707     switch(keyType)
708     {
709         case AlgoType::AES_CBC:
710         case AlgoType::AES_CTR:
711         case AlgoType::AES_CFB:
712             return decryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
713         case AlgoType::AES_GCM:
714         {
715             int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
716             alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
717             RawBuffer aad;
718             alg.getParam(ParamName::ED_AAD, aad);
719             return decryptDataAesGcmPacked(key,
720                                            data,
721                                            unpack<RawBuffer>(alg, ParamName::ED_IV),
722                                            tagLenBits/8,
723                                            aad);
724         }
725         default:
726             break;
727     }
728     ThrowErr(Exc::Crypto::InputParam, "symmetric dec: algorithm not recognized");
729 }
730
731 RawBuffer asymmetricEncrypt(const EvpShPtr &pkey,
732                             const CryptoAlgorithm &alg,
733                             const RawBuffer &data)
734 {
735     return asymmetricHelper(RSA_public_encrypt, "Asymmetric encryption: ", pkey, alg, data);
736 }
737
738 RawBuffer asymmetricDecrypt(const EvpShPtr &pkey,
739                             const CryptoAlgorithm &alg,
740                             const RawBuffer &data)
741 {
742     return asymmetricHelper(RSA_private_decrypt, "Asymmetric decryption: ", pkey, alg, data);
743 }
744
745 RawBuffer sign(EVP_PKEY *pkey,
746     const CryptoAlgorithm &alg,
747     const RawBuffer &message)
748 {
749     validateParams<IsSignVerify>(alg);
750
751     int rsa_padding = NOT_DEFINED;
752     const EVP_MD *md_algo = NULL;
753
754     HashAlgorithm hashTmp = HashAlgorithm::NONE;
755     alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
756     md_algo = getMdAlgo(hashTmp);
757
758     RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
759     alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
760     rsa_padding = getRsaPadding(rsaPad);
761
762 //
763 //    if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
764 //       (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
765 //       (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
766 //    {
767 //        LogError("Error in private key type");
768 //        ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
769 //    }
770 //
771 //    if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
772 //        rsa_padding = getRsaPadding(padAlgo);
773 //    }
774
775     if (NULL == pkey) {
776         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
777     }
778
779     if(md_algo == NULL) {
780         return signMessage(pkey, message, rsa_padding);
781     }
782
783     return digestSignMessage(pkey,message, md_algo, rsa_padding);
784 }
785
786 RawBuffer signMessage(EVP_PKEY *privKey,
787         const RawBuffer &message,
788         const int rsa_padding)
789 {
790     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
791  
792     if(!pctx.get()) {
793         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
794     }
795
796     if(EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) {
797         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
798     }
799
800     /* Set padding algorithm */
801     if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
802         if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
803             ThrowErr(Exc::Crypto::InternalError,
804                      "Error in EVP_PKEY_CTX_set_rsa_padding function");
805         }
806     }
807
808     /* Finalize the Sign operation */
809     /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
810      * signature. Length is returned in slen */
811     size_t slen;
812     if(EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())) {
813         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function");
814     }
815
816     /* Allocate memory for the signature based on size in slen */
817     RawBuffer sig(slen);
818
819     if(EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
820                                     sig.data(),
821                                     &slen,
822                                     message.data(),
823                                     message.size()))
824     {
825         // Set value to return RawData
826         sig.resize(slen);
827         return sig;
828     }
829
830     ThrowErr(Exc::Crypto::InputParam, "Error in EVP_PKEY_sign function. Input param error.");
831 }
832
833 RawBuffer digestSignMessage(EVP_PKEY *privKey,
834         const RawBuffer &message,
835         const EVP_MD *md_algo,
836         const int rsa_padding)
837 {
838     EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
839  
840     EVP_PKEY_CTX *pctx = NULL;
841
842     // Create the Message Digest Context
843     if(!mdctx.get()) {
844         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
845     }
846
847     if(EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) {
848         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
849     }
850
851     /* Set padding algorithm */
852     if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
853         if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
854             ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
855         }
856     }
857
858     /* Call update with the message */
859     if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())) {
860         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function");
861     }
862
863     /* Finalize the DigestSign operation */
864     /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
865      * signature. Length is returned in slen */
866     size_t slen;
867     if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) {
868         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
869     }
870
871     /* Allocate memory for the signature based on size in slen */
872     RawBuffer sig(slen);
873
874     /* Obtain the signature */
875     if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) {
876         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
877     }
878
879     // Set value to return RawData
880     sig.resize(slen);
881     return sig;
882 }
883
884 int verify(EVP_PKEY *pkey,
885     const CryptoAlgorithm &alg,
886     const RawBuffer &message,
887     const RawBuffer &signature)
888 {
889     validateParams<IsSignVerify>(alg);
890
891     int rsa_padding = NOT_DEFINED;
892     const EVP_MD *md_algo = NULL;
893
894     HashAlgorithm hashTmp = HashAlgorithm::NONE;
895     alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
896     md_algo = getMdAlgo(hashTmp);
897
898     RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
899     alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
900     rsa_padding = getRsaPadding(rsaPad);
901
902 //
903 //    if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
904 //       (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
905 //       (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
906 //    {
907 //        LogError("Error in private key type");
908 //        ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
909 //    }
910 //
911 //    if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
912 //        rsa_padding = getRsaPadding(padAlgo);
913 //    }
914
915 //    auto shrPKey = publicKey.getEvpShPtr();
916     if (NULL == pkey) {
917         ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
918     }
919
920     if (md_algo == NULL) {
921         return verifyMessage(pkey, message, signature, rsa_padding);
922     }
923
924     return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
925 }
926
927 int verifyMessage(EVP_PKEY *pubKey,
928         const RawBuffer &message,
929         const RawBuffer &signature,
930         const int rsa_padding)
931 {
932     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
933
934     if(!pctx.get()) {
935         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
936     }
937
938     if(EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) {
939         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
940     }
941
942     /* Set padding algorithm  */
943     if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
944         if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
945             ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
946         }
947     }
948
949     if(EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) {
950         return CKM_API_SUCCESS;
951     } 
952
953     LogError("EVP_PKEY_verify Failed");
954     return CKM_API_ERROR_VERIFICATION_FAILED;
955 }
956
957 int digestVerifyMessage(EVP_PKEY *pubKey,
958         const RawBuffer &message,
959         const RawBuffer &signature,
960         const EVP_MD *md_algo,
961         const int rsa_padding)
962 {
963     EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
964     EVP_PKEY_CTX *pctx = NULL;
965
966     /* Create the Message Digest Context */
967     if(!mdctx.get()) {
968         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
969     }
970
971     if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) {
972         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
973     }
974
975     if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
976         if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
977             ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
978         }
979     }
980
981     if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()) ) {
982         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyUpdate function");
983     }
984
985     if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size()) ) {
986         return CKM_API_SUCCESS;
987     }
988
989     LogError("EVP_PKEY_verify Failed");
990     return CKM_API_ERROR_VERIFICATION_FAILED;
991 }
992
993 } // namespace Internals
994 } // namespace SW
995 } // namespace Crypto
996 } // namespace CKM