ad646fb6d1ff5962422fa0737298d027765b5bf0
[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 <fstream>
23 #include <utility>
24 #include <algorithm>
25
26 #include <openssl/evp.h>
27 #include <openssl/obj_mac.h>
28 #include <openssl/ec.h>
29 #include <openssl/dsa.h>
30 #include <openssl/rsa.h>
31 #include <openssl/bio.h>
32 #include <openssl/rand.h>
33 #include <openssl/crypto.h>
34 #include <openssl/err.h>
35 #include <openssl/x509v3.h>
36 #include <openssl/obj_mac.h>
37
38 #include <ckm/ckm-error.h>
39 #include <assert.h>
40 #include <dpl/log/log.h>
41
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>
46
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"
51
52 namespace CKM {
53 namespace Crypto {
54 namespace SW {
55 namespace Internals {
56
57 namespace {
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;
61
62 typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
63 typedef int(*I2D_CONV)(BIO*, EVP_PKEY*);
64
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
67
68 RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
69     BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
70
71     if (NULL == pkey) {
72         ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
73     }
74
75     if (NULL == bio.get()) {
76         ThrowErr(Exc::Crypto::InternalError, "Error in memory allocation! Function: BIO_new.");
77     }
78
79     if (1 != fun(bio.get(), pkey)) {
80         ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
81     }
82
83     RawBuffer output(8196);
84
85     int size = BIO_read(bio.get(), output.data(), output.size());
86
87     if (size <= 0) {
88         ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
89     }
90
91     output.resize(size);
92     return output;
93 }
94
95 // encryption / decryption
96 typedef ParamCheck<ParamName::ALGO_TYPE,
97                    AlgoType,
98                    true,
99                    Type<AlgoType>::Equals<AlgoType::AES_CTR,
100                                           AlgoType::AES_CBC,
101                                           AlgoType::AES_GCM,
102                                           AlgoType::AES_CFB,
103                                           AlgoType::RSA_OAEP>> IsEncryption;
104
105 typedef ParamCheck<ParamName::ED_IV,
106                    RawBuffer,
107                    true,
108                    Type<size_t>::Equals<DEFAULT_AES_IV_LEN>,
109                    BufferSizeGetter> IvSizeCheck;
110
111 typedef ParamCheck<ParamName::ED_CTR_LEN,
112                    int,
113                    false,
114                    Type<int>::Equals<128>> CtrLenCheck;
115
116 typedef ParamCheck<ParamName::ED_IV,
117                    RawBuffer,
118                    true,
119                    DefaultValidator<size_t>,
120                    BufferSizeGetter> 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 // sign / verify
128 typedef ParamCheck<ParamName::ALGO_TYPE,
129                    AlgoType,
130                    false,
131                    Type<AlgoType>::Equals<AlgoType::RSA_SV,
132                                           AlgoType::DSA_SV,
133                                           AlgoType::ECDSA_SV>> IsSignVerify;
134
135 typedef ParamCheck<ParamName::SV_HASH_ALGO,
136                    HashAlgorithm,
137                    false,
138                    Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
139                                                HashAlgorithm::SHA1,
140                                                HashAlgorithm::SHA256,
141                                                HashAlgorithm::SHA384,
142                                                HashAlgorithm::SHA512>> HashAlgoCheck;
143
144 typedef ParamCheck<ParamName::SV_RSA_PADDING,
145                    RSAPaddingAlgorithm,
146                    false,
147                    Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
148                                                      RSAPaddingAlgorithm::PKCS1,
149                                                      RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
150
151 // key generation
152 typedef ParamCheck<ParamName::ALGO_TYPE,
153                    AlgoType,
154                    true,
155                    Type<AlgoType>::Equals<AlgoType::RSA_GEN,
156                                           AlgoType::DSA_GEN,
157                                           AlgoType::ECDSA_GEN>> IsAsymGeneration;
158
159 typedef ParamCheck<ParamName::ALGO_TYPE,
160                    AlgoType,
161                    true,
162                    Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
163
164 typedef ParamCheck<ParamName::GEN_KEY_LEN,
165                    int,
166                    true,
167                    Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
168
169 typedef ParamCheck<ParamName::GEN_KEY_LEN,
170                    int,
171                    true,
172                    Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
173
174 typedef ParamCheck<ParamName::GEN_KEY_LEN,
175                    int,
176                    true,
177                    Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
178
179 typedef ParamCheck<ParamName::GEN_EC,
180                    ElipticCurve,
181                    true,
182                    Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
183                                               ElipticCurve::prime256v1,
184                                               ElipticCurve::secp384r1>> EcdsaEcCheck;
185
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());
201     return validators;
202 };
203 ValidatorMap g_validators = initValidators();
204
205 template <typename TypeCheck>
206 void validateParams(const CryptoAlgorithm& ca)
207 {
208     // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
209     TypeCheck tc;
210     tc.Check(ca);
211
212     AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
213     for(const auto& validator : g_validators.at(at)) {
214         validator->Check(ca);
215     }
216 }
217
218 typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr;
219
220 typedef std::function<void(EvpCipherPtr&, const RawBuffer& key, const RawBuffer& iv)> InitCipherFn;
221
222 // aes mode, key length in bits, encryption
223 typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> CipherTree;
224
225 template <typename T>
226 void initCipher(EvpCipherPtr& ptr, const RawBuffer& key, const RawBuffer& iv)
227 {
228     ptr.reset(new T(key, iv));
229 }
230
231 CipherTree initializeCipherTree()
232 {
233     CipherTree tree;
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>;
237
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>;
241
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>;
245
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>;
249
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>;
253
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>;
257
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>;
261
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>;
265
266     return tree;
267 }
268
269 CipherTree g_cipherTree = initializeCipherTree();
270
271 // key length in bytes
272 InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = true)
273 {
274     try {
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), ", ",
280                  key_len, ", ",
281                  encryption);
282     }
283 }
284
285 } // anonymous namespace
286
287 int initialize() {
288     int hw_rand_ret = 0;
289     int u_rand_ret = 0;
290
291     // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms
292     ERR_load_crypto_strings();
293     OpenSSL_add_all_algorithms();
294
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);
299     }
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);
303
304         if(hw_rand_ret != 32) {
305             ThrowErr(Exc::Crypto::InternalError, "Error in U_RAND_file_load");
306         }
307     }
308
309     return CKM_CRYPTO_INIT_SUCCESS;
310 }
311
312 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) {
313     const EVP_MD *md_algo=NULL;
314     switch(hashAlgo) {
315     case HashAlgorithm::NONE:
316         md_algo = NULL;
317         break;
318     case HashAlgorithm::SHA1:
319         md_algo = EVP_sha1();
320          break;
321     case HashAlgorithm::SHA256:
322          md_algo = EVP_sha256();
323          break;
324     case HashAlgorithm::SHA384:
325          md_algo = EVP_sha384();
326          break;
327     case HashAlgorithm::SHA512:
328          md_algo = EVP_sha512();
329          break;
330     default:
331         ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value");
332     }
333     return md_algo;
334 }
335
336 int getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
337     int rsa_padding = -1;
338     switch(padAlgo) {
339     case RSAPaddingAlgorithm::NONE:
340         rsa_padding = RSA_NO_PADDING;
341         break;
342     case RSAPaddingAlgorithm::PKCS1:
343         rsa_padding = RSA_PKCS1_PADDING;
344         break;
345     case RSAPaddingAlgorithm::X931:
346         rsa_padding = RSA_X931_PADDING;
347         break;
348     default:
349         ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value");
350     }
351     return rsa_padding;
352 }
353
354 TokenPair createKeyPairRSA(CryptoBackend backendId, const int size)
355 {
356     EvpPkeyUPtr pkey;
357
358     // check the parameters of functions
359     if(size!=1024 && size!=2048 && size!=4096) {
360         ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size");
361     }
362
363     EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free);
364     if(!ctx) {
365         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!");
366     }
367
368     if(EVP_PKEY_keygen_init(ctx.get()) <= 0) {
369         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function !!");
370     }
371
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 !!");
374     }
375
376     EVP_PKEY *pkeyTmp = NULL;
377     if(!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) {
378         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
379     }
380     pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
381
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())));
384 }
385
386
387 TokenPair createKeyPairDSA(CryptoBackend backendId, const int size)
388 {
389     EvpPkeyUPtr pkey;
390     EvpPkeyUPtr pparam;
391
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");
395     }
396
397     /* Create the context for generating the parameters */
398     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free);
399     if(!pctx) {
400         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
401     }
402
403     if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
404         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
405     }
406
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");
409     }
410
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");
415     }
416     pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
417
418     // Start to generate key
419     EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
420     if(!kctx) {
421         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
422     }
423
424     if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
425         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
426     }
427
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 !!");
432     }
433     pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
434
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())));
437 }
438
439 TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type)
440 {
441     int ecCurve = NOT_DEFINED;
442     EvpPkeyUPtr pkey;
443     EvpPkeyUPtr pparam;
444
445     switch(type) {
446     case ElipticCurve::prime192v1:
447         ecCurve = NID_X9_62_prime192v1;
448         break;
449     case ElipticCurve::prime256v1:
450         ecCurve = NID_X9_62_prime256v1;
451         break;
452     case ElipticCurve::secp384r1:
453         ecCurve = NID_secp384r1;
454         break;
455     default:
456         ThrowErr(Exc::Crypto::InputParam, "Error in EC type");
457     }
458
459     /* Create the context for generating the parameters */
460     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free);
461     if(!pctx) {
462         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
463     }
464
465     if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
466         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function");
467     }
468
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");
471     }
472
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");
477     }
478     pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
479
480     // Start to generate key
481     EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
482     if(!kctx) {
483         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
484     }
485
486     if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
487         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
488     }
489
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 !!");
494     }
495     pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
496
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())));
499 }
500
501 Token createKeyAES(CryptoBackend backendId, const int sizeBits)
502 {
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");
507     }
508
509     uint8_t key[32];
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");
514     }
515
516     return Token(backendId, DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes));
517 }
518
519 TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
520 {
521     validateParams<IsAsymGeneration>(algorithm);
522
523     AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
524     if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
525     {
526         int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
527         if(keyType == AlgoType::RSA_GEN)
528             return createKeyPairRSA(backendId, keyLength);
529         else
530             return createKeyPairDSA(backendId, keyLength);
531     }
532     else // AlgoType::ECDSA_GEN
533     {
534         ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
535         return createKeyPairECDSA(backendId, ecType);
536     }
537 }
538
539 Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
540 {
541     validateParams<IsSymGeneration>(algorithm);
542
543     int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
544     return createKeyAES(backendId, keySizeBits);
545 }
546
547 RawBuffer encryptDataAes(
548     AlgoType type,
549     const RawBuffer &key,
550     const RawBuffer &data,
551     const RawBuffer &iv)
552 {
553     EvpCipherPtr enc;
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));
558     return result;
559 }
560
561 std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
562     const RawBuffer &key,
563     const RawBuffer &data,
564     const RawBuffer &iv,
565     int tagSize)
566 {
567     RawBuffer tag(tagSize);
568     EvpCipherPtr enc;
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.");
575     }
576     return std::make_pair(result, tag);
577 }
578
579 RawBuffer encryptDataAesGcmPacked(
580     const RawBuffer &key,
581     const RawBuffer &data,
582     const RawBuffer &iv,
583     int tagSize)
584 {
585     auto pair = encryptDataAesGcm(key, data, iv, tagSize);
586     std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first));
587     return pair.first;
588 }
589
590 RawBuffer decryptDataAes(
591     AlgoType type,
592     const RawBuffer &key,
593     const RawBuffer &data,
594     const RawBuffer &iv)
595 {
596     EvpCipherPtr dec;
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));
601     return result;
602 }
603
604 RawBuffer decryptDataAesGcm(
605     const RawBuffer &key,
606     const RawBuffer &data,
607     const RawBuffer &iv,
608     const RawBuffer &tag)
609 {
610     EvpCipherPtr dec;
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.");
616     }
617     RawBuffer result = dec->Append(data);
618     RawBuffer tmp = dec->Finalize();
619     std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
620     return result;
621 }
622
623 RawBuffer decryptDataAesGcmPacked(
624     const RawBuffer &key,
625     const RawBuffer &data,
626     const RawBuffer &iv,
627     int tagSize)
628 {
629     if (tagSize > static_cast<int>(data.size()))
630         ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
631
632     auto tagPos = data.data() + data.size() - tagSize;
633     return decryptDataAesGcm(
634         key,
635         RawBuffer(data.data(), tagPos),
636         iv,
637         RawBuffer(tagPos, data.data() + data.size()));
638 }
639
640 RawBuffer symmetricEncrypt(const RawBuffer &key,
641                            const CryptoAlgorithm &alg,
642                            const RawBuffer &data)
643 {
644     validateParams<IsEncryption>(alg);
645     AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
646
647     switch(keyType)
648     {
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:
654         {
655             int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
656             alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
657             return encryptDataAesGcmPacked(key,
658                                            data,
659                                            unpack<RawBuffer>(alg, ParamName::ED_IV),
660                                            tagLenBits/8);
661         }
662         default:
663             break;
664     }
665     ThrowErr(Exc::Crypto::OperationNotSupported,
666         "symmetric enc error: algorithm not recognized");
667 }
668
669 RawBuffer symmetricDecrypt(const RawBuffer &key,
670                            const CryptoAlgorithm &alg,
671                            const RawBuffer &data)
672 {
673     validateParams<IsEncryption>(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 decryptDataAes(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             return decryptDataAesGcmPacked(key,
687                                            data,
688                                            unpack<RawBuffer>(alg, ParamName::ED_IV),
689                                            tagLenBits/8);
690         }
691         default:
692             break;
693     }
694     ThrowErr(Exc::Crypto::InputParam, "symmetric dec error: algorithm not recognized");
695 }
696
697 RawBuffer sign(EVP_PKEY *pkey,
698     const CryptoAlgorithm &alg,
699     const RawBuffer &message)
700 {
701     validateParams<IsSignVerify>(alg);
702
703     int rsa_padding = NOT_DEFINED;
704     const EVP_MD *md_algo = NULL;
705
706     HashAlgorithm hashTmp = HashAlgorithm::NONE;
707     alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
708     md_algo = getMdAlgo(hashTmp);
709
710     RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
711     alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
712     rsa_padding = getRsaPadding(rsaPad);
713
714 //
715 //    if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
716 //       (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
717 //       (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
718 //    {
719 //        LogError("Error in private key type");
720 //        ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
721 //    }
722 //
723 //    if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
724 //        rsa_padding = getRsaPadding(padAlgo);
725 //    }
726
727     if (NULL == pkey) {
728         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function");
729     }
730
731     if(md_algo == NULL) {
732         return signMessage(pkey, message, rsa_padding);
733     }
734
735     return digestSignMessage(pkey,message, md_algo, rsa_padding);
736 }
737
738 RawBuffer signMessage(EVP_PKEY *privKey,
739         const RawBuffer &message,
740         const int rsa_padding)
741 {
742     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
743  
744     if(!pctx.get()) {
745         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
746     }
747
748     if(EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) {
749         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
750     }
751
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");
757         }
758     }
759
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 */
763     size_t 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");
766     }
767
768     /* Allocate memory for the signature based on size in slen */
769     RawBuffer sig(slen);
770
771     if(EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
772                                     sig.data(),
773                                     &slen,
774                                     message.data(),
775                                     message.size()))
776     {
777         // Set value to return RawData
778         sig.resize(slen);
779         return sig;
780     }
781
782     ThrowErr(Exc::Crypto::InputParam, "Error in EVP_PKEY_sign function. Input param error.");
783 }
784
785 RawBuffer digestSignMessage(EVP_PKEY *privKey,
786         const RawBuffer &message,
787         const EVP_MD *md_algo,
788         const int rsa_padding)
789 {
790     EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
791  
792     EVP_PKEY_CTX *pctx = NULL;
793
794     // Create the Message Digest Context
795     if(!mdctx.get()) {
796         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
797     }
798
799     if(EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) {
800         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
801     }
802
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");
807         }
808     }
809
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");
813     }
814
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 */
818     size_t slen;
819     if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) {
820         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
821     }
822
823     /* Allocate memory for the signature based on size in slen */
824     RawBuffer sig(slen);
825
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");
829     }
830
831     // Set value to return RawData
832     sig.resize(slen);
833     return sig;
834 }
835
836 int verify(EVP_PKEY *pkey,
837     const CryptoAlgorithm &alg,
838     const RawBuffer &message,
839     const RawBuffer &signature)
840 {
841     validateParams<IsSignVerify>(alg);
842
843     int rsa_padding = NOT_DEFINED;
844     const EVP_MD *md_algo = NULL;
845
846     HashAlgorithm hashTmp = HashAlgorithm::NONE;
847     alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
848     md_algo = getMdAlgo(hashTmp);
849
850     RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
851     alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
852     rsa_padding = getRsaPadding(rsaPad);
853
854 //
855 //    if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
856 //       (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
857 //       (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
858 //    {
859 //        LogError("Error in private key type");
860 //        ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type");
861 //    }
862 //
863 //    if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
864 //        rsa_padding = getRsaPadding(padAlgo);
865 //    }
866
867 //    auto shrPKey = publicKey.getEvpShPtr();
868     if (NULL == pkey) {
869         ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function");
870     }
871
872     if (md_algo == NULL) {
873         return verifyMessage(pkey, message, signature, rsa_padding);
874     }
875
876     return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
877 }
878
879 int verifyMessage(EVP_PKEY *pubKey,
880         const RawBuffer &message,
881         const RawBuffer &signature,
882         const int rsa_padding)
883 {
884     EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
885
886     if(!pctx.get()) {
887         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
888     }
889
890     if(EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) {
891         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
892     }
893
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");
898         }
899     }
900
901     if(EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) {
902         return CKM_API_SUCCESS;
903     } 
904
905     LogError("EVP_PKEY_verify Failed");
906     return CKM_API_ERROR_VERIFICATION_FAILED;
907 }
908
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)
914 {
915     EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
916     EVP_PKEY_CTX *pctx = NULL;
917
918     /* Create the Message Digest Context */
919     if(!mdctx.get()) {
920         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
921     }
922
923     if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) {
924         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
925     }
926
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");
930         }
931     }
932
933     if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()) ) {
934         ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyUpdate function");
935     }
936
937     if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size()) ) {
938         return CKM_API_SUCCESS;
939     }
940
941     LogError("EVP_PKEY_verify Failed");
942     return CKM_API_ERROR_VERIFICATION_FAILED;
943 }
944
945 } // namespace Internals
946 } // namespace SW
947 } // namespace Crypto
948 } // namespace CKM