9959cce90e38429ecc1c40c21f924d794cfe0f4d
[platform/core/security/key-manager.git] / src / manager / crypto / sw-backend / crypto-service.cpp
1 #include <iostream>
2 #include <exception>
3 #include <vector>
4 #include <fstream>
5 #include <string.h>
6 #include <memory>
7
8 #include <openssl/x509_vfy.h>
9 #include <openssl/evp.h>
10 #include <openssl/obj_mac.h>
11 #include <openssl/ec.h>
12 #include <openssl/dsa.h>
13 #include <openssl/dh.h>
14 #include <openssl/rsa.h>
15 #include <openssl/bio.h>
16 #include <openssl/rand.h>
17 #include <openssl/crypto.h>
18 #include <openssl/err.h>
19 #include <openssl/x509v3.h>
20 #include <openssl/obj_mac.h>
21 #include <ckm/ckm-error.h>
22 #include <ckm/ckm-type.h>
23 #include <key-impl.h>
24 #include <sw-backend/crypto-service.h>
25 #include <assert.h>
26 #include <dpl/log/log.h>
27
28 #define OPENSSL_SUCCESS 1       // DO NOTCHANGE THIS VALUE
29 #define OPENSSL_FAIL    0       // DO NOTCHANGE THIS VALUE
30
31 namespace CKM {
32 namespace Crypto {
33 namespace SW {
34
35 CryptoService::CryptoService(){
36 }
37
38 CryptoService::~CryptoService(){
39 }
40
41 int CryptoService::initialize() {
42     int hw_rand_ret = 0;
43     int u_rand_ret = 0;
44
45     // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms
46     ERR_load_crypto_strings();
47     OpenSSL_add_all_algorithms();
48
49     // initialize entropy
50     std::ifstream ifile(DEV_HW_RANDOM_FILE);
51     if(ifile.is_open()) {
52         u_rand_ret= RAND_load_file(DEV_HW_RANDOM_FILE, 32);
53     }
54     if(u_rand_ret != 32 ){
55         LogError("Error in HW_RAND file load");
56         hw_rand_ret = RAND_load_file(DEV_URANDOM_FILE, 32);
57
58         if(hw_rand_ret != 32) {
59             LogError("Error in U_RAND_file_load");
60             ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in U_RAND_file_load");
61         }
62     }
63
64     return CKM_CRYPTO_INIT_SUCCESS;
65 }
66
67 int CryptoService::createKeyPairRSA(const int size, // size in bits [1024, 2048, 4096]
68         KeyImpl &createdPrivateKey,  // returned value
69         KeyImpl &createdPublicKey)  // returned value
70 {
71     EVP_PKEY_CTX *ctx = NULL;
72     EVP_PKEY *pkey = NULL;
73     EVP_PKEY *pparam = NULL;
74
75     // check the parameters of functions
76     if(size != 1024 && size !=2048 && size != 4096) {
77         LogError("Error in RSA input size");
78         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in RSA input size");
79     }
80
81     // check the parameters of functions
82     if(&createdPrivateKey == NULL) {
83         LogError("Error in createdPrivateKey value");
84         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
85     }
86
87     // check the parameters of functions
88     if(&createdPublicKey == NULL) {
89         LogError("Error in createdPrivateKey value");
90         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
91     }
92
93     Try {
94         if(!(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL))) {
95             LogError("Error in EVP_PKEY_CTX_new_id function !!");
96             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function !!");
97         }
98
99         if(EVP_PKEY_keygen_init(ctx) <= 0) {
100             LogError("Error in EVP_PKEY_keygen_init function !!");
101             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function !!");
102         }
103
104         if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx,size) <= 0) {
105             LogError("Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
106             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
107         }
108
109         if(!EVP_PKEY_keygen(ctx, &pkey)) {
110             LogError("Error in EVP_PKEY_keygen function !!");
111             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function !!");
112         }
113     } Catch(CryptoService::Exception::opensslError) {
114         if(pkey) {
115             EVP_PKEY_free(pkey);
116         }
117
118         if(pparam) {
119             EVP_PKEY_free(pparam);
120         }
121
122         if(ctx) {
123             EVP_PKEY_CTX_free(ctx);
124         }
125
126         ReThrowMsg(CryptoService::Exception::opensslError,"Error in opensslError function !!");
127     }
128
129     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
130
131     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_RSA_PRIVATE);
132     createdPublicKey = KeyImpl(ptr, KeyType::KEY_RSA_PUBLIC);
133
134     if(pparam) {
135         EVP_PKEY_free(pparam);
136     }
137
138     if(ctx) {
139         EVP_PKEY_CTX_free(ctx);
140     }
141
142     return CKM_CRYPTO_CREATEKEY_SUCCESS;
143 }
144
145
146 int CryptoService::createKeyPairDSA(const int size, // size in bits [1024, 2048, 3072, 4096]
147                 KeyImpl &createdPrivateKey,  // returned value
148                 KeyImpl &createdPublicKey)  // returned value
149 {
150         EVP_PKEY_CTX *pctx = NULL;
151         EVP_PKEY_CTX *kctx = NULL;
152         EVP_PKEY *pkey = NULL;
153         EVP_PKEY *pparam = NULL;
154
155         // check the parameters of functions
156         if(size != 1024 && size !=2048 && size !=3072 && size != 4096) {
157                 LogError("Error in DSA input size");
158                 ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in DSA input size");
159         }
160
161         // check the parameters of functions
162         if(&createdPrivateKey == NULL) {
163                 LogError("Error in createdPrivateKey value");
164                 ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
165         }
166
167         // check the parameters of functions
168         if(&createdPublicKey == NULL) {
169                 LogError("Error in createdPrivateKey value");
170                 ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
171         }
172
173         Try {
174                 /* Create the context for generating the parameters */
175                 if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL))) {
176                         LogError("Error in EVP_PKEY_CTX_new_id function");
177                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
178                 }
179
180                 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
181                         LogError("Error in EVP_PKEY_paramgen_init function");
182                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
183                 }
184
185                 if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, size)) {
186                         LogError("Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
187                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
188                 }
189
190                 /* Generate parameters */
191                 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
192                         LogError("Error in EVP_PKEY_paramgen function");
193                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
194                 }
195
196                 // Start to generate key
197                 if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
198                         LogError("Error in EVP_PKEY_CTX_new function");
199                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
200                 }
201
202                 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
203                         LogError("Error in EVP_PKEY_keygen_init function");
204                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
205                 }
206
207                 /* Generate the key */
208                 if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
209                         LogError("Error in EVP_PKEY_keygen function");
210                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
211                 }
212         }
213         Catch(CryptoService::Exception::opensslError)
214         {
215                 if(pkey) {
216                         EVP_PKEY_free(pkey);
217                 }
218
219                 if(pparam) {
220                         EVP_PKEY_free(pparam);
221                 }
222
223                 if(pctx) {
224                         EVP_PKEY_CTX_free(pctx);
225                 }
226
227                 if(kctx) {
228                         EVP_PKEY_CTX_free(kctx);
229                 }
230
231                 ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
232         }
233
234         KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
235
236         createdPrivateKey = KeyImpl(ptr, KeyType::KEY_DSA_PRIVATE);
237         createdPublicKey = KeyImpl(ptr, KeyType::KEY_DSA_PUBLIC);
238
239         if(pparam) {
240                 EVP_PKEY_free(pparam);
241         }
242
243         if(pctx) {
244                 EVP_PKEY_CTX_free(pctx);
245         }
246
247         if(kctx) {
248                 EVP_PKEY_CTX_free(kctx);
249         }
250
251         return CKM_CRYPTO_CREATEKEY_SUCCESS;
252 }
253
254
255 int CryptoService::createKeyPairECDSA(ElipticCurve type,
256         KeyImpl &createdPrivateKey,  // returned value
257         KeyImpl &createdPublicKey)  // returned value
258 {
259     int ecCurve = NOT_DEFINED;
260     EVP_PKEY_CTX *pctx = NULL;
261     EVP_PKEY_CTX *kctx = NULL;
262     EVP_PKEY *pkey = NULL;
263     EVP_PKEY *pparam = NULL;
264
265     switch(type) {
266     case ElipticCurve::prime192v1:
267         ecCurve = NID_X9_62_prime192v1;
268         break;
269     case ElipticCurve::prime256v1:
270         ecCurve = NID_X9_62_prime256v1;
271         break;
272     case ElipticCurve::secp384r1:
273         ecCurve = NID_secp384r1;
274         break;
275     default:
276         LogError("Error in EC type");
277         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in EC type");
278     }
279
280     // check the parameters of functions
281     if(&createdPrivateKey == NULL) {
282         LogError("Error in createdPrivateKey value");
283         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
284     }
285
286     // check the parameters of functions
287     if(&createdPublicKey == NULL) {
288         LogError("Error in createdPrivateKey value");
289         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
290     }
291
292     Try {
293         /* Create the context for generating the parameters */
294         if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) {
295             LogError("Error in EVP_PKEY_CTX_new_id function");
296             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
297         }
298
299         if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
300             LogError("Error in EVP_PKEY_paramgen_init function");
301             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
302         }
303
304         if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecCurve)) {
305             LogError("Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
306             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
307         }
308
309         /* Generate parameters */
310         if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
311             LogError("Error in EVP_PKEY_paramgen function");
312             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
313         }
314
315         // Start to generate key
316         if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
317             LogError("Error in EVP_PKEY_CTX_new function");
318             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
319         }
320
321         if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
322             LogError("Error in EVP_PKEY_keygen_init function");
323             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
324         }
325
326         /* Generate the key */
327         if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
328             LogError("Error in EVP_PKEY_keygen function");
329             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
330         }
331     } Catch(CryptoService::Exception::opensslError) {
332         if(pkey) {
333             EVP_PKEY_free(pkey);
334         }
335
336         if(pparam) {
337             EVP_PKEY_free(pparam);
338         }
339
340         if(pctx) {
341             EVP_PKEY_CTX_free(pctx);
342         }
343
344         if(kctx) {
345             EVP_PKEY_CTX_free(kctx);
346         }
347
348         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
349     }
350
351     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
352
353     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_ECDSA_PRIVATE);
354     createdPublicKey = KeyImpl(ptr, KeyType::KEY_ECDSA_PUBLIC);
355
356     if(pparam) {
357         EVP_PKEY_free(pparam);
358     }
359
360     if(pctx) {
361         EVP_PKEY_CTX_free(pctx);
362     }
363
364     if(kctx) {
365         EVP_PKEY_CTX_free(kctx);
366     }
367
368     return CKM_CRYPTO_CREATEKEY_SUCCESS;
369 }
370
371 } // namespace SW
372 } // namespace Crypto
373 } // namespace CKM