6ce25cc54a3aca47c86e7c12a74f95c4e8b8a229
[platform/core/security/yaca.git] / src / encrypt.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file encrypt.c
21  * @brief
22  */
23
24 #include <assert.h>
25 #include <stdint.h>
26 #include <stdbool.h>
27 #include <limits.h>
28
29 #include <openssl/evp.h>
30
31 #include <yaca_crypto.h>
32 #include <yaca_encrypt.h>
33 #include <yaca_error.h>
34 #include <yaca_key.h>
35
36 #include "internal.h"
37
38 static const size_t DEFAULT_GCM_TAG_LEN = 16;
39 static const size_t DEFAULT_CCM_TAG_LEN = 12;
40
41 static const struct {
42         yaca_encrypt_algorithm_e algo;
43         yaca_block_cipher_mode_e bcm;
44         size_t key_bit_len;
45         const EVP_CIPHER *(*cipher)(void);
46 } ENCRYPTION_CIPHERS[] = {
47         {YACA_ENCRYPT_AES, YACA_BCM_CBC,  128, EVP_aes_128_cbc},
48         {YACA_ENCRYPT_AES, YACA_BCM_CCM,  128, EVP_aes_128_ccm},
49         {YACA_ENCRYPT_AES, YACA_BCM_CFB,  128, EVP_aes_128_cfb},
50         {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 128, EVP_aes_128_cfb1},
51         {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 128, EVP_aes_128_cfb8},
52         {YACA_ENCRYPT_AES, YACA_BCM_CTR,  128, EVP_aes_128_ctr},
53         {YACA_ENCRYPT_AES, YACA_BCM_ECB,  128, EVP_aes_128_ecb},
54         {YACA_ENCRYPT_AES, YACA_BCM_GCM,  128, EVP_aes_128_gcm},
55         {YACA_ENCRYPT_AES, YACA_BCM_OFB,  128, EVP_aes_128_ofb},
56         {YACA_ENCRYPT_AES, YACA_BCM_WRAP, 128, EVP_aes_128_wrap},
57
58         {YACA_ENCRYPT_AES, YACA_BCM_CBC,  192, EVP_aes_192_cbc},
59         {YACA_ENCRYPT_AES, YACA_BCM_CCM,  192, EVP_aes_192_ccm},
60         {YACA_ENCRYPT_AES, YACA_BCM_CFB,  192, EVP_aes_192_cfb},
61         {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 192, EVP_aes_192_cfb1},
62         {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 192, EVP_aes_192_cfb8},
63         {YACA_ENCRYPT_AES, YACA_BCM_CTR,  192, EVP_aes_192_ctr},
64         {YACA_ENCRYPT_AES, YACA_BCM_ECB,  192, EVP_aes_192_ecb},
65         {YACA_ENCRYPT_AES, YACA_BCM_GCM,  192, EVP_aes_192_gcm},
66         {YACA_ENCRYPT_AES, YACA_BCM_OFB,  192, EVP_aes_192_ofb},
67         {YACA_ENCRYPT_AES, YACA_BCM_WRAP, 192, EVP_aes_192_wrap},
68
69         {YACA_ENCRYPT_AES, YACA_BCM_CBC,  256, EVP_aes_256_cbc},
70         {YACA_ENCRYPT_AES, YACA_BCM_CCM,  256, EVP_aes_256_ccm},
71         {YACA_ENCRYPT_AES, YACA_BCM_CFB,  256, EVP_aes_256_cfb},
72         {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 256, EVP_aes_256_cfb1},
73         {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 256, EVP_aes_256_cfb8},
74         {YACA_ENCRYPT_AES, YACA_BCM_CTR,  256, EVP_aes_256_ctr},
75         {YACA_ENCRYPT_AES, YACA_BCM_ECB,  256, EVP_aes_256_ecb},
76         {YACA_ENCRYPT_AES, YACA_BCM_GCM,  256, EVP_aes_256_gcm},
77         {YACA_ENCRYPT_AES, YACA_BCM_OFB,  256, EVP_aes_256_ofb},
78         {YACA_ENCRYPT_AES, YACA_BCM_WRAP, 256, EVP_aes_256_wrap},
79
80         {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC,  -1, EVP_des_cbc},
81         {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB,  -1, EVP_des_cfb},
82         {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB1, -1, EVP_des_cfb1},
83         {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB8, -1, EVP_des_cfb8},
84         {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB,  -1, EVP_des_ecb},
85         {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_OFB,  -1, EVP_des_ofb},
86
87         {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, -1, EVP_des_ede_cbc},
88         {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CFB, -1, EVP_des_ede_cfb},
89         {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, -1, EVP_des_ede_ecb},
90         {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_OFB, -1, EVP_des_ede_ofb},
91
92         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC,  -1, EVP_des_ede3_cbc},
93         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB,  -1, EVP_des_ede3_cfb},
94         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB1, -1, EVP_des_ede3_cfb1},
95         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB8, -1, EVP_des_ede3_cfb8},
96         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB,  -1, EVP_des_ede3_ecb},
97         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_OFB,  -1, EVP_des_ede3_ofb},
98         {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_WRAP, -1, EVP_des_ede3_wrap},
99
100         {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, -1, EVP_rc2_cbc},
101         {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CFB, -1, EVP_rc2_cfb},
102         {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_ECB, -1, EVP_rc2_ecb},
103         {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_OFB, -1, EVP_rc2_ofb},
104
105         {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, -1, EVP_rc4},
106
107         {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, -1, EVP_cast5_cbc},
108         {YACA_ENCRYPT_CAST5, YACA_BCM_CFB, -1, EVP_cast5_cfb},
109         {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, -1, EVP_cast5_ecb},
110         {YACA_ENCRYPT_CAST5, YACA_BCM_OFB, -1, EVP_cast5_ofb},
111 };
112
113 static const size_t ENCRYPTION_CIPHERS_SIZE = sizeof(ENCRYPTION_CIPHERS) / sizeof(ENCRYPTION_CIPHERS[0]);
114
115 static bool is_encryption_op(enum encrypt_op_type_e op_type)
116 {
117         return (op_type == OP_ENCRYPT || op_type == OP_SEAL);
118 }
119
120 static bool DEFAULT_STATES[STATE_COUNT][STATE_COUNT] = {
121 /* from \ to  INIT, MLEN, AAD,  MSG,  TAG,  TLEN, FIN */
122 /* INIT */  { 0,    0,    0,    1,    0,    0,    1 },
123 /* MLEN  */ { 0,    0,    0,    0,    0,    0,    0 },
124 /* AAD  */  { 0,    0,    0,    0,    0,    0,    0 },
125 /* MSG  */  { 0,    0,    0,    1,    0,    0,    1 },
126 /* TAG  */  { 0,    0,    0,    0,    0,    0,    0 },
127 /* TLEN */  { 0,    0,    0,    0,    0,    0,    0 },
128 /* FIN  */  { 0,    0,    0,    0,    0,    0,    0 },
129 };
130
131 static bool GCM_STATES[2][STATE_COUNT][STATE_COUNT] = { {
132 /* ENCRYPTION */
133 /* from \ to  INIT, MLEN, AAD,  MSG,  TAG,  TLEN, FIN */
134 /* INIT */  { 0,    0,    1,    1,    0,    0,    1 },
135 /* MLEN */  { 0,    0,    0,    0,    0,    0,    0 },
136 /* AAD  */  { 0,    0,    1,    1,    0,    0,    1 },
137 /* MSG  */  { 0,    0,    0,    1,    0,    0,    1 },
138 /* TAG  */  { 0,    0,    0,    0,    0,    0,    0 },
139 /* TLEN */  { 0,    0,    0,    0,    0,    0,    0 },
140 /* FIN  */  { 0,    0,    0,    0,    0,    1,    0 },
141 }, {
142 /* DECRYPTION */
143 /* from \ to  INIT, MLEN, AAD,  MSG,  TAG,  TLEN, FIN */
144 /* INIT */  { 0,    0,    1,    1,    1,    0,    0 },
145 /* MLEN */  { 0,    0,    0,    0,    0,    0,    0 },
146 /* AAD  */  { 0,    0,    1,    1,    1,    0,    0 },
147 /* MSG  */  { 0,    0,    0,    1,    1,    0,    0 },
148 /* TAG  */  { 0,    0,    0,    0,    0,    0,    1 },
149 /* TLEN */  { 0,    0,    0,    0,    0,    0,    0 },
150 /* FIN  */  { 0,    0,    0,    0,    0,    0,    0 },
151 } };
152
153 static bool CCM_STATES[2][STATE_COUNT][STATE_COUNT] = { {
154 /* ENCRYPTION */
155 /* from \ to  INIT, MLEN, AAD,  MSG,  TAG,  TLEN, FIN */
156 /* INIT */  { 0,    1,    0,    1,    0,    1,    0 },
157 /* MLEN */  { 0,    0,    1,    0,    0,    0,    0 },
158 /* AAD  */  { 0,    0,    0,    1,    0,    0,    0 },
159 /* MSG  */  { 0,    0,    0,    0,    0,    0,    1 },
160 /* TAG  */  { 0,    0,    0,    0,    0,    0,    0 },
161 /* TLEN */  { 0,    1,    0,    1,    0,    0,    0 },
162 /* FIN  */  { 0,    0,    0,    0,    0,    0,    0 },
163 }, {
164 /* DECRYPTION */
165 /* from \ to  INIT, MLEN, AAD,  MSG,  TAG,  TLEN, FIN */
166 /* INIT */  { 0,    0,    0,    0,    1,    0,    0 },
167 /* MLEN */  { 0,    0,    1,    0,    0,    0,    0 },
168 /* AAD  */  { 0,    0,    0,    1,    0,    0,    0 },
169 /* MSG  */  { 0,    0,    0,    0,    0,    0,    1 },
170 /* TAG  */  { 0,    1,    0,    1,    0,    0,    0 },
171 /* TLEN */  { 0,    0,    0,    0,    0,    0,    0 },
172 /* FIN  */  { 0,    0,    0,    0,    0,    0,    0 },
173 } };
174
175 static bool WRAP_STATES[STATE_COUNT][STATE_COUNT] = {
176 /* from \ to  INIT, MLEN, AAD,  MSG,  TAG,  TLEN, FIN */
177 /* INIT */  { 0,    0,    0,    1,    0,    0,    0 },
178 /* MLEN */  { 0,    0,    0,    0,    0,    0,    0 },
179 /* AAD  */  { 0,    0,    0,    0,    0,    0,    0 },
180 /* MSG  */  { 0,    0,    0,    0,    0,    0,    1 },
181 /* TAG  */  { 0,    0,    0,    0,    0,    0,    0 },
182 /* TLEN */  { 0,    0,    0,    0,    0,    0,    0 },
183 /* FIN  */  { 0,    0,    0,    0,    0,    0,    0 },
184 };
185
186 static bool verify_state_change(struct yaca_encrypt_context_s *c, enum encrypt_context_state_e to)
187 {
188         int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
189         bool encryption = is_encryption_op(c->op_type);
190         int from = c->state;
191
192         if (mode == EVP_CIPH_CCM_MODE)
193                 return CCM_STATES[encryption ? 0 : 1][from][to];
194         else if (mode == EVP_CIPH_GCM_MODE)
195                 return GCM_STATES[encryption ? 0 : 1][from][to];
196         else if (mode == EVP_CIPH_WRAP_MODE)
197                 return WRAP_STATES[from][to];
198         else
199                 return DEFAULT_STATES[from][to];
200
201         return false;
202 }
203
204 static const size_t VALID_GCM_TAG_LENGTHS[] = { 4, 8, 12, 13, 14, 15, 16 };
205 static const size_t VALID_GCM_TAG_LENGTHS_LENGTH =
206                 sizeof(VALID_GCM_TAG_LENGTHS) / sizeof(VALID_GCM_TAG_LENGTHS[0]);
207
208 struct yaca_encrypt_context_s *get_encrypt_context(const yaca_context_h ctx)
209 {
210         if (ctx == YACA_CONTEXT_NULL)
211                 return NULL;
212
213         switch (ctx->type) {
214         case YACA_CONTEXT_ENCRYPT:
215                 return (struct yaca_encrypt_context_s *)ctx;
216         default:
217                 return NULL;
218         }
219 }
220
221 void destroy_encrypt_context(const yaca_context_h ctx)
222 {
223         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
224
225         if (c == NULL)
226                 return;
227
228         if (c->backup_ctx != NULL) {
229                 yaca_key_destroy(c->backup_ctx->iv);
230                 yaca_key_destroy(c->backup_ctx->sym_key);
231                 yaca_free(c->backup_ctx);
232                 c->backup_ctx = NULL;
233         }
234
235         EVP_CIPHER_CTX_free(c->cipher_ctx);
236         c->cipher_ctx = NULL;
237 }
238
239 int get_encrypt_output_length(const yaca_context_h ctx, size_t input_len, size_t *output_len)
240 {
241         assert(output_len != NULL);
242
243         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
244         int block_size;
245
246         if (c == NULL)
247                 return YACA_ERROR_INVALID_PARAMETER;
248         assert(c->cipher_ctx != NULL);
249
250         block_size = EVP_CIPHER_CTX_block_size(c->cipher_ctx);
251         if (block_size <= 0) {
252                 ERROR_DUMP(YACA_ERROR_INTERNAL);
253                 return YACA_ERROR_INTERNAL;
254         }
255
256         if (input_len > 0) {
257                 if ((size_t)block_size > SIZE_MAX - input_len + 1)
258                         return YACA_ERROR_INVALID_PARAMETER;
259
260                 *output_len = block_size + input_len - 1;
261         } else {
262                 *output_len = block_size;
263         }
264         if (*output_len == 0)
265                 return YACA_ERROR_INTERNAL;
266
267         return YACA_ERROR_NONE;
268 }
269
270 int get_wrap_output_length(const yaca_context_h ctx, size_t input_len, size_t *output_len)
271 {
272         assert(output_len != NULL);
273
274         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
275         if (c == NULL)
276                 return YACA_ERROR_INVALID_PARAMETER;
277         assert(c->cipher_ctx != NULL);
278
279         bool encryption = is_encryption_op(c->op_type);
280         int type = EVP_CIPHER_CTX_type(c->cipher_ctx);
281
282         if (input_len > 0) {
283                 if (type == NID_id_aes128_wrap || type == NID_id_aes192_wrap || type == NID_id_aes256_wrap) {
284                         *output_len = encryption ? input_len + 8 : input_len - 8;
285                 } else if (type == NID_id_smime_alg_CMS3DESwrap) {
286                         *output_len = encryption ? input_len + 16 : input_len - 16;
287                 } else {
288                         assert(false);
289                         return YACA_ERROR_INTERNAL;
290                 }
291         } else {
292                 *output_len = 0;
293         }
294
295         return YACA_ERROR_NONE;
296 }
297
298 static int encrypt_ctx_create(struct yaca_encrypt_context_s **c,
299                               enum encrypt_op_type_e op_type,
300                               const EVP_CIPHER *cipher)
301 {
302         int ret;
303         int mode;
304         struct yaca_encrypt_context_s *nc;
305
306         assert(c != NULL);
307         assert(cipher != NULL);
308
309         ret = yaca_zalloc(sizeof(struct yaca_encrypt_context_s), (void**)&nc);
310         if (ret != YACA_ERROR_NONE)
311                 return ret;
312
313         mode = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
314
315         nc->ctx.type = YACA_CONTEXT_ENCRYPT;
316         nc->backup_ctx = NULL;
317         nc->ctx.context_destroy = destroy_encrypt_context;
318         nc->ctx.get_output_length = (mode == EVP_CIPH_WRAP_MODE) ?
319                                     get_wrap_output_length :
320                                     get_encrypt_output_length;
321         nc->ctx.set_property = set_encrypt_property;
322         nc->ctx.get_property = get_encrypt_property;
323         nc->op_type = op_type;
324         nc->tag_len = 0;
325
326         /* set default tag length for GCM and CCM */
327         if (mode == EVP_CIPH_GCM_MODE)
328                 nc->tag_len = DEFAULT_GCM_TAG_LEN;
329         else if (mode == EVP_CIPH_CCM_MODE)
330                 nc->tag_len = DEFAULT_CCM_TAG_LEN;
331
332         nc->cipher_ctx = EVP_CIPHER_CTX_new();
333         if (nc->cipher_ctx == NULL) {
334                 ret =  YACA_ERROR_INTERNAL;
335                 ERROR_DUMP(ret);
336                 goto exit;
337         }
338
339         if (mode == EVP_CIPH_WRAP_MODE)
340                 EVP_CIPHER_CTX_set_flags(nc->cipher_ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
341
342         *c = nc;
343         nc = NULL;
344
345         ret = YACA_ERROR_NONE;
346
347 exit:
348         yaca_free(nc);
349         return ret;
350 }
351
352 static int encrypt_ctx_init(struct yaca_encrypt_context_s *c,
353                             const EVP_CIPHER *cipher,
354                             size_t key_bit_len)
355 {
356         int ret;
357
358         assert(c != NULL);
359         assert(cipher != NULL);
360
361         if (key_bit_len / 8 > INT_MAX)
362                 return YACA_ERROR_INVALID_PARAMETER;
363
364         ret = EVP_CipherInit_ex(c->cipher_ctx,
365                                 cipher,
366                                 NULL,
367                                 NULL,
368                                 NULL,
369                                 is_encryption_op(c->op_type) ? 1 : 0);
370         if (ret != 1) {
371                 ret = YACA_ERROR_INTERNAL;
372                 ERROR_DUMP(ret);
373                 return ret;
374         }
375
376         /* Handling of algorithms with variable key length */
377         ret = EVP_CIPHER_CTX_set_key_length(c->cipher_ctx, key_bit_len / 8);
378         if (ret != 1) {
379                 ret = YACA_ERROR_INVALID_PARAMETER;
380                 ERROR_CLEAR();
381                 return ret;
382         }
383
384         return YACA_ERROR_NONE;
385 }
386
387 static int encrypt_ctx_setup_iv(struct yaca_encrypt_context_s *c,
388                                 const EVP_CIPHER *cipher,
389                                 const struct yaca_key_simple_s *iv)
390 {
391         int ret;
392         size_t default_iv_bit_len;
393
394         assert(c != NULL);
395         assert(cipher != NULL);
396
397         ret = EVP_CIPHER_iv_length(cipher);
398         if (ret < 0) {
399                 ret = YACA_ERROR_INTERNAL;
400                 ERROR_DUMP(ret);
401                 return ret;
402         }
403
404         default_iv_bit_len = ret * 8;
405
406         /* 0 -> cipher doesn't use iv, but it was provided */
407         if (default_iv_bit_len == 0 && iv != NULL)
408                 return YACA_ERROR_INVALID_PARAMETER;
409
410         if (default_iv_bit_len != 0) { /* cipher requires iv */
411                  /* iv was not provided */
412                 if (iv == NULL || iv->key.type != YACA_KEY_TYPE_IV)
413                         return YACA_ERROR_INVALID_PARAMETER;
414
415                 if (iv->bit_len / 8 > INT_MAX)
416                         return YACA_ERROR_INVALID_PARAMETER;
417
418                 /* IV length doesn't match cipher (GCM & CCM supports variable IV length) */
419                 if (default_iv_bit_len != iv->bit_len) {
420                         int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
421
422                         if (mode == EVP_CIPH_GCM_MODE) {
423                                 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_GCM_SET_IVLEN,
424                                                           iv->bit_len / 8, NULL);
425                         } else if (mode == EVP_CIPH_CCM_MODE) {
426                                 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_IVLEN,
427                                                           iv->bit_len / 8, NULL);
428                         } else {
429                                 return YACA_ERROR_INVALID_PARAMETER;
430                         }
431
432                         if (ret != 1)
433                                 return YACA_ERROR_INVALID_PARAMETER;
434                 }
435         }
436
437         return YACA_ERROR_NONE;
438 }
439
440 static int encrypt_ctx_setup(struct yaca_encrypt_context_s *c,
441                              const yaca_key_h key,
442                              const yaca_key_h iv)
443 {
444         int ret;
445         unsigned char *iv_data = NULL;
446         const struct yaca_key_simple_s *lkey;
447         const struct yaca_key_simple_s *liv;
448
449         assert(c != NULL);
450         assert(key != YACA_KEY_NULL);
451
452         const EVP_CIPHER *cipher = EVP_CIPHER_CTX_cipher(c->cipher_ctx);
453
454         if (cipher == NULL)
455                 return YACA_ERROR_INTERNAL;
456
457         lkey = key_get_simple(key);
458         if (lkey == NULL)
459                 return YACA_ERROR_INVALID_PARAMETER;
460
461         liv = key_get_simple(iv);
462
463         ret = encrypt_ctx_setup_iv(c, cipher, liv);
464         if (ret != YACA_ERROR_NONE)
465                 return ret;
466
467         /* Fix for OpenSSL error in 3DES CFB1 */
468         int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
469         if (nid == NID_des_ede3_cfb1)
470                 EVP_CIPHER_CTX_set_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS);
471
472         if (liv != NULL)
473                 iv_data = (unsigned char*)liv->d;
474
475         ret = EVP_CipherInit_ex(c->cipher_ctx,
476                                 NULL,
477                                 NULL,
478                                 (unsigned char*)lkey->d,
479                                 iv_data,
480                                 is_encryption_op(c->op_type) ? 1 : 0);
481         if (ret != 1) {
482                 ret = YACA_ERROR_INTERNAL;
483                 ERROR_DUMP(ret);
484                 return ret;
485         }
486
487         return YACA_ERROR_NONE;
488 }
489
490 static int encrypt_ctx_backup(struct yaca_encrypt_context_s *c,
491                               const EVP_CIPHER *cipher,
492                               const yaca_key_h sym_key,
493                               const yaca_key_h iv)
494 {
495         int ret;
496         struct yaca_backup_context_s *bc;
497
498         assert(c != NULL);
499         assert(cipher != NULL);
500         assert(sym_key != YACA_KEY_NULL);
501         assert(c->backup_ctx == NULL);
502
503         ret = yaca_zalloc(sizeof(struct yaca_backup_context_s), (void**)&bc);
504         if (ret != YACA_ERROR_NONE)
505                 return ret;
506
507         bc->cipher = cipher;
508         bc->sym_key = key_copy(sym_key);
509         bc->iv = key_copy(iv);
510         bc->padding = YACA_PADDING_PKCS7;
511
512         c->backup_ctx = bc;
513
514         return YACA_ERROR_NONE;
515 }
516
517 static int encrypt_ctx_restore(struct yaca_encrypt_context_s *c)
518 {
519         int ret;
520         struct yaca_key_simple_s *key;
521
522         assert(c != NULL);
523         assert(c->backup_ctx != NULL);
524
525         ret = EVP_CIPHER_CTX_cleanup(c->cipher_ctx);
526         if (ret != 1) {
527                 ret = YACA_ERROR_INTERNAL;
528                 ERROR_DUMP(ret);
529                 return ret;
530         }
531
532         key = key_get_simple(c->backup_ctx->sym_key);
533         if (key == NULL)
534                 return YACA_ERROR_INVALID_PARAMETER;
535
536         ret = encrypt_ctx_init(c, c->backup_ctx->cipher, key->bit_len);
537         assert(ret != YACA_ERROR_INVALID_PARAMETER);
538
539         if (c->backup_ctx->padding == YACA_PADDING_NONE &&
540             EVP_CIPHER_CTX_set_padding(c->cipher_ctx, 0) != 1) {
541                 ret = YACA_ERROR_INTERNAL;
542                 ERROR_DUMP(ret);
543                 return ret;
544         }
545
546         return ret;
547 }
548
549 static int encrypt_ctx_set_ccm_tag_len(struct yaca_encrypt_context_s *c, size_t tag_len)
550 {
551         int ret;
552
553         assert(c != NULL);
554         assert(c->backup_ctx != NULL);
555         assert(is_encryption_op(c->op_type));
556
557         if (tag_len == 0 || tag_len > INT_MAX)
558                 return YACA_ERROR_INVALID_PARAMETER;
559
560         ret = encrypt_ctx_restore(c);
561         if (ret != YACA_ERROR_NONE)
562                 return ret;
563
564         c->tag_len = tag_len;
565         ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL);
566         if (ret != 1) {
567                 ret = YACA_ERROR_INTERNAL;
568                 ERROR_DUMP(ret);
569                 return ret;
570         }
571
572         ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
573         assert(ret != YACA_ERROR_INVALID_PARAMETER);
574         return ret;
575 }
576
577 static int encrypt_ctx_set_ccm_tag(struct yaca_encrypt_context_s *c, char *tag, size_t tag_len)
578 {
579         int ret;
580
581         assert(c != NULL);
582         assert(c->backup_ctx != NULL);
583         assert(!is_encryption_op(c->op_type));
584         assert(tag != NULL);
585
586         if (tag_len == 0 || tag_len > INT_MAX)
587                 return YACA_ERROR_INVALID_PARAMETER;
588
589         ret = encrypt_ctx_restore(c);
590         if (ret != YACA_ERROR_NONE)
591                 return ret;
592
593         ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag);
594         if (ret != 1) {
595                 ret = YACA_ERROR_INTERNAL;
596                 ERROR_DUMP(ret);
597                 return ret;
598         }
599
600         ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
601         assert(ret != YACA_ERROR_INVALID_PARAMETER);
602         return ret;
603 }
604
605 static int encrypt_ctx_set_rc2_effective_key_bits(struct yaca_encrypt_context_s *c, size_t key_bits)
606 {
607         int ret;
608
609         assert(c != NULL);
610         assert(c->backup_ctx != NULL);
611
612         if (key_bits == 0 || key_bits > 1024)
613                 return YACA_ERROR_INVALID_PARAMETER;
614
615         ret = encrypt_ctx_restore(c);
616         if (ret != YACA_ERROR_NONE)
617                 return ret;
618
619         ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
620         if (ret != 1) {
621                 ret = YACA_ERROR_INTERNAL;
622                 ERROR_DUMP(ret);
623                 return ret;
624         }
625
626         ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
627         assert(ret != YACA_ERROR_INVALID_PARAMETER);
628         return ret;
629 }
630
631 int set_encrypt_property(yaca_context_h ctx,
632                          yaca_property_e property,
633                          const void *value,
634                          size_t value_len)
635 {
636         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
637         int len;
638         int ret = YACA_ERROR_NONE;
639         int mode;
640         int nid;
641
642         if (c == NULL || value == NULL || value_len == 0)
643                 return YACA_ERROR_INVALID_PARAMETER;
644         assert(c->cipher_ctx != NULL);
645
646         mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
647         nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
648
649         switch (property) {
650         case YACA_PROPERTY_GCM_AAD:
651                 if (mode != EVP_CIPH_GCM_MODE)
652                         return YACA_ERROR_INVALID_PARAMETER;
653
654                 if (!verify_state_change(c, STATE_AAD_UPDATED))
655                         return YACA_ERROR_INVALID_PARAMETER;
656
657                 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
658                         ERROR_DUMP(YACA_ERROR_INTERNAL);
659                         return YACA_ERROR_INTERNAL;
660                 }
661                 c->state = STATE_AAD_UPDATED;
662                 break;
663         case YACA_PROPERTY_CCM_AAD:
664                 if (mode != EVP_CIPH_CCM_MODE)
665                         return YACA_ERROR_INVALID_PARAMETER;
666
667                 if (!verify_state_change(c, STATE_AAD_UPDATED))
668                         return YACA_ERROR_INVALID_PARAMETER;
669
670                 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
671                         ERROR_DUMP(YACA_ERROR_INTERNAL);
672                         return YACA_ERROR_INTERNAL;
673                 }
674                 c->state = STATE_AAD_UPDATED;
675                 break;
676         case YACA_PROPERTY_GCM_TAG:
677                 if (mode != EVP_CIPH_GCM_MODE || is_encryption_op(c->op_type) ||
678                     value_len == 0 || value_len > INT_MAX)
679                         return YACA_ERROR_INVALID_PARAMETER;
680
681                 if (!verify_state_change(c, STATE_TAG_SET))
682                         return YACA_ERROR_INVALID_PARAMETER;
683
684                 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
685                                         EVP_CTRL_GCM_SET_TAG,
686                                         value_len,
687                                         (void*)value) != 1) {
688                         ERROR_DUMP(YACA_ERROR_INTERNAL);
689                         return YACA_ERROR_INTERNAL;
690                 }
691                 c->state = STATE_TAG_SET;
692                 break;
693         case YACA_PROPERTY_GCM_TAG_LEN:
694                 if (value_len != sizeof(size_t) || mode != EVP_CIPH_GCM_MODE ||
695                     !is_encryption_op(c->op_type) ||
696                     *(size_t*)value == 0 || *(size_t*)value > INT_MAX)
697                         return YACA_ERROR_INVALID_PARAMETER;
698
699                 if (!verify_state_change(c, STATE_TAG_LENGTH_SET))
700                         return YACA_ERROR_INVALID_PARAMETER;
701
702                 /* check allowed tag lengths */
703                 {
704                         size_t tag_len = *(size_t*)value;
705                         for (size_t i = 0; i < VALID_GCM_TAG_LENGTHS_LENGTH; i++) {
706                                 if (tag_len == VALID_GCM_TAG_LENGTHS[i]) {
707                                         c->tag_len = tag_len;
708                                         c->state = STATE_TAG_LENGTH_SET;
709                                         return YACA_ERROR_NONE;
710                                 }
711                         }
712                         return YACA_ERROR_INVALID_PARAMETER;
713                 }
714                 break;
715         case YACA_PROPERTY_CCM_TAG:
716                 if (mode != EVP_CIPH_CCM_MODE || is_encryption_op(c->op_type))
717                         return YACA_ERROR_INVALID_PARAMETER;
718
719                 if (!verify_state_change(c, STATE_TAG_SET))
720                         return YACA_ERROR_INVALID_PARAMETER;
721
722                 ret = encrypt_ctx_set_ccm_tag(c, (char*)value, value_len);
723                 if (ret != YACA_ERROR_NONE)
724                         return ret;
725
726                 c->state = STATE_TAG_SET;
727                 break;
728         case YACA_PROPERTY_CCM_TAG_LEN:
729                 if (value_len != sizeof(size_t) || mode != EVP_CIPH_CCM_MODE ||
730                     !is_encryption_op(c->op_type))
731                         return YACA_ERROR_INVALID_PARAMETER;
732
733                 if (!verify_state_change(c, STATE_TAG_LENGTH_SET))
734                         return YACA_ERROR_INVALID_PARAMETER;
735
736                 ret = encrypt_ctx_set_ccm_tag_len(c, *(size_t*)value);
737                 if (ret != YACA_ERROR_NONE)
738                         return ret;
739
740                 c->state = STATE_TAG_LENGTH_SET;
741                 break;
742         case YACA_PROPERTY_PADDING:
743                 if ((mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE) ||
744                     value_len != sizeof(yaca_padding_e) ||
745                     (*(yaca_padding_e*)value != YACA_PADDING_NONE &&
746                     *(yaca_padding_e*)value != YACA_PADDING_PKCS7) ||
747                     c->state == STATE_FINALIZED)
748                         return YACA_ERROR_INVALID_PARAMETER;
749
750                 int padding = *(yaca_padding_e*)value == YACA_PADDING_NONE ? 0 : 1;
751                 if (EVP_CIPHER_CTX_set_padding(c->cipher_ctx, padding) != 1) {
752                         ERROR_DUMP(YACA_ERROR_INTERNAL);
753                         return YACA_ERROR_INTERNAL;
754                 }
755                 if (c->backup_ctx != NULL)
756                         c->backup_ctx->padding = padding;
757                 break;
758         case YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS:
759                 if (value_len != sizeof(size_t) ||
760                     (nid != NID_rc2_cbc && nid != NID_rc2_ecb && nid != NID_rc2_cfb64 && nid != NID_rc2_ofb64) ||
761                     c->state != STATE_INITIALIZED)
762                         return YACA_ERROR_INVALID_PARAMETER;
763
764                 ret = encrypt_ctx_set_rc2_effective_key_bits(c, *(size_t*)value);
765                 break;
766         default:
767                 return YACA_ERROR_INVALID_PARAMETER;
768         }
769
770         return ret;
771 }
772
773 int get_encrypt_property(const yaca_context_h ctx, yaca_property_e property,
774                          void **value, size_t *value_len)
775 {
776         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
777         int mode;
778
779         if (c == NULL || value == NULL)
780                 return YACA_ERROR_INVALID_PARAMETER;
781         assert(c->cipher_ctx != NULL);
782
783         mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
784
785         switch (property) {
786         case YACA_PROPERTY_GCM_TAG:
787                 if (value_len == NULL ||
788                     !is_encryption_op(c->op_type) ||
789                     mode != EVP_CIPH_GCM_MODE ||
790                     (c->state != STATE_TAG_LENGTH_SET && c->state != STATE_FINALIZED))
791                         return YACA_ERROR_INVALID_PARAMETER;
792
793                 assert(c->tag_len <= INT_MAX);
794
795                 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
796                                         EVP_CTRL_GCM_GET_TAG,
797                                         c->tag_len,
798                                         value) != 1) {
799                         ERROR_DUMP(YACA_ERROR_INTERNAL);
800                         return YACA_ERROR_INTERNAL;
801                 }
802                 *value_len = c->tag_len;
803                 break;
804         case YACA_PROPERTY_CCM_TAG:
805                 if (value_len == NULL ||
806                     !is_encryption_op(c->op_type) ||
807                     mode != EVP_CIPH_CCM_MODE ||
808                     c->state != STATE_FINALIZED)
809                         return YACA_ERROR_INVALID_PARAMETER;
810
811                 assert(c->tag_len <= INT_MAX);
812
813                 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
814                                         EVP_CTRL_CCM_GET_TAG,
815                                         c->tag_len,
816                                         value) != 1) {
817                         ERROR_DUMP(YACA_ERROR_INTERNAL);
818                         return YACA_ERROR_INTERNAL;
819                 }
820                 *value_len = c->tag_len;
821                 break;
822         default:
823                 return YACA_ERROR_INVALID_PARAMETER;
824                 break;
825         }
826
827         return YACA_ERROR_NONE;
828 }
829
830 static int check_key_bit_length_for_algo(yaca_encrypt_algorithm_e algo, size_t key_bit_len)
831 {
832         assert(key_bit_len % 8 == 0);
833         int ret = YACA_ERROR_NONE;
834
835         switch (algo) {
836         case YACA_ENCRYPT_AES:
837                 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
838                     key_bit_len != YACA_KEY_LENGTH_192BIT &&
839                     key_bit_len != YACA_KEY_LENGTH_256BIT)
840                         ret = YACA_ERROR_INVALID_PARAMETER;
841                 break;
842         case YACA_ENCRYPT_UNSAFE_DES:
843                 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT)
844                         ret = YACA_ERROR_INVALID_PARAMETER;
845                 break;
846         case YACA_ENCRYPT_UNSAFE_3DES_2TDEA:
847                 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT)
848                         ret = YACA_ERROR_INVALID_PARAMETER;
849                 break;
850         case YACA_ENCRYPT_3DES_3TDEA:
851                 if (key_bit_len != YACA_KEY_LENGTH_192BIT)
852                         ret = YACA_ERROR_INVALID_PARAMETER;
853                 break;
854         case YACA_ENCRYPT_UNSAFE_RC2:
855                 if (key_bit_len < YACA_KEY_LENGTH_UNSAFE_8BIT || key_bit_len > YACA_KEY_LENGTH_1024BIT)
856                         ret = YACA_ERROR_INVALID_PARAMETER;
857                 break;
858         case YACA_ENCRYPT_UNSAFE_RC4:
859                 if (key_bit_len < YACA_KEY_LENGTH_UNSAFE_40BIT || key_bit_len > YACA_KEY_LENGTH_2048BIT)
860                         ret = YACA_ERROR_INVALID_PARAMETER;
861                 break;
862         case YACA_ENCRYPT_CAST5:
863                 if (key_bit_len < YACA_KEY_LENGTH_UNSAFE_40BIT || key_bit_len > YACA_KEY_LENGTH_UNSAFE_128BIT)
864                         ret = YACA_ERROR_INVALID_PARAMETER;
865                 break;
866         default:
867                 ret = YACA_ERROR_INVALID_PARAMETER;
868                 break;
869         }
870
871         return ret;
872 }
873
874 int encrypt_get_algorithm(yaca_encrypt_algorithm_e algo,
875                           yaca_block_cipher_mode_e bcm,
876                           size_t key_bit_len,
877                           const EVP_CIPHER **cipher)
878 {
879         int ret;
880         size_t i;
881
882         assert(cipher != NULL);
883
884         ret = check_key_bit_length_for_algo(algo, key_bit_len);
885         if (ret != YACA_ERROR_NONE)
886                 return ret;
887
888         *cipher = NULL;
889         ret = YACA_ERROR_INVALID_PARAMETER;
890
891         for (i = 0; i < ENCRYPTION_CIPHERS_SIZE; ++i)
892                 if (ENCRYPTION_CIPHERS[i].algo == algo &&
893                     ENCRYPTION_CIPHERS[i].bcm == bcm &&
894                     (ENCRYPTION_CIPHERS[i].key_bit_len == key_bit_len ||
895                      ENCRYPTION_CIPHERS[i].key_bit_len == (size_t)-1)) {
896                         *cipher = ENCRYPTION_CIPHERS[i].cipher();
897                         ret = YACA_ERROR_NONE;
898                         break;
899                 }
900
901         if (ret == YACA_ERROR_NONE && *cipher == NULL) {
902                 ret = YACA_ERROR_INTERNAL;
903                 ERROR_DUMP(ret);
904         }
905
906         return ret;
907 }
908
909 int encrypt_initialize(yaca_context_h *ctx,
910                        const EVP_CIPHER *cipher,
911                        const yaca_key_h sym_key,
912                        const yaca_key_h iv,
913                        enum encrypt_op_type_e op_type)
914 {
915         struct yaca_encrypt_context_s *nc;
916         struct yaca_key_simple_s *lsym_key;
917         int ret;
918         int mode;
919         int nid;
920
921         if (ctx == NULL || sym_key == YACA_KEY_NULL)
922                 return YACA_ERROR_INVALID_PARAMETER;
923
924         lsym_key = key_get_simple(sym_key);
925         if (lsym_key == NULL)
926                 return YACA_ERROR_INVALID_PARAMETER;
927
928         if (lsym_key->key.type != YACA_KEY_TYPE_DES &&
929             lsym_key->key.type != YACA_KEY_TYPE_SYMMETRIC)
930                 return YACA_ERROR_INVALID_PARAMETER;
931
932         ret = encrypt_ctx_create(&nc, op_type, cipher);
933         if (ret != YACA_ERROR_NONE)
934                 return ret;
935
936         ret = encrypt_ctx_init(nc, cipher, lsym_key->bit_len);
937         if (ret != YACA_ERROR_NONE)
938                 goto exit;
939
940         ret = encrypt_ctx_setup(nc, sym_key, iv);
941         if (ret != YACA_ERROR_NONE)
942                 goto exit;
943
944         mode = EVP_CIPHER_CTX_mode(nc->cipher_ctx);
945         nid = EVP_CIPHER_CTX_nid(nc->cipher_ctx);
946         if (mode == EVP_CIPH_CCM_MODE ||
947             nid == NID_rc2_cbc || nid == NID_rc2_ecb || nid == NID_rc2_cfb64 || nid == NID_rc2_ofb64) {
948                 ret = encrypt_ctx_backup(nc, cipher, sym_key, iv);
949                 if (ret != YACA_ERROR_NONE)
950                         goto exit;
951         }
952
953         nc->state = STATE_INITIALIZED;
954
955         *ctx = (yaca_context_h)nc;
956         nc = NULL;
957         ret = YACA_ERROR_NONE;
958
959 exit:
960         yaca_context_destroy((yaca_context_h)nc);
961
962         return ret;
963 }
964
965 int encrypt_update(yaca_context_h ctx,
966                    const unsigned char *input, size_t input_len,
967                    unsigned char *output, size_t *output_len,
968                    enum encrypt_op_type_e op_type)
969 {
970         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
971         int ret;
972         int loutput_len;
973         int mode;
974         int type;
975
976         if (c == NULL || input_len == 0 || output_len == NULL || op_type != c->op_type)
977                 return YACA_ERROR_INVALID_PARAMETER;
978
979         mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
980         type = EVP_CIPHER_CTX_type(c->cipher_ctx);
981
982         enum encrypt_context_state_e target_state;
983         if (output == NULL && input == NULL)
984                 target_state = STATE_MSG_LENGTH_UPDATED;
985         else if (output == NULL)
986                 target_state = STATE_AAD_UPDATED;
987         else if (input == NULL)
988                 return YACA_ERROR_INVALID_PARAMETER;
989         else
990                 target_state = STATE_MSG_UPDATED;
991
992         if (!verify_state_change(c, target_state))
993                 return YACA_ERROR_INVALID_PARAMETER;
994
995         if (mode == EVP_CIPH_WRAP_MODE) {
996                 if (op_type == OP_ENCRYPT) {
997                         if (type == NID_id_aes128_wrap || type == NID_id_aes192_wrap || type == NID_id_aes256_wrap) {
998                                 if (input_len % 8 != 0 || input_len < (YACA_KEY_LENGTH_UNSAFE_128BIT / 8))
999                                         return YACA_ERROR_INVALID_PARAMETER;
1000                         } else if (type == NID_id_smime_alg_CMS3DESwrap) {
1001                                 if (input_len != (YACA_KEY_LENGTH_UNSAFE_128BIT / 8) &&
1002                                     input_len != (YACA_KEY_LENGTH_192BIT / 8))
1003                                         return YACA_ERROR_INVALID_PARAMETER;
1004                         } else {
1005                                 assert(false);
1006                                 return YACA_ERROR_INTERNAL;
1007                         }
1008                 } else if (op_type == OP_DECRYPT) {
1009                         if (type == NID_id_aes128_wrap || type == NID_id_aes192_wrap || type == NID_id_aes256_wrap) {
1010                                 if (input_len % 8 != 0 || input_len < (YACA_KEY_LENGTH_UNSAFE_128BIT / 8 + 8))
1011                                         return YACA_ERROR_INVALID_PARAMETER;
1012                         } else if (type == NID_id_smime_alg_CMS3DESwrap) {
1013                                 if (input_len != (YACA_KEY_LENGTH_UNSAFE_128BIT / 8 + 16) &&
1014                                     input_len != (YACA_KEY_LENGTH_192BIT / 8 + 16))
1015                                         return YACA_ERROR_INVALID_PARAMETER;
1016                         } else {
1017                                 assert(false);
1018                                 return YACA_ERROR_INTERNAL;
1019                         }
1020                 } else {
1021                         assert(false);
1022                         return YACA_ERROR_INTERNAL;
1023                 }
1024         }
1025
1026         /* Fix for OpenSSL error in 3DES CFB1 */
1027         if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) {
1028                 if (input_len > INT_MAX / 8)
1029                         return YACA_ERROR_INVALID_PARAMETER;
1030                 input_len *= 8;
1031         }
1032
1033         ret = EVP_CipherUpdate(c->cipher_ctx, output, &loutput_len, input, input_len);
1034         if (ret != 1 || loutput_len < 0) {
1035                 ret = YACA_ERROR_INTERNAL;
1036                 ERROR_DUMP(ret);
1037                 return ret;
1038         }
1039
1040         *output_len = loutput_len;
1041
1042         c->state = target_state;
1043
1044         /* Fix for OpenSSL error in 3DES CFB1 */
1045         if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0)
1046                 *output_len /= 8;
1047
1048         return YACA_ERROR_NONE;
1049 }
1050
1051 int encrypt_finalize(yaca_context_h ctx,
1052                      unsigned char *output, size_t *output_len,
1053                      enum encrypt_op_type_e op_type)
1054 {
1055         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1056         int ret;
1057         int loutput_len = 0;
1058
1059         if (c == NULL || output == NULL || output_len == NULL || op_type != c->op_type)
1060                 return YACA_ERROR_INVALID_PARAMETER;
1061
1062         if (!verify_state_change(c, STATE_FINALIZED))
1063                 return YACA_ERROR_INVALID_PARAMETER;
1064
1065         if (EVP_CIPHER_CTX_mode(c->cipher_ctx) != EVP_CIPH_WRAP_MODE) {
1066                 ret = EVP_CipherFinal(c->cipher_ctx, output, &loutput_len);
1067                 if (ret != 1 || loutput_len < 0)
1068                         return ERROR_HANDLE();
1069         }
1070
1071         *output_len = loutput_len;
1072
1073         /* Fix for OpenSSL error in 3DES CFB1 */
1074         if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0)
1075                 *output_len /= 8;
1076
1077         c->state = STATE_FINALIZED;
1078         return YACA_ERROR_NONE;
1079 }
1080
1081 API int yaca_encrypt_get_iv_bit_length(yaca_encrypt_algorithm_e algo,
1082                                        yaca_block_cipher_mode_e bcm,
1083                                        size_t key_bit_len,
1084                                        size_t *iv_bit_len)
1085 {
1086         const EVP_CIPHER *cipher;
1087         int ret;
1088
1089         if (iv_bit_len == NULL)
1090                 return YACA_ERROR_INVALID_PARAMETER;
1091
1092         ret = encrypt_get_algorithm(algo, bcm, key_bit_len, &cipher);
1093         if (ret != YACA_ERROR_NONE)
1094                 return ret;
1095
1096         ret = EVP_CIPHER_iv_length(cipher);
1097         if (ret < 0) {
1098                 ERROR_DUMP(YACA_ERROR_INTERNAL);
1099                 return YACA_ERROR_INTERNAL;
1100         }
1101
1102         *iv_bit_len = ret * 8;
1103         return YACA_ERROR_NONE;
1104 }
1105
1106 API int yaca_encrypt_initialize(yaca_context_h *ctx,
1107                                 yaca_encrypt_algorithm_e algo,
1108                                 yaca_block_cipher_mode_e bcm,
1109                                 const yaca_key_h sym_key,
1110                                 const yaca_key_h iv)
1111 {
1112         int ret;
1113         const EVP_CIPHER *cipher;
1114         struct yaca_key_simple_s *key = key_get_simple(sym_key);
1115
1116         if (key == NULL)
1117                 return YACA_ERROR_INVALID_PARAMETER;
1118
1119         ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1120         if (ret != YACA_ERROR_NONE)
1121                 return ret;
1122
1123         return encrypt_initialize(ctx, cipher, sym_key, iv, OP_ENCRYPT);
1124 }
1125
1126 API int yaca_encrypt_update(yaca_context_h ctx,
1127                             const char *plaintext,
1128                             size_t plaintext_len,
1129                             char *ciphertext,
1130                             size_t *ciphertext_len)
1131 {
1132         return encrypt_update(ctx, (const unsigned char*)plaintext, plaintext_len,
1133                               (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
1134 }
1135
1136 API int yaca_encrypt_finalize(yaca_context_h ctx,
1137                               char *ciphertext,
1138                               size_t *ciphertext_len)
1139 {
1140         return encrypt_finalize(ctx, (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
1141 }
1142
1143 API int yaca_decrypt_initialize(yaca_context_h *ctx,
1144                                 yaca_encrypt_algorithm_e algo,
1145                                 yaca_block_cipher_mode_e bcm,
1146                                 const yaca_key_h sym_key,
1147                                 const yaca_key_h iv)
1148 {
1149         int ret;
1150         const EVP_CIPHER *cipher;
1151         struct yaca_key_simple_s *key = key_get_simple(sym_key);
1152
1153         if (key == NULL)
1154                 return YACA_ERROR_INVALID_PARAMETER;
1155
1156         ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1157         if (ret != YACA_ERROR_NONE)
1158                 return ret;
1159
1160         return encrypt_initialize(ctx, cipher, sym_key, iv, OP_DECRYPT);
1161 }
1162
1163 API int yaca_decrypt_update(yaca_context_h ctx,
1164                             const char *ciphertext,
1165                             size_t ciphertext_len,
1166                             char *plaintext,
1167                             size_t *plaintext_len)
1168 {
1169         return encrypt_update(ctx, (const unsigned char*)ciphertext, ciphertext_len,
1170                               (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);
1171 }
1172
1173 API int yaca_decrypt_finalize(yaca_context_h ctx,
1174                               char *plaintext,
1175                               size_t *plaintext_len)
1176 {
1177         return encrypt_finalize(ctx, (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);
1178 }