Apply coding style of tizen by astyle
[platform/core/security/libwebappenc.git] / srcs / crypto_service.c
1 /*
2  *  Copyright (c) 2016 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        crypto_service.c
18  * @author      Dongsun Lee (ds73.lee@samsung.com)
19  * @version     1.0
20  * @brief       provides encryption and decription operations.
21  */
22 #include "crypto_service.h"
23
24 #include <stdbool.h>
25 #include <openssl/evp.h>
26 #include <openssl/rand.h>
27 #include <openssl/crypto.h>
28 #include <openssl/err.h>
29 #include <openssl/bio.h>
30 #include <openssl/evp.h>
31 #include <openssl/pem.h>
32 #include <openssl/rsa.h>
33
34 #include "web_app_enc.h"
35 #include "wae_log.h"
36
37 #define AES_256_KEY_SIZE 32
38
39 static unsigned char AES_CBC_IV[16] = {
40         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
41         0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
42 };
43
44 static bool __initialized = false;
45
46 void _initialize()
47 {
48         if (!__initialized) {
49                 ERR_load_crypto_strings();
50                 OpenSSL_add_all_algorithms();
51                 __initialized = true;
52         }
53 }
54
55 int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen,
56                                         const unsigned char *dek, size_t dekLen,
57                                         unsigned char **encryptedDek, size_t *encryptedDekLen)
58 {
59         int ret = WAE_ERROR_NONE;
60         EVP_PKEY *pKey = NULL;
61         BIO *bio = NULL;
62         EVP_PKEY_CTX *ctx = NULL;
63         unsigned char *out = NULL;
64         size_t outLen = 0;
65
66         _initialize();
67
68         bio = BIO_new(BIO_s_mem());
69         BIO_write(bio, rsaPublicKey, pubKeyLen);
70         pKey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
71
72         if (pKey == NULL) {
73                 BIO_reset(bio);
74                 BIO_write(bio, rsaPublicKey, pubKeyLen);
75                 pKey = d2i_PUBKEY_bio(bio, NULL);
76         }
77
78         if (pKey == NULL) {
79                 ret = WAE_ERROR_FILE;
80                 WAE_SLOGE("Failt to convert to public key.");
81                 goto error;
82         }
83
84         ctx = EVP_PKEY_CTX_new(pKey, NULL);
85
86         if (ctx == NULL) {
87                 WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_new failed");
88                 ret = WAE_ERROR_CRYPTO;
89                 goto error;
90         }
91
92         if (EVP_PKEY_encrypt_init(ctx) <= 0) {
93                 WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt_init failed");
94                 ret = WAE_ERROR_CRYPTO;
95                 goto error;
96         }
97
98         if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
99                 WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_set_rsa_padding failed");
100                 ret = WAE_ERROR_CRYPTO;
101                 goto error;
102         }
103
104         /* Determine buffer length */
105         if (EVP_PKEY_encrypt(ctx, NULL, &outLen, dek, dekLen) <= 0) {
106                 WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed");
107                 ret = WAE_ERROR_CRYPTO;
108                 goto error;
109         }
110
111         out = OPENSSL_malloc(outLen);
112
113         if (out == NULL) {
114                 WAE_SLOGE("Encrypt APP DEK Failed. OPENSSL_malloc failed");
115                 ret = WAE_ERROR_MEMORY;
116                 goto error;
117         }
118
119         if (EVP_PKEY_encrypt(ctx, out, &outLen, dek, dekLen) <= 0) {
120                 WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed");
121                 ret = WAE_ERROR_CRYPTO;
122                 goto error;
123         }
124
125         *encryptedDek = out;
126         *encryptedDekLen = outLen;
127
128 error:
129         if (bio != NULL)
130                 BIO_free(bio);
131
132         if (pKey != NULL)
133                 EVP_PKEY_free(pKey);
134
135         if (ctx != NULL)
136                 EVP_PKEY_CTX_free(ctx);
137
138         if (ret != WAE_ERROR_NONE && out != NULL)
139                 OPENSSL_free(out);
140
141         return ret;
142 }
143
144 int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen,
145                                         const char *priKeyPassword,
146                                         const unsigned char *encryptedDek, size_t dencryptedDekLen,
147                                         unsigned char **decryptedDek, size_t *decryptedDekLen)
148 {
149         int ret = WAE_ERROR_NONE;
150         EVP_PKEY *pKey = NULL;
151         BIO *bio = NULL;
152         EVP_PKEY_CTX *ctx = NULL;
153         unsigned char *out = NULL;
154         size_t outLen = 0;
155
156         _initialize();
157
158         bio = BIO_new(BIO_s_mem());
159         BIO_write(bio, rsaPrivateKey, priKeyLen);
160         pKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)priKeyPassword);
161
162         if (pKey == NULL) {
163                 BIO_reset(bio);
164                 BIO_write(bio, rsaPrivateKey, priKeyLen);
165                 pKey = d2i_PrivateKey_bio(bio, NULL);
166         }
167
168         if (pKey == NULL) {
169                 ret = WAE_ERROR_FILE;
170                 WAE_SLOGE("Failt to convert to public key.");
171                 goto error;
172         }
173
174         ctx = EVP_PKEY_CTX_new(pKey, NULL);
175
176         if (ctx == NULL) {
177                 WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_new failed");
178                 ret = WAE_ERROR_CRYPTO;
179                 goto error;
180         }
181
182         if (EVP_PKEY_decrypt_init(ctx) <= 0) {
183                 WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt_init failed");
184                 ret = WAE_ERROR_CRYPTO;
185                 goto error;
186         }
187
188         if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
189                 WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_set_rsa_padding failed");
190                 ret = WAE_ERROR_CRYPTO;
191                 goto error;
192         }
193
194         /* Determine buffer length */
195         if (EVP_PKEY_decrypt(ctx, NULL, &outLen, encryptedDek, dencryptedDekLen) <= 0) {
196                 WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt failed");
197                 ret = WAE_ERROR_CRYPTO;
198                 goto error;
199         }
200
201         out = OPENSSL_malloc(outLen);
202
203         if (out == NULL) {
204                 WAE_SLOGE("Decrypt APP DEK Failed. OPENSSL_malloc failed");
205                 ret = WAE_ERROR_MEMORY;
206                 goto error;
207         }
208
209         if (EVP_PKEY_decrypt(ctx, out, &outLen, encryptedDek, dencryptedDekLen) <= 0) {
210                 WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_decrypt failed");
211                 ret = WAE_ERROR_CRYPTO;
212                 goto error;
213         }
214
215         *decryptedDek = out;
216         *decryptedDekLen = outLen;
217
218 error:
219         if (bio != NULL)
220                 BIO_free(bio);
221
222         if (pKey != NULL)
223                 EVP_PKEY_free(pKey);
224
225         if (ctx != NULL)
226                 EVP_PKEY_CTX_free(ctx);
227
228         if (ret != WAE_ERROR_NONE && out != NULL)
229                 OPENSSL_free(out);
230
231         return ret;
232 }
233
234
235 int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen,
236                                         const unsigned char *pData, size_t dataLen,
237                                         unsigned char **ppEncryptedData, size_t *pEncDataLen)
238 {
239         EVP_CIPHER_CTX *ctx;
240         int len;
241         unsigned char *ciphertext = NULL;
242         size_t ciphertext_len;
243         unsigned char *iv = AES_CBC_IV;
244         int ret = WAE_ERROR_NONE;
245
246         _initialize();
247
248         WAE_SLOGI("Encryption Started. size=%d", dataLen);
249
250         /* check input paramter */
251         if (keyLen != 32) {
252                 WAE_SLOGE("Encryption Failed. Invalid Key Length. keyLen=%d", keyLen);
253                 return WAE_ERROR_INVALID_PARAMETER;
254         }
255
256         // assing a enough memory for decryption.
257         ciphertext = (unsigned char *) malloc(dataLen + 32);
258
259         /* Create and initialise the context */
260         if (!(ctx = EVP_CIPHER_CTX_new())) {
261                 WAE_SLOGE("Encryption Failed. EVP_CIPHER_CTX_new failed");
262                 ret = WAE_ERROR_CRYPTO;
263                 goto error;
264         }
265
266         /* Initialise the encryption operation. IMPORTANT - ensure you use a key
267          * and IV size appropriate for your cipher
268          * In this example we are using 256 bit AES (i.e. a 256 bit key). The
269          * IV size for *most* modes is the same as the block size. For AES this
270          * is 128 bits */
271         if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) {
272                 WAE_SLOGE("Encryption Failed. EVP_EncryptInit_ex failed");
273                 ret = WAE_ERROR_CRYPTO;
274                 goto error;
275         }
276
277         /* Provide the message to be encrypted, and obtain the encrypted output.
278          * EVP_EncryptUpdate can be called multiple times if necessary
279          */
280         if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, pData, dataLen)) {
281                 WAE_SLOGE("Encryption Failed. EVP_EncryptUpdate failed");
282                 ret = WAE_ERROR_CRYPTO;
283                 goto error;
284         }
285
286         ciphertext_len = len;
287
288         /* Finalise the encryption. Further ciphertext bytes may be written at
289          * this stage.
290          */
291         if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) {
292                 WAE_SLOGE("Encryption Failed. EVP_EncryptFinal_ex failed");
293                 ret = WAE_ERROR_CRYPTO;
294                 goto error;
295         }
296
297         ciphertext_len += len;
298
299         *ppEncryptedData = ciphertext;
300         *pEncDataLen = ciphertext_len;
301
302         ret = WAE_ERROR_NONE;
303         WAE_SLOGI("Encryption Ended Successfully. encrypted_len", ciphertext_len);
304
305 error:
306         if (ctx != NULL)
307                 EVP_CIPHER_CTX_free(ctx);
308
309         if (ret != WAE_ERROR_NONE && ciphertext != NULL)
310                 free(ciphertext);
311
312         return ret;
313 }
314
315 int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen,
316                                         const unsigned char *pData, size_t dataLen,
317                                         unsigned char **ppDecryptedData, size_t *pDecDataLen)
318 {
319         EVP_CIPHER_CTX *ctx;
320         int len;
321         unsigned char *plaintext = NULL;
322         size_t plaintext_len;
323         unsigned char *iv = AES_CBC_IV;
324         int ret = WAE_ERROR_NONE;
325
326         _initialize();
327
328         WAE_SLOGI("Decryption Started. size=%d", dataLen);
329
330         /* check input paramter */
331         if (keyLen != 32) {
332                 WAE_SLOGE("Decryption Failed. Invalid Key Length. keyLen=%d", keyLen);
333                 return WAE_ERROR_INVALID_PARAMETER;
334         }
335
336         // assing a enough memory for decryption.
337         plaintext = (unsigned char *) malloc(dataLen);
338
339         /* Create and initialise the context */
340         if (!(ctx = EVP_CIPHER_CTX_new())) {
341                 WAE_SLOGE("Decryption Failed. EVP_CIPHER_CTX_new failed");
342                 ret = WAE_ERROR_CRYPTO;
343                 goto error;
344         }
345
346         /* Initialise the decryption operation. IMPORTANT - ensure you use a key
347          * and IV size appropriate for your cipher
348          * In this example we are using 256 bit AES (i.e. a 256 bit key). The
349          * IV size for *most* modes is the same as the block size. For AES this
350          * is 128 bits */
351         if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) {
352                 WAE_SLOGE("Decryption Failed. EVP_DecryptInit_ex failed");
353                 ret = WAE_ERROR_CRYPTO;
354                 goto error;
355         }
356
357         /* Provide the message to be decrypted, and obtain the plaintext output.
358          * EVP_DecryptUpdate can be called multiple times if necessary
359          */
360         if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, pData, dataLen)) {
361                 WAE_SLOGE("Decryption Failed. EVP_DecryptUpdate failed");
362                 ret = WAE_ERROR_CRYPTO;
363                 goto error;
364         }
365
366         plaintext_len = len;
367
368         /* Finalise the decryption. Further plaintext bytes may be written at
369          * this stage.
370          */
371         if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) {
372                 WAE_SLOGE("Decryption Failed. EVP_DecryptFinal_ex failed");
373                 ret = WAE_ERROR_CRYPTO;
374                 goto error;
375         }
376
377         plaintext_len += len;
378
379         *ppDecryptedData = plaintext;
380         *pDecDataLen = plaintext_len;
381
382         ret = WAE_ERROR_NONE;
383         WAE_SLOGI("Decryption Ended Successfully. decrypted_len", plaintext_len);
384
385 error:
386         if (ctx != NULL)
387                 EVP_CIPHER_CTX_free(ctx);
388
389         if (ret != WAE_ERROR_NONE && plaintext != NULL)
390                 free(plaintext);
391
392         return ret;
393 }