Remove support for OpenSSL 1.0.x, it's EOL
[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 (liv != NULL)
530                 iv_data = (unsigned char*)liv->d;
531
532         ret = EVP_CipherInit_ex(c->cipher_ctx,
533                                                         NULL,
534                                                         NULL,
535                                                         (unsigned char*)lkey->d,
536                                                         iv_data,
537                                                         is_encryption_op(c->op_type) ? 1 : 0);
538         if (ret != 1) {
539                 ret = YACA_ERROR_INTERNAL;
540                 ERROR_DUMP(ret);
541                 return ret;
542         }
543
544         return YACA_ERROR_NONE;
545 }
546
547 static int key_copy_simple(const yaca_key_h key, yaca_key_h *out)
548 {
549         assert(key != YACA_KEY_NULL);
550         assert(out != NULL);
551
552         int ret;
553         struct yaca_key_simple_s *simple = key_get_simple(key);
554         assert(simple != NULL);
555
556         struct yaca_key_simple_s *copy;
557         size_t size = sizeof(struct yaca_key_simple_s) + simple->bit_len / 8;
558
559         ret = yaca_zalloc(size, (void**)&copy);
560         if (ret != YACA_ERROR_NONE)
561                 return ret;
562
563         memcpy(copy, key, size);
564         *out = (yaca_key_h)copy;
565         return YACA_ERROR_NONE;
566 }
567
568 static int encrypt_ctx_backup(struct yaca_encrypt_context_s *c,
569                                                           const EVP_CIPHER *cipher,
570                                                           const yaca_key_h sym_key,
571                                                           const yaca_key_h iv)
572 {
573         int ret;
574         struct yaca_backup_context_s *bc;
575
576         assert(c != NULL);
577         assert(cipher != NULL);
578         assert(sym_key != YACA_KEY_NULL);
579         assert(c->backup_ctx == NULL);
580
581         ret = yaca_zalloc(sizeof(struct yaca_backup_context_s), (void**)&bc);
582         if (ret != YACA_ERROR_NONE)
583                 return ret;
584
585         ret = key_copy_simple(sym_key, &bc->sym_key);
586         if (ret != YACA_ERROR_NONE)
587                 goto err;
588         if (iv != YACA_KEY_NULL) {
589                 ret = key_copy_simple(iv, &bc->iv);
590                 if (ret != YACA_ERROR_NONE)
591                         goto err;
592         }
593         bc->cipher = cipher;
594         bc->padding = YACA_PADDING_PKCS7;
595
596         c->backup_ctx = bc;
597
598         return YACA_ERROR_NONE;
599
600 err:
601         yaca_key_destroy(bc->iv);
602         yaca_key_destroy(bc->sym_key);
603         yaca_free(bc);
604         return ret;
605 }
606
607 static int encrypt_ctx_restore(struct yaca_encrypt_context_s *c)
608 {
609         int ret;
610         struct yaca_key_simple_s *key;
611
612         assert(c != NULL);
613         assert(c->backup_ctx != NULL);
614
615         ret = EVP_CIPHER_CTX_cleanup(c->cipher_ctx);
616         if (ret != 1) {
617                 ret = YACA_ERROR_INTERNAL;
618                 ERROR_DUMP(ret);
619                 return ret;
620         }
621
622         key = key_get_simple(c->backup_ctx->sym_key);
623         assert(key != NULL);
624
625         ret = encrypt_ctx_init(c, c->backup_ctx->cipher, key->bit_len);
626         assert(ret != YACA_ERROR_INVALID_PARAMETER);
627         if (ret != YACA_ERROR_NONE)
628                 return ret;
629
630         if (c->backup_ctx->padding == YACA_PADDING_NONE &&
631                 EVP_CIPHER_CTX_set_padding(c->cipher_ctx, 0) != 1) {
632                 ret = YACA_ERROR_INTERNAL;
633                 ERROR_DUMP(ret);
634                 return ret;
635         }
636
637         return ret;
638 }
639
640 static int encrypt_ctx_set_ccm_tag_len(struct yaca_encrypt_context_s *c, size_t tag_len)
641 {
642         int ret;
643
644         assert(c != NULL);
645         assert(c->backup_ctx != NULL);
646         assert(is_encryption_op(c->op_type));
647
648         ret = encrypt_ctx_restore(c);
649         if (ret != YACA_ERROR_NONE)
650                 return ret;
651
652         c->tag_len = tag_len;
653         ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL);
654         if (ret != 1) {
655                 ret = YACA_ERROR_INTERNAL;
656                 ERROR_DUMP(ret);
657                 return ret;
658         }
659
660         ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
661         assert(ret != YACA_ERROR_INVALID_PARAMETER);
662         return ret;
663 }
664
665 static int encrypt_ctx_set_ccm_tag(struct yaca_encrypt_context_s *c, char *tag, size_t tag_len)
666 {
667         int ret;
668
669         assert(c != NULL);
670         assert(c->backup_ctx != NULL);
671         assert(!is_encryption_op(c->op_type));
672         assert(tag != NULL);
673
674         ret = encrypt_ctx_restore(c);
675         if (ret != YACA_ERROR_NONE)
676                 return ret;
677
678         ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag);
679         if (ret != 1) {
680                 ret = YACA_ERROR_INTERNAL;
681                 ERROR_DUMP(ret);
682                 return ret;
683         }
684
685         ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
686         assert(ret != YACA_ERROR_INVALID_PARAMETER);
687         return ret;
688 }
689
690 static int encrypt_ctx_set_rc2_effective_key_bits(struct yaca_encrypt_context_s *c, size_t key_bits)
691 {
692         int ret;
693
694         assert(c != NULL);
695         assert(c->backup_ctx != NULL);
696
697         if (key_bits == 0 || key_bits > 1024)
698                 return YACA_ERROR_INVALID_PARAMETER;
699
700         ret = encrypt_ctx_restore(c);
701         if (ret != YACA_ERROR_NONE)
702                 return ret;
703
704         ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
705         if (ret != 1) {
706                 ret = YACA_ERROR_INTERNAL;
707                 ERROR_DUMP(ret);
708                 return ret;
709         }
710
711         ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
712         assert(ret != YACA_ERROR_INVALID_PARAMETER);
713         return ret;
714 }
715
716 static int set_encrypt_property(yaca_context_h ctx,
717                                                                 yaca_property_e property,
718                                                                 const void *value,
719                                                                 size_t value_len)
720 {
721         int len;
722         int ret = YACA_ERROR_NONE;
723         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
724         assert(c != NULL);
725         assert(c->cipher_ctx != NULL);
726
727         if (value == NULL || value_len == 0)
728                 return YACA_ERROR_INVALID_PARAMETER;
729
730         int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
731         int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
732
733         switch (property) {
734         case YACA_PROPERTY_GCM_AAD:
735                 if (mode != EVP_CIPH_GCM_MODE ||
736                         !verify_state_change(c, ENC_CTX_AAD_UPDATED))
737                         return YACA_ERROR_INVALID_PARAMETER;
738
739                 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
740                         ret = YACA_ERROR_INTERNAL;
741                         ERROR_DUMP(ret);
742                         return ret;
743                 }
744                 c->state = ENC_CTX_AAD_UPDATED;
745                 break;
746         case YACA_PROPERTY_CCM_AAD:
747                 if (mode != EVP_CIPH_CCM_MODE ||
748                         !verify_state_change(c, ENC_CTX_AAD_UPDATED))
749                         return YACA_ERROR_INVALID_PARAMETER;
750
751                 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
752                         ret = YACA_ERROR_INTERNAL;
753                         ERROR_DUMP(ret);
754                         return ret;
755                 }
756                 c->state = ENC_CTX_AAD_UPDATED;
757                 break;
758         case YACA_PROPERTY_GCM_TAG:
759                 if (mode != EVP_CIPH_GCM_MODE || is_encryption_op(c->op_type) ||
760                         !is_valid_tag_len(mode, value_len) ||
761                         !verify_state_change(c, ENC_CTX_TAG_SET))
762                         return YACA_ERROR_INVALID_PARAMETER;
763
764                 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_GCM_SET_TAG, value_len, (void*)value) != 1) {
765                         ret = YACA_ERROR_INTERNAL;
766                         ERROR_DUMP(ret);
767                         return ret;
768                 }
769                 c->state = ENC_CTX_TAG_SET;
770                 break;
771         case YACA_PROPERTY_GCM_TAG_LEN:
772                 if (value_len != sizeof(size_t) || mode != EVP_CIPH_GCM_MODE ||
773                         !is_encryption_op(c->op_type) ||
774                         !is_valid_tag_len(mode, *(size_t*)value) ||
775                         !verify_state_change(c, ENC_CTX_TAG_LENGTH_SET))
776                         return YACA_ERROR_INVALID_PARAMETER;
777
778                 c->tag_len = *(size_t*)value;
779                 c->state = ENC_CTX_TAG_LENGTH_SET;
780                 break;
781         case YACA_PROPERTY_CCM_TAG:
782                 if (mode != EVP_CIPH_CCM_MODE || is_encryption_op(c->op_type) ||
783                         !is_valid_tag_len(mode, value_len) ||
784                         !verify_state_change(c, ENC_CTX_TAG_SET))
785                         return YACA_ERROR_INVALID_PARAMETER;
786
787                 ret = encrypt_ctx_set_ccm_tag(c, (char*)value, value_len);
788                 if (ret != YACA_ERROR_NONE)
789                         return ret;
790
791                 c->state = ENC_CTX_TAG_SET;
792                 break;
793         case YACA_PROPERTY_CCM_TAG_LEN:
794                 if (value_len != sizeof(size_t) || mode != EVP_CIPH_CCM_MODE ||
795                         !is_encryption_op(c->op_type) ||
796                         !is_valid_tag_len(mode, *(size_t*)value) ||
797                         !verify_state_change(c, ENC_CTX_TAG_LENGTH_SET))
798                         return YACA_ERROR_INVALID_PARAMETER;
799
800                 ret = encrypt_ctx_set_ccm_tag_len(c, *(size_t*)value);
801                 if (ret != YACA_ERROR_NONE)
802                         return ret;
803
804                 c->state = ENC_CTX_TAG_LENGTH_SET;
805                 break;
806         case YACA_PROPERTY_PADDING:
807                 if ((mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE) ||
808                         value_len != sizeof(yaca_padding_e) ||
809                         (*(yaca_padding_e*)value != YACA_PADDING_NONE &&
810                         *(yaca_padding_e*)value != YACA_PADDING_PKCS7) ||
811                         c->state == ENC_CTX_FINALIZED)
812                         return YACA_ERROR_INVALID_PARAMETER;
813
814                 int padding = *(yaca_padding_e*)value == YACA_PADDING_NONE ? 0 : 1;
815                 if (EVP_CIPHER_CTX_set_padding(c->cipher_ctx, padding) != 1) {
816                         ret = YACA_ERROR_INTERNAL;
817                         ERROR_DUMP(ret);
818                         return ret;
819                 }
820                 if (c->backup_ctx != NULL)
821                         c->backup_ctx->padding = padding;
822                 break;
823         case YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS:
824                 if (value_len != sizeof(size_t) ||
825                         (nid != NID_rc2_cbc && nid != NID_rc2_ecb && nid != NID_rc2_cfb64 && nid != NID_rc2_ofb64) ||
826                         c->state != ENC_CTX_INITIALIZED)
827                         return YACA_ERROR_INVALID_PARAMETER;
828
829                 ret = encrypt_ctx_set_rc2_effective_key_bits(c, *(size_t*)value);
830                 break;
831         default:
832                 return YACA_ERROR_INVALID_PARAMETER;
833         }
834
835         return ret;
836 }
837
838 static int get_encrypt_property(const yaca_context_h ctx, yaca_property_e property,
839                                                                 void **value, size_t *value_len)
840 {
841         int ret;
842         void *tag = NULL;
843         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
844         int mode;
845
846         if (c == NULL || value == NULL)
847                 return YACA_ERROR_INVALID_PARAMETER;
848         assert(c->cipher_ctx != NULL);
849
850         mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
851
852         switch (property) {
853         case YACA_PROPERTY_GCM_TAG:
854                 if (value_len == NULL ||
855                         !is_encryption_op(c->op_type) ||
856                         mode != EVP_CIPH_GCM_MODE ||
857                         (c->state != ENC_CTX_TAG_LENGTH_SET && c->state != ENC_CTX_FINALIZED))
858                         return YACA_ERROR_INVALID_PARAMETER;
859
860                 assert(c->tag_len <= INT_MAX);
861
862                 ret = yaca_malloc(c->tag_len, &tag);
863                 if (ret != YACA_ERROR_NONE)
864                         return ret;
865
866                 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
867                                                                 EVP_CTRL_GCM_GET_TAG,
868                                                                 c->tag_len,
869                                                                 tag) != 1) {
870                         ret = YACA_ERROR_INTERNAL;
871                         ERROR_DUMP(ret);
872                         goto err;
873                 }
874                 *value = tag;
875                 *value_len = c->tag_len;
876                 break;
877         case YACA_PROPERTY_CCM_TAG:
878                 if (value_len == NULL ||
879                         !is_encryption_op(c->op_type) ||
880                         mode != EVP_CIPH_CCM_MODE ||
881                         c->state != ENC_CTX_FINALIZED)
882                         return YACA_ERROR_INVALID_PARAMETER;
883
884                 assert(c->tag_len <= INT_MAX);
885
886                 ret = yaca_malloc(c->tag_len, &tag);
887                 if (ret != YACA_ERROR_NONE)
888                         return ret;
889
890                 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
891                                                                 EVP_CTRL_CCM_GET_TAG,
892                                                                 c->tag_len,
893                                                                 tag) != 1) {
894                         ret = YACA_ERROR_INTERNAL;
895                         ERROR_DUMP(ret);
896                         goto err;
897                 }
898                 *value = tag;
899                 *value_len = c->tag_len;
900                 break;
901         default:
902                 return YACA_ERROR_INVALID_PARAMETER;
903                 break;
904         }
905
906         return YACA_ERROR_NONE;
907
908 err:
909         yaca_free(tag);
910         return ret;
911 }
912
913 static int check_key_bit_length_for_algo(yaca_encrypt_algorithm_e algo, size_t key_bit_len)
914 {
915         assert(key_bit_len % 8 == 0);
916         int ret = YACA_ERROR_NONE;
917
918         switch (algo) {
919         case YACA_ENCRYPT_AES:
920                 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
921                         key_bit_len != YACA_KEY_LENGTH_192BIT &&
922                         key_bit_len != YACA_KEY_LENGTH_256BIT)
923                         ret = YACA_ERROR_INVALID_PARAMETER;
924                 break;
925         case YACA_ENCRYPT_UNSAFE_DES:
926                 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT)
927                         ret = YACA_ERROR_INVALID_PARAMETER;
928                 break;
929         case YACA_ENCRYPT_UNSAFE_3DES_2TDEA:
930                 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT)
931                         ret = YACA_ERROR_INVALID_PARAMETER;
932                 break;
933         case YACA_ENCRYPT_3DES_3TDEA:
934                 if (key_bit_len != YACA_KEY_LENGTH_192BIT)
935                         ret = YACA_ERROR_INVALID_PARAMETER;
936                 break;
937         case YACA_ENCRYPT_UNSAFE_RC2:
938                 if (key_bit_len < YACA_KEY_LENGTH_UNSAFE_8BIT || key_bit_len > YACA_KEY_LENGTH_1024BIT)
939                         ret = YACA_ERROR_INVALID_PARAMETER;
940                 break;
941         case YACA_ENCRYPT_UNSAFE_RC4:
942                 if (key_bit_len < YACA_KEY_LENGTH_UNSAFE_40BIT || key_bit_len > YACA_KEY_LENGTH_2048BIT)
943                         ret = YACA_ERROR_INVALID_PARAMETER;
944                 break;
945         case YACA_ENCRYPT_CAST5:
946                 if (key_bit_len < YACA_KEY_LENGTH_UNSAFE_40BIT || key_bit_len > YACA_KEY_LENGTH_UNSAFE_128BIT)
947                         ret = YACA_ERROR_INVALID_PARAMETER;
948                 break;
949         default:
950                 ret = YACA_ERROR_INVALID_PARAMETER;
951                 break;
952         }
953
954         return ret;
955 }
956
957 int encrypt_get_algorithm(yaca_encrypt_algorithm_e algo,
958                                                   yaca_block_cipher_mode_e bcm,
959                                                   size_t key_bit_len,
960                                                   const EVP_CIPHER **cipher)
961 {
962         int ret;
963         size_t i;
964
965         assert(cipher != NULL);
966
967         ret = check_key_bit_length_for_algo(algo, key_bit_len);
968         if (ret != YACA_ERROR_NONE)
969                 return ret;
970
971         *cipher = NULL;
972         ret = YACA_ERROR_INVALID_PARAMETER;
973
974         for (i = 0; i < ENCRYPTION_CIPHERS_SIZE; ++i)
975                 if (ENCRYPTION_CIPHERS[i].algo == algo &&
976                         ENCRYPTION_CIPHERS[i].bcm == bcm &&
977                         (ENCRYPTION_CIPHERS[i].key_bit_len == key_bit_len ||
978                          ENCRYPTION_CIPHERS[i].key_bit_len == (size_t)-1)) {
979                         *cipher = ENCRYPTION_CIPHERS[i].cipher();
980                         ret = YACA_ERROR_NONE;
981                         break;
982                 }
983
984         if (ret == YACA_ERROR_NONE && *cipher == NULL) {
985                 ret = YACA_ERROR_INTERNAL;
986                 ERROR_DUMP(ret);
987                 return ret;
988         }
989
990         return ret;
991 }
992
993 int encrypt_initialize(yaca_context_h *ctx,
994                                            const EVP_CIPHER *cipher,
995                                            const yaca_key_h sym_key,
996                                            const yaca_key_h iv,
997                                            enum encrypt_op_type_e op_type)
998 {
999         struct yaca_encrypt_context_s *nc;
1000         struct yaca_key_simple_s *lsym_key;
1001         int ret;
1002
1003         if (ctx == NULL || sym_key == YACA_KEY_NULL)
1004                 return YACA_ERROR_INVALID_PARAMETER;
1005
1006         lsym_key = key_get_simple(sym_key);
1007         assert(lsym_key != NULL);
1008
1009         if (lsym_key->key.type != YACA_KEY_TYPE_DES &&
1010                 lsym_key->key.type != YACA_KEY_TYPE_SYMMETRIC)
1011                 return YACA_ERROR_INVALID_PARAMETER;
1012
1013         ret = encrypt_ctx_create(&nc, op_type, cipher);
1014         if (ret != YACA_ERROR_NONE)
1015                 return ret;
1016
1017         ret = encrypt_ctx_init(nc, cipher, lsym_key->bit_len);
1018         if (ret != YACA_ERROR_NONE)
1019                 goto exit;
1020
1021         ret = encrypt_ctx_setup(nc, sym_key, iv);
1022         if (ret != YACA_ERROR_NONE)
1023                 goto exit;
1024
1025         int mode = EVP_CIPHER_CTX_mode(nc->cipher_ctx);
1026         int nid = EVP_CIPHER_CTX_nid(nc->cipher_ctx);
1027         if (mode == EVP_CIPH_CCM_MODE ||
1028                 nid == NID_rc2_cbc || nid == NID_rc2_ecb || nid == NID_rc2_cfb64 || nid == NID_rc2_ofb64) {
1029                 ret = encrypt_ctx_backup(nc, cipher, sym_key, iv);
1030                 if (ret != YACA_ERROR_NONE)
1031                         goto exit;
1032         }
1033
1034         nc->state = ENC_CTX_INITIALIZED;
1035
1036         *ctx = (yaca_context_h)nc;
1037         nc = NULL;
1038         ret = YACA_ERROR_NONE;
1039
1040 exit:
1041         yaca_context_destroy((yaca_context_h)nc);
1042
1043         return ret;
1044 }
1045
1046 int encrypt_update(yaca_context_h ctx,
1047                                    const unsigned char *input, size_t input_len,
1048                                    unsigned char *output, size_t *output_len,
1049                                    enum encrypt_op_type_e op_type)
1050 {
1051         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1052         int ret;
1053         int loutput_len;
1054
1055         if (c == NULL || input_len == 0 || output_len == NULL || op_type != c->op_type)
1056                 return YACA_ERROR_INVALID_PARAMETER;
1057
1058         int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
1059         int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
1060
1061         enum encrypt_context_state_e target_state;
1062         if (output == NULL && input == NULL)
1063                 target_state = ENC_CTX_MSG_LENGTH_UPDATED;
1064         else if (output == NULL)
1065                 target_state = ENC_CTX_AAD_UPDATED;
1066         else if (input == NULL)
1067                 return YACA_ERROR_INVALID_PARAMETER;
1068         else
1069                 target_state = ENC_CTX_MSG_UPDATED;
1070
1071         if (!verify_state_change(c, target_state))
1072                 return YACA_ERROR_INVALID_PARAMETER;
1073
1074         if (mode == EVP_CIPH_WRAP_MODE) {
1075                 if (op_type == OP_ENCRYPT) {
1076                         if (nid == NID_id_aes128_wrap || nid == NID_id_aes192_wrap || nid == NID_id_aes256_wrap) {
1077                                 if (input_len % 8 != 0 || input_len < (YACA_KEY_LENGTH_UNSAFE_128BIT / 8))
1078                                         return YACA_ERROR_INVALID_PARAMETER;
1079                         } else if (nid == NID_id_smime_alg_CMS3DESwrap) {
1080                                 if (input_len != (YACA_KEY_LENGTH_UNSAFE_128BIT / 8) &&
1081                                         input_len != (YACA_KEY_LENGTH_192BIT / 8))
1082                                         return YACA_ERROR_INVALID_PARAMETER;
1083                         } else {
1084                                 assert(false);
1085                                 return YACA_ERROR_INTERNAL;
1086                         }
1087                 } else if (op_type == OP_DECRYPT) {
1088                         if (nid == NID_id_aes128_wrap || nid == NID_id_aes192_wrap || nid == NID_id_aes256_wrap) {
1089                                 if (input_len % 8 != 0 || input_len < (YACA_KEY_LENGTH_UNSAFE_128BIT / 8 + 8))
1090                                         return YACA_ERROR_INVALID_PARAMETER;
1091                         } else if (nid == NID_id_smime_alg_CMS3DESwrap) {
1092                                 if (input_len != (YACA_KEY_LENGTH_UNSAFE_128BIT / 8 + 16) &&
1093                                         input_len != (YACA_KEY_LENGTH_192BIT / 8 + 16))
1094                                         return YACA_ERROR_INVALID_PARAMETER;
1095                         } else {
1096                                 assert(false);
1097                                 return YACA_ERROR_INTERNAL;
1098                         }
1099                 } else {
1100                         assert(false);
1101                         return YACA_ERROR_INTERNAL;
1102                 }
1103         }
1104
1105         ret = EVP_CipherUpdate(c->cipher_ctx, output, &loutput_len, input, input_len);
1106         if (ret != 1 || loutput_len < 0) {
1107                 if (mode == EVP_CIPH_CCM_MODE && (op_type == OP_DECRYPT || op_type == OP_OPEN)) {
1108                         /* A non positive return value from EVP_CipherUpdate should be considered as
1109                          * a failure to authenticate ciphertext and/or AAD.
1110                          * It does not necessarily indicate a more serious error.
1111                          * There is no call to EVP_CipherFinal.
1112                          */
1113                         return YACA_ERROR_INVALID_PARAMETER;
1114                 } else {
1115                         ret = YACA_ERROR_INTERNAL;
1116                         ERROR_DUMP(ret);
1117                         return ret;
1118                 }
1119         }
1120
1121         *output_len = loutput_len;
1122
1123         c->state = target_state;
1124         return YACA_ERROR_NONE;
1125 }
1126
1127 int encrypt_finalize(yaca_context_h ctx,
1128                                          unsigned char *output, size_t *output_len,
1129                                          enum encrypt_op_type_e op_type)
1130 {
1131         struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1132         int ret;
1133         int mode;
1134         int loutput_len = 0;
1135
1136         if (c == NULL || output == NULL || output_len == NULL || op_type != c->op_type)
1137                 return YACA_ERROR_INVALID_PARAMETER;
1138
1139         if (!verify_state_change(c, ENC_CTX_FINALIZED))
1140                 return YACA_ERROR_INVALID_PARAMETER;
1141
1142         mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
1143         if (mode != EVP_CIPH_WRAP_MODE && mode != EVP_CIPH_CCM_MODE) {
1144                 ret = EVP_CipherFinal(c->cipher_ctx, output, &loutput_len);
1145                 if (ret != 1 || loutput_len < 0) {
1146                         if (mode == EVP_CIPH_GCM_MODE && (op_type == OP_DECRYPT || op_type == OP_OPEN))
1147                         /* A non positive return value from EVP_CipherFinal should be considered as
1148                          * a failure to authenticate ciphertext and/or AAD.
1149                          * It does not necessarily indicate a more serious error.
1150                          */
1151                                 return YACA_ERROR_INVALID_PARAMETER;
1152                         else
1153                                 return ERROR_HANDLE();
1154                 }
1155         }
1156
1157         *output_len = loutput_len;
1158
1159         c->state = ENC_CTX_FINALIZED;
1160         return YACA_ERROR_NONE;
1161 }
1162
1163 API int yaca_encrypt_get_iv_bit_length(yaca_encrypt_algorithm_e algo,
1164                                                                            yaca_block_cipher_mode_e bcm,
1165                                                                            size_t key_bit_len,
1166                                                                            size_t *iv_bit_len)
1167 {
1168         int ret;
1169         const EVP_CIPHER *cipher;
1170
1171         if (iv_bit_len == NULL || key_bit_len % 8 != 0)
1172                 return YACA_ERROR_INVALID_PARAMETER;
1173
1174         ret = encrypt_get_algorithm(algo, bcm, key_bit_len, &cipher);
1175         if (ret != YACA_ERROR_NONE)
1176                 return ret;
1177
1178         ret = EVP_CIPHER_iv_length(cipher);
1179         if (ret < 0) {
1180                 ret = YACA_ERROR_INTERNAL;
1181                 ERROR_DUMP(ret);
1182                 return ret;
1183         }
1184
1185         *iv_bit_len = ret * 8;
1186         return YACA_ERROR_NONE;
1187 }
1188
1189 API int yaca_encrypt_initialize(yaca_context_h *ctx,
1190                                                                 yaca_encrypt_algorithm_e algo,
1191                                                                 yaca_block_cipher_mode_e bcm,
1192                                                                 const yaca_key_h sym_key,
1193                                                                 const yaca_key_h iv)
1194 {
1195         int ret;
1196         const EVP_CIPHER *cipher;
1197         struct yaca_key_simple_s *key = key_get_simple(sym_key);
1198
1199         if (key == NULL)
1200                 return YACA_ERROR_INVALID_PARAMETER;
1201
1202         ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1203         if (ret != YACA_ERROR_NONE)
1204                 return ret;
1205
1206         return encrypt_initialize(ctx, cipher, sym_key, iv, OP_ENCRYPT);
1207 }
1208
1209 API int yaca_encrypt_update(yaca_context_h ctx,
1210                                                         const char *plaintext,
1211                                                         size_t plaintext_len,
1212                                                         char *ciphertext,
1213                                                         size_t *ciphertext_len)
1214 {
1215         return encrypt_update(ctx, (const unsigned char*)plaintext, plaintext_len,
1216                                                   (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
1217 }
1218
1219 API int yaca_encrypt_finalize(yaca_context_h ctx,
1220                                                           char *ciphertext,
1221                                                           size_t *ciphertext_len)
1222 {
1223         return encrypt_finalize(ctx, (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
1224 }
1225
1226 API int yaca_decrypt_initialize(yaca_context_h *ctx,
1227                                                                 yaca_encrypt_algorithm_e algo,
1228                                                                 yaca_block_cipher_mode_e bcm,
1229                                                                 const yaca_key_h sym_key,
1230                                                                 const yaca_key_h iv)
1231 {
1232         int ret;
1233         const EVP_CIPHER *cipher;
1234         struct yaca_key_simple_s *key = key_get_simple(sym_key);
1235
1236         if (key == NULL)
1237                 return YACA_ERROR_INVALID_PARAMETER;
1238
1239         ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1240         if (ret != YACA_ERROR_NONE)
1241                 return ret;
1242
1243         return encrypt_initialize(ctx, cipher, sym_key, iv, OP_DECRYPT);
1244 }
1245
1246 API int yaca_decrypt_update(yaca_context_h ctx,
1247                                                         const char *ciphertext,
1248                                                         size_t ciphertext_len,
1249                                                         char *plaintext,
1250                                                         size_t *plaintext_len)
1251 {
1252         return encrypt_update(ctx, (const unsigned char*)ciphertext, ciphertext_len,
1253                                                   (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);
1254 }
1255
1256 API int yaca_decrypt_finalize(yaca_context_h ctx,
1257                                                           char *plaintext,
1258                                                           size_t *plaintext_len)
1259 {
1260         return encrypt_finalize(ctx, (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);
1261 }