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)
530 iv_data = (unsigned char*)liv->d;
532 ret = EVP_CipherInit_ex(c->cipher_ctx,
535 (unsigned char*)lkey->d,
537 is_encryption_op(c->op_type) ? 1 : 0);
539 ret = YACA_ERROR_INTERNAL;
544 return YACA_ERROR_NONE;
547 static int key_copy_simple(const yaca_key_h key, yaca_key_h *out)
549 assert(key != YACA_KEY_NULL);
553 struct yaca_key_simple_s *simple = key_get_simple(key);
554 assert(simple != NULL);
556 struct yaca_key_simple_s *copy;
557 size_t size = sizeof(struct yaca_key_simple_s) + simple->bit_len / 8;
559 ret = yaca_zalloc(size, (void**)©);
560 if (ret != YACA_ERROR_NONE)
563 memcpy(copy, key, size);
564 *out = (yaca_key_h)copy;
565 return YACA_ERROR_NONE;
568 static int encrypt_ctx_backup(struct yaca_encrypt_context_s *c,
569 const EVP_CIPHER *cipher,
570 const yaca_key_h sym_key,
574 struct yaca_backup_context_s *bc;
577 assert(cipher != NULL);
578 assert(sym_key != YACA_KEY_NULL);
579 assert(c->backup_ctx == NULL);
581 ret = yaca_zalloc(sizeof(struct yaca_backup_context_s), (void**)&bc);
582 if (ret != YACA_ERROR_NONE)
585 ret = key_copy_simple(sym_key, &bc->sym_key);
586 if (ret != YACA_ERROR_NONE)
588 if (iv != YACA_KEY_NULL) {
589 ret = key_copy_simple(iv, &bc->iv);
590 if (ret != YACA_ERROR_NONE)
594 bc->padding = YACA_PADDING_PKCS7;
598 return YACA_ERROR_NONE;
601 yaca_key_destroy(bc->iv);
602 yaca_key_destroy(bc->sym_key);
607 static int encrypt_ctx_restore(struct yaca_encrypt_context_s *c)
610 struct yaca_key_simple_s *key;
613 assert(c->backup_ctx != NULL);
615 ret = EVP_CIPHER_CTX_cleanup(c->cipher_ctx);
617 ret = YACA_ERROR_INTERNAL;
622 key = key_get_simple(c->backup_ctx->sym_key);
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)
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;
640 static int encrypt_ctx_set_ccm_tag_len(struct yaca_encrypt_context_s *c, size_t tag_len)
645 assert(c->backup_ctx != NULL);
646 assert(is_encryption_op(c->op_type));
648 ret = encrypt_ctx_restore(c);
649 if (ret != YACA_ERROR_NONE)
652 c->tag_len = tag_len;
653 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL);
655 ret = YACA_ERROR_INTERNAL;
660 ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
661 assert(ret != YACA_ERROR_INVALID_PARAMETER);
665 static int encrypt_ctx_set_ccm_tag(struct yaca_encrypt_context_s *c, char *tag, size_t tag_len)
670 assert(c->backup_ctx != NULL);
671 assert(!is_encryption_op(c->op_type));
674 ret = encrypt_ctx_restore(c);
675 if (ret != YACA_ERROR_NONE)
678 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag);
680 ret = YACA_ERROR_INTERNAL;
685 ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
686 assert(ret != YACA_ERROR_INVALID_PARAMETER);
690 static int encrypt_ctx_set_rc2_effective_key_bits(struct yaca_encrypt_context_s *c, size_t key_bits)
695 assert(c->backup_ctx != NULL);
697 if (key_bits == 0 || key_bits > 1024)
698 return YACA_ERROR_INVALID_PARAMETER;
700 ret = encrypt_ctx_restore(c);
701 if (ret != YACA_ERROR_NONE)
704 ret = EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
706 ret = YACA_ERROR_INTERNAL;
711 ret = encrypt_ctx_setup(c, c->backup_ctx->sym_key, c->backup_ctx->iv);
712 assert(ret != YACA_ERROR_INVALID_PARAMETER);
716 static int set_encrypt_property(yaca_context_h ctx,
717 yaca_property_e property,
722 int ret = YACA_ERROR_NONE;
723 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
725 assert(c->cipher_ctx != NULL);
727 if (value == NULL || value_len == 0)
728 return YACA_ERROR_INVALID_PARAMETER;
730 int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
731 int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
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;
739 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
740 ret = YACA_ERROR_INTERNAL;
744 c->state = ENC_CTX_AAD_UPDATED;
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;
751 if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) {
752 ret = YACA_ERROR_INTERNAL;
756 c->state = ENC_CTX_AAD_UPDATED;
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;
764 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_GCM_SET_TAG, value_len, (void*)value) != 1) {
765 ret = YACA_ERROR_INTERNAL;
769 c->state = ENC_CTX_TAG_SET;
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;
778 c->tag_len = *(size_t*)value;
779 c->state = ENC_CTX_TAG_LENGTH_SET;
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;
787 ret = encrypt_ctx_set_ccm_tag(c, (char*)value, value_len);
788 if (ret != YACA_ERROR_NONE)
791 c->state = ENC_CTX_TAG_SET;
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;
800 ret = encrypt_ctx_set_ccm_tag_len(c, *(size_t*)value);
801 if (ret != YACA_ERROR_NONE)
804 c->state = ENC_CTX_TAG_LENGTH_SET;
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;
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;
820 if (c->backup_ctx != NULL)
821 c->backup_ctx->padding = padding;
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;
829 ret = encrypt_ctx_set_rc2_effective_key_bits(c, *(size_t*)value);
832 return YACA_ERROR_INVALID_PARAMETER;
838 static int get_encrypt_property(const yaca_context_h ctx, yaca_property_e property,
839 void **value, size_t *value_len)
843 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
846 if (c == NULL || value == NULL)
847 return YACA_ERROR_INVALID_PARAMETER;
848 assert(c->cipher_ctx != NULL);
850 mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
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;
860 assert(c->tag_len <= INT_MAX);
862 ret = yaca_malloc(c->tag_len, &tag);
863 if (ret != YACA_ERROR_NONE)
866 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
867 EVP_CTRL_GCM_GET_TAG,
870 ret = YACA_ERROR_INTERNAL;
875 *value_len = c->tag_len;
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;
884 assert(c->tag_len <= INT_MAX);
886 ret = yaca_malloc(c->tag_len, &tag);
887 if (ret != YACA_ERROR_NONE)
890 if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx,
891 EVP_CTRL_CCM_GET_TAG,
894 ret = YACA_ERROR_INTERNAL;
899 *value_len = c->tag_len;
902 return YACA_ERROR_INVALID_PARAMETER;
906 return YACA_ERROR_NONE;
913 static int check_key_bit_length_for_algo(yaca_encrypt_algorithm_e algo, size_t key_bit_len)
915 assert(key_bit_len % 8 == 0);
916 int ret = YACA_ERROR_NONE;
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;
925 case YACA_ENCRYPT_UNSAFE_DES:
926 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT)
927 ret = YACA_ERROR_INVALID_PARAMETER;
929 case YACA_ENCRYPT_UNSAFE_3DES_2TDEA:
930 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT)
931 ret = YACA_ERROR_INVALID_PARAMETER;
933 case YACA_ENCRYPT_3DES_3TDEA:
934 if (key_bit_len != YACA_KEY_LENGTH_192BIT)
935 ret = YACA_ERROR_INVALID_PARAMETER;
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;
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;
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;
950 ret = YACA_ERROR_INVALID_PARAMETER;
957 int encrypt_get_algorithm(yaca_encrypt_algorithm_e algo,
958 yaca_block_cipher_mode_e bcm,
960 const EVP_CIPHER **cipher)
965 assert(cipher != NULL);
967 ret = check_key_bit_length_for_algo(algo, key_bit_len);
968 if (ret != YACA_ERROR_NONE)
972 ret = YACA_ERROR_INVALID_PARAMETER;
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;
984 if (ret == YACA_ERROR_NONE && *cipher == NULL) {
985 ret = YACA_ERROR_INTERNAL;
993 int encrypt_initialize(yaca_context_h *ctx,
994 const EVP_CIPHER *cipher,
995 const yaca_key_h sym_key,
997 enum encrypt_op_type_e op_type)
999 struct yaca_encrypt_context_s *nc;
1000 struct yaca_key_simple_s *lsym_key;
1003 if (ctx == NULL || sym_key == YACA_KEY_NULL)
1004 return YACA_ERROR_INVALID_PARAMETER;
1006 lsym_key = key_get_simple(sym_key);
1007 assert(lsym_key != NULL);
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;
1013 ret = encrypt_ctx_create(&nc, op_type, cipher);
1014 if (ret != YACA_ERROR_NONE)
1017 ret = encrypt_ctx_init(nc, cipher, lsym_key->bit_len);
1018 if (ret != YACA_ERROR_NONE)
1021 ret = encrypt_ctx_setup(nc, sym_key, iv);
1022 if (ret != YACA_ERROR_NONE)
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)
1034 nc->state = ENC_CTX_INITIALIZED;
1036 *ctx = (yaca_context_h)nc;
1038 ret = YACA_ERROR_NONE;
1041 yaca_context_destroy((yaca_context_h)nc);
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)
1051 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1055 if (c == NULL || input_len == 0 || output_len == NULL || op_type != c->op_type)
1056 return YACA_ERROR_INVALID_PARAMETER;
1058 int mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
1059 int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
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;
1069 target_state = ENC_CTX_MSG_UPDATED;
1071 if (!verify_state_change(c, target_state))
1072 return YACA_ERROR_INVALID_PARAMETER;
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;
1085 return YACA_ERROR_INTERNAL;
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;
1097 return YACA_ERROR_INTERNAL;
1101 return YACA_ERROR_INTERNAL;
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.
1113 return YACA_ERROR_INVALID_PARAMETER;
1115 ret = YACA_ERROR_INTERNAL;
1121 *output_len = loutput_len;
1123 c->state = target_state;
1124 return YACA_ERROR_NONE;
1127 int encrypt_finalize(yaca_context_h ctx,
1128 unsigned char *output, size_t *output_len,
1129 enum encrypt_op_type_e op_type)
1131 struct yaca_encrypt_context_s *c = get_encrypt_context(ctx);
1134 int loutput_len = 0;
1136 if (c == NULL || output == NULL || output_len == NULL || op_type != c->op_type)
1137 return YACA_ERROR_INVALID_PARAMETER;
1139 if (!verify_state_change(c, ENC_CTX_FINALIZED))
1140 return YACA_ERROR_INVALID_PARAMETER;
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.
1151 return YACA_ERROR_INVALID_PARAMETER;
1153 return ERROR_HANDLE();
1157 *output_len = loutput_len;
1159 c->state = ENC_CTX_FINALIZED;
1160 return YACA_ERROR_NONE;
1163 API int yaca_encrypt_get_iv_bit_length(yaca_encrypt_algorithm_e algo,
1164 yaca_block_cipher_mode_e bcm,
1169 const EVP_CIPHER *cipher;
1171 if (iv_bit_len == NULL || key_bit_len % 8 != 0)
1172 return YACA_ERROR_INVALID_PARAMETER;
1174 ret = encrypt_get_algorithm(algo, bcm, key_bit_len, &cipher);
1175 if (ret != YACA_ERROR_NONE)
1178 ret = EVP_CIPHER_iv_length(cipher);
1180 ret = YACA_ERROR_INTERNAL;
1185 *iv_bit_len = ret * 8;
1186 return YACA_ERROR_NONE;
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)
1196 const EVP_CIPHER *cipher;
1197 struct yaca_key_simple_s *key = key_get_simple(sym_key);
1200 return YACA_ERROR_INVALID_PARAMETER;
1202 ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1203 if (ret != YACA_ERROR_NONE)
1206 return encrypt_initialize(ctx, cipher, sym_key, iv, OP_ENCRYPT);
1209 API int yaca_encrypt_update(yaca_context_h ctx,
1210 const char *plaintext,
1211 size_t plaintext_len,
1213 size_t *ciphertext_len)
1215 return encrypt_update(ctx, (const unsigned char*)plaintext, plaintext_len,
1216 (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
1219 API int yaca_encrypt_finalize(yaca_context_h ctx,
1221 size_t *ciphertext_len)
1223 return encrypt_finalize(ctx, (unsigned char*)ciphertext, ciphertext_len, OP_ENCRYPT);
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)
1233 const EVP_CIPHER *cipher;
1234 struct yaca_key_simple_s *key = key_get_simple(sym_key);
1237 return YACA_ERROR_INVALID_PARAMETER;
1239 ret = encrypt_get_algorithm(algo, bcm, key->bit_len, &cipher);
1240 if (ret != YACA_ERROR_NONE)
1243 return encrypt_initialize(ctx, cipher, sym_key, iv, OP_DECRYPT);
1246 API int yaca_decrypt_update(yaca_context_h ctx,
1247 const char *ciphertext,
1248 size_t ciphertext_len,
1250 size_t *plaintext_len)
1252 return encrypt_update(ctx, (const unsigned char*)ciphertext, ciphertext_len,
1253 (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);
1256 API int yaca_decrypt_finalize(yaca_context_h ctx,
1258 size_t *plaintext_len)
1260 return encrypt_finalize(ctx, (unsigned char*)plaintext, plaintext_len, OP_DECRYPT);