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