2 * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
30 #include <openssl/evp.h>
32 #include <yaca_crypto.h>
33 #include <yaca_encrypt.h>
34 #include <yaca_error.h>
39 static int set_encrypt_property(yaca_context_h ctx, yaca_property_e property,
40 const void *value, size_t value_len);
42 static int get_encrypt_property(const yaca_context_h ctx, yaca_property_e property,
43 void **value, size_t *value_len);
45 static const size_t DEFAULT_GCM_TAG_LEN = 16;
46 static const size_t DEFAULT_CCM_TAG_LEN = 12;
48 enum encrypt_context_state_e {
49 ENC_CTX_INITIALIZED = 0,
50 ENC_CTX_MSG_LENGTH_UPDATED,
54 ENC_CTX_TAG_LENGTH_SET,
60 struct yaca_encrypt_context_s {
61 struct yaca_context_s ctx;
62 struct yaca_backup_context_s *backup_ctx;
64 EVP_CIPHER_CTX *cipher_ctx;
65 enum encrypt_op_type_e op_type; /* Operation context was created for */
67 enum encrypt_context_state_e state;
70 struct yaca_backup_context_s {
71 const EVP_CIPHER *cipher;
74 yaca_padding_e padding;
78 yaca_encrypt_algorithm_e algo;
79 yaca_block_cipher_mode_e bcm;
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},
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},
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},
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},
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},
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},
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},
141 {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, -1, EVP_rc4},
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},
149 static const size_t ENCRYPTION_CIPHERS_SIZE = sizeof(ENCRYPTION_CIPHERS) / sizeof(ENCRYPTION_CIPHERS[0]);
151 static bool is_encryption_op(enum encrypt_op_type_e op_type)
153 return (op_type == OP_ENCRYPT || op_type == OP_SEAL);
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 },
167 static bool GCM_STATES[2][ENC_CTX_COUNT][ENC_CTX_COUNT] = { {
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 },
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 },
189 static bool CCM_STATES[2][ENC_CTX_COUNT][ENC_CTX_COUNT] = { {
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 },
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 },
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 },
222 static bool verify_state_change(struct yaca_encrypt_context_s *c, enum encrypt_context_state_e to)
224 int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
225 bool encryption = is_encryption_op(c->op_type);
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];
235 return DEFAULT_STATES[from][to];
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]);
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]);
248 static bool is_valid_tag_len(int mode, size_t tag_len)
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])
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])
269 static struct yaca_encrypt_context_s *get_encrypt_context(const yaca_context_h ctx)
271 if (ctx == YACA_CONTEXT_NULL)
275 case YACA_CONTEXT_ENCRYPT:
276 return (struct yaca_encrypt_context_s *)ctx;
282 static void destroy_encrypt_context(const yaca_context_h ctx)
284 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
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;
294 EVP_CIPHER_CTX_free(c->cipher_ctx);
295 c->cipher_ctx = NULL;
298 static int get_encrypt_output_length(const yaca_context_h ctx, size_t input_len, size_t *output_len)
300 assert(output_len != NULL);
303 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
305 assert(c->cipher_ctx != NULL);
307 block_size = EVP_CIPHER_CTX_block_size(c->cipher_ctx);
308 if (block_size <= 0) {
309 const int ret = YACA_ERROR_INTERNAL;
315 if ((size_t)block_size > SIZE_MAX - input_len + 1)
316 return YACA_ERROR_INVALID_PARAMETER;
318 *output_len = block_size + input_len - 1;
320 *output_len = block_size;
322 assert(*output_len != 0);
324 return YACA_ERROR_NONE;
327 static int get_wrap_output_length(const yaca_context_h ctx, size_t input_len, size_t *output_len)
329 assert(output_len != NULL);
331 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
333 assert(c->cipher_ctx != NULL);
335 bool encryption = is_encryption_op(c->op_type);
336 int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
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;
345 return YACA_ERROR_INTERNAL;
351 return YACA_ERROR_NONE;
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)
360 struct yaca_encrypt_context_s *nc;
363 assert(cipher != NULL);
365 ret = yaca_zalloc(sizeof(struct yaca_encrypt_context_s), (void**)&nc);
366 if (ret != YACA_ERROR_NONE)
369 mode = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
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;
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;
388 nc->cipher_ctx = EVP_CIPHER_CTX_new();
389 if (nc->cipher_ctx == NULL) {
390 ret = YACA_ERROR_INTERNAL;
395 if (mode == EVP_CIPH_WRAP_MODE)
396 EVP_CIPHER_CTX_set_flags(nc->cipher_ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
401 ret = YACA_ERROR_NONE;
408 static int encrypt_ctx_init(struct yaca_encrypt_context_s *c,
409 const EVP_CIPHER *cipher,
415 assert(cipher != NULL);
417 if (key_bit_len / 8 > INT_MAX)
418 return YACA_ERROR_INVALID_PARAMETER;
420 ret = EVP_CipherInit_ex(c->cipher_ctx,
425 is_encryption_op(c->op_type) ? 1 : 0);
427 ret = YACA_ERROR_INTERNAL;
432 /* Handling of algorithms with variable key length */
433 ret = EVP_CIPHER_CTX_set_key_length(c->cipher_ctx, key_bit_len / 8);
435 return ERROR_HANDLE();
437 return YACA_ERROR_NONE;
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)
445 size_t default_iv_bit_len;
448 assert(cipher != NULL);
450 ret = EVP_CIPHER_iv_length(cipher);
452 ret = YACA_ERROR_INTERNAL;
457 default_iv_bit_len = ret * 8;
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;
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;
468 if (iv->bit_len / 8 > INT_MAX)
469 return YACA_ERROR_INVALID_PARAMETER;
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);
476 if (mode == EVP_CIPH_GCM_MODE) {
477 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_GCM_SET_IVLEN,
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.
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,
490 return YACA_ERROR_INVALID_PARAMETER;
494 return ERROR_HANDLE();
498 return YACA_ERROR_NONE;
501 static int encrypt_ctx_setup(struct yaca_encrypt_context_s *c,
502 const yaca_key_h key,
506 unsigned char *iv_data = NULL;
507 const struct yaca_key_simple_s *lkey;
508 const struct yaca_key_simple_s *liv;
511 assert(key != YACA_KEY_NULL);
513 const EVP_CIPHER *cipher = EVP_CIPHER_CTX_cipher(c->cipher_ctx);
514 if (cipher == NULL) {
515 ret = YACA_ERROR_INTERNAL;
520 lkey = key_get_simple(key);
521 assert(lkey != NULL);
523 liv = key_get_simple(iv);
525 ret = encrypt_ctx_setup_iv(c, cipher, liv);
526 if (ret != YACA_ERROR_NONE)
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);
537 iv_data = (unsigned char*)liv->d;
539 ret = EVP_CipherInit_ex(c->cipher_ctx,
542 (unsigned char*)lkey->d,
544 is_encryption_op(c->op_type) ? 1 : 0);
546 ret = YACA_ERROR_INTERNAL;
551 return YACA_ERROR_NONE;
554 static int key_copy_simple(const yaca_key_h key, yaca_key_h *out)
556 assert(key != YACA_KEY_NULL);
560 struct yaca_key_simple_s *simple = key_get_simple(key);
561 assert(simple != NULL);
563 struct yaca_key_simple_s *copy;
564 size_t size = sizeof(struct yaca_key_simple_s) + simple->bit_len / 8;
566 ret = yaca_zalloc(size, (void**)©);
567 if (ret != YACA_ERROR_NONE)
570 memcpy(copy, key, size);
571 *out = (yaca_key_h)copy;
572 return YACA_ERROR_NONE;
575 static int encrypt_ctx_backup(struct yaca_encrypt_context_s *c,
576 const EVP_CIPHER *cipher,
577 const yaca_key_h sym_key,
581 struct yaca_backup_context_s *bc;
584 assert(cipher != NULL);
585 assert(sym_key != YACA_KEY_NULL);
586 assert(c->backup_ctx == NULL);
588 ret = yaca_zalloc(sizeof(struct yaca_backup_context_s), (void**)&bc);
589 if (ret != YACA_ERROR_NONE)
592 ret = key_copy_simple(sym_key, &bc->sym_key);
593 if (ret != YACA_ERROR_NONE)
595 if (iv != YACA_KEY_NULL) {
596 ret = key_copy_simple(iv, &bc->iv);
597 if (ret != YACA_ERROR_NONE)
601 bc->padding = YACA_PADDING_PKCS7;
605 return YACA_ERROR_NONE;
608 yaca_key_destroy(bc->iv);
609 yaca_key_destroy(bc->sym_key);
614 static int encrypt_ctx_restore(struct yaca_encrypt_context_s *c)
617 struct yaca_key_simple_s *key;
620 assert(c->backup_ctx != NULL);
622 ret = EVP_CIPHER_CTX_cleanup(c->cipher_ctx);
624 ret = YACA_ERROR_INTERNAL;
629 key = key_get_simple(c->backup_ctx->sym_key);
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)
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;
647 static int encrypt_ctx_set_ccm_tag_len(struct yaca_encrypt_context_s *c, size_t tag_len)
652 assert(c->backup_ctx != NULL);
653 assert(is_encryption_op(c->op_type));
655 ret = encrypt_ctx_restore(c);
656 if (ret != YACA_ERROR_NONE)
659 c->tag_len = tag_len;
660 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL);
662 ret = YACA_ERROR_INTERNAL;
667 ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
668 assert(ret != YACA_ERROR_INVALID_PARAMETER);
672 static int encrypt_ctx_set_ccm_tag(struct yaca_encrypt_context_s *c, char *tag, size_t tag_len)
677 assert(c->backup_ctx != NULL);
678 assert(!is_encryption_op(c->op_type));
681 ret = encrypt_ctx_restore(c);
682 if (ret != YACA_ERROR_NONE)
685 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag);
687 ret = YACA_ERROR_INTERNAL;
692 ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
693 assert(ret != YACA_ERROR_INVALID_PARAMETER);
697 static int encrypt_ctx_set_rc2_effective_key_bits(struct yaca_encrypt_context_s *c, size_t key_bits)
702 assert(c->backup_ctx != NULL);
704 if (key_bits == 0 || key_bits > 1024)
705 return YACA_ERROR_INVALID_PARAMETER;
707 ret = encrypt_ctx_restore(c);
708 if (ret != YACA_ERROR_NONE)
711 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
713 ret = YACA_ERROR_INTERNAL;
718 ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
719 assert(ret != YACA_ERROR_INVALID_PARAMETER);
723 static int set_encrypt_property(yaca_context_h ctx,
724 yaca_property_e property,
729 int ret = YACA_ERROR_NONE;
730 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
732 assert(c->cipher_ctx != NULL);
734 if (value == NULL || value_len == 0)
735 return YACA_ERROR_INVALID_PARAMETER;
737 int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
738 int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
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;
746 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
747 ret = YACA_ERROR_INTERNAL;
751 c->state = ENC_CTX_AAD_UPDATED;
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;
758 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
759 ret = YACA_ERROR_INTERNAL;
763 c->state = ENC_CTX_AAD_UPDATED;
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;
771 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_GCM_SET_TAG, value_len, (void*)value) != 1) {
772 ret = YACA_ERROR_INTERNAL;
776 c->state = ENC_CTX_TAG_SET;
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;
785 c->tag_len = *(size_t*)value;
786 c->state = ENC_CTX_TAG_LENGTH_SET;
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;
794 ret = encrypt_ctx_set_ccm_tag(c, (char*)value, value_len);
795 if (ret != YACA_ERROR_NONE)
798 c->state = ENC_CTX_TAG_SET;
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;
807 ret = encrypt_ctx_set_ccm_tag_len(c, *(size_t*)value);
808 if (ret != YACA_ERROR_NONE)
811 c->state = ENC_CTX_TAG_LENGTH_SET;
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;
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;
827 if (c->backup_ctx != NULL)
828 c->backup_ctx->padding = padding;
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;
836 ret = encrypt_ctx_set_rc2_effective_key_bits(c, *(size_t*)value);
839 return YACA_ERROR_INVALID_PARAMETER;
845 static int get_encrypt_property(const yaca_context_h ctx, yaca_property_e property,
846 void **value, size_t *value_len)
850 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
853 if (c == NULL || value == NULL)
854 return YACA_ERROR_INVALID_PARAMETER;
855 assert(c->cipher_ctx != NULL);
857 mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
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;
867 assert(c->tag_len <= INT_MAX);
869 ret = yaca_malloc(c->tag_len, &tag);
870 if (ret != YACA_ERROR_NONE)
873 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
874 EVP_CTRL_GCM_GET_TAG,
877 ret = YACA_ERROR_INTERNAL;
882 *value_len = c->tag_len;
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;
891 assert(c->tag_len <= INT_MAX);
893 ret = yaca_malloc(c->tag_len, &tag);
894 if (ret != YACA_ERROR_NONE)
897 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
898 EVP_CTRL_CCM_GET_TAG,
901 ret = YACA_ERROR_INTERNAL;
906 *value_len = c->tag_len;
909 return YACA_ERROR_INVALID_PARAMETER;
913 return YACA_ERROR_NONE;
920 static int check_key_bit_length_for_algo(yaca_encrypt_algorithm_e algo, size_t key_bit_len)
922 assert(key_bit_len % 8 == 0);
923 int ret = YACA_ERROR_NONE;
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;
932 case YACA_ENCRYPT_UNSAFE_DES:
933 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT)
934 ret = YACA_ERROR_INVALID_PARAMETER;
936 case YACA_ENCRYPT_UNSAFE_3DES_2TDEA:
937 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT)
938 ret = YACA_ERROR_INVALID_PARAMETER;
940 case YACA_ENCRYPT_3DES_3TDEA:
941 if (key_bit_len != YACA_KEY_LENGTH_192BIT)
942 ret = YACA_ERROR_INVALID_PARAMETER;
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;
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;
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;
957 ret = YACA_ERROR_INVALID_PARAMETER;
964 int encrypt_get_algorithm(yaca_encrypt_algorithm_e algo,
965 yaca_block_cipher_mode_e bcm,
967 const EVP_CIPHER **cipher)
972 assert(cipher != NULL);
974 ret = check_key_bit_length_for_algo(algo, key_bit_len);
975 if (ret != YACA_ERROR_NONE)
979 ret = YACA_ERROR_INVALID_PARAMETER;
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;
991 if (ret == YACA_ERROR_NONE && *cipher == NULL) {
992 ret = YACA_ERROR_INTERNAL;
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)
1006 struct yaca_encrypt_context_s *nc;
1007 struct yaca_key_simple_s *lsym_key;
1010 if (ctx == NULL || sym_key == YACA_KEY_NULL)
1011 return YACA_ERROR_INVALID_PARAMETER;
1013 lsym_key = key_get_simple(sym_key);
1014 assert(lsym_key != NULL);
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;
1020 ret = encrypt_ctx_create(&nc, op_type, cipher);
1021 if (ret != YACA_ERROR_NONE)
1024 ret = encrypt_ctx_init(nc, cipher, lsym_key->bit_len);
1025 if (ret != YACA_ERROR_NONE)
1028 ret = encrypt_ctx_setup(nc, sym_key, iv);
1029 if (ret != YACA_ERROR_NONE)
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)
1041 nc->state = ENC_CTX_INITIALIZED;
1043 *ctx = (yaca_context_h)nc;
1045 ret = YACA_ERROR_NONE;
1048 yaca_context_destroy((yaca_context_h)nc);
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)
1058 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1062 if (c == NULL || input_len == 0 || output_len == NULL || op_type != c->op_type)
1063 return YACA_ERROR_INVALID_PARAMETER;
1065 int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
1066 int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
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;
1076 target_state = ENC_CTX_MSG_UPDATED;
1078 if (!verify_state_change(c, target_state))
1079 return YACA_ERROR_INVALID_PARAMETER;
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;
1092 return YACA_ERROR_INTERNAL;
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;
1104 return YACA_ERROR_INTERNAL;
1108 return YACA_ERROR_INTERNAL;
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;
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.
1127 return YACA_ERROR_INVALID_PARAMETER;
1129 ret = YACA_ERROR_INTERNAL;
1135 *output_len = loutput_len;
1137 c->state = target_state;
1139 /* Fix for OpenSSL error in 3DES CFB1 */
1140 if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0)
1143 return YACA_ERROR_NONE;
1146 int encrypt_finalize(yaca_context_h ctx,
1147 unsigned char *output, size_t *output_len,
1148 enum encrypt_op_type_e op_type)
1150 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1153 int loutput_len = 0;
1155 if (c == NULL || output == NULL || output_len == NULL || op_type != c->op_type)
1156 return YACA_ERROR_INVALID_PARAMETER;
1158 if (!verify_state_change(c, ENC_CTX_FINALIZED))
1159 return YACA_ERROR_INVALID_PARAMETER;
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.
1170 return YACA_ERROR_INVALID_PARAMETER;
1172 return ERROR_HANDLE();
1176 *output_len = loutput_len;
1178 /* Fix for OpenSSL error in 3DES CFB1 */
1179 if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0)
1182 c->state = ENC_CTX_FINALIZED;
1183 return YACA_ERROR_NONE;
1186 API int yaca_encrypt_get_iv_bit_length(yaca_encrypt_algorithm_e algo,
1187 yaca_block_cipher_mode_e bcm,
1192 const EVP_CIPHER *cipher;
1194 if (iv_bit_len == NULL || key_bit_len % 8 != 0)
1195 return YACA_ERROR_INVALID_PARAMETER;
1197 ret = encrypt_get_algorithm(algo, bcm, key_bit_len, &cipher);
1198 if (ret != YACA_ERROR_NONE)
1201 ret = EVP_CIPHER_iv_length(cipher);
1203 ret = YACA_ERROR_INTERNAL;
1208 *iv_bit_len = ret * 8;
1209 return YACA_ERROR_NONE;
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)
1219 const EVP_CIPHER *cipher;
1220 struct yaca_key_simple_s *key = key_get_simple(sym_key);
1223 return YACA_ERROR_INVALID_PARAMETER;
1225 ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1226 if (ret != YACA_ERROR_NONE)
1229 return encrypt_initialize(ctx, cipher, sym_key, iv, OP_ENCRYPT);
1232 API int yaca_encrypt_update(yaca_context_h ctx,
1233 const char *plaintext,
1234 size_t plaintext_len,
1236 size_t *ciphertext_len)
1238 return encrypt_update(ctx, (const unsigned char*)plaintext, plaintext_len,
1239 (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
1242 API int yaca_encrypt_finalize(yaca_context_h ctx,
1244 size_t *ciphertext_len)
1246 return encrypt_finalize(ctx, (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
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)
1256 const EVP_CIPHER *cipher;
1257 struct yaca_key_simple_s *key = key_get_simple(sym_key);
1260 return YACA_ERROR_INVALID_PARAMETER;
1262 ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1263 if (ret != YACA_ERROR_NONE)
1266 return encrypt_initialize(ctx, cipher, sym_key, iv, OP_DECRYPT);
1269 API int yaca_decrypt_update(yaca_context_h ctx,
1270 const char *ciphertext,
1271 size_t ciphertext_len,
1273 size_t *plaintext_len)
1275 return encrypt_update(ctx, (const unsigned char*)ciphertext, ciphertext_len,
1276 (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);
1279 API int yaca_decrypt_finalize(yaca_context_h ctx,
1281 size_t *plaintext_len)
1283 return encrypt_finalize(ctx, (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);