]>
Commit | Line | Data |
---|---|---|
62867571 | 1 | /* |
da1c088f | 2 | * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
d02b48c6 RE |
8 | */ |
9 | ||
e4468e6d P |
10 | /* We need to use some engine deprecated APIs */ |
11 | #define OPENSSL_SUPPRESS_DEPRECATED | |
12 | ||
d02b48c6 | 13 | #include <stdio.h> |
c9fb704c | 14 | #include <limits.h> |
c3a73daf | 15 | #include <assert.h> |
ec577822 | 16 | #include <openssl/evp.h> |
7f060601 | 17 | #include <openssl/err.h> |
3a87a9b9 | 18 | #include <openssl/rand.h> |
3f773c91 TM |
19 | #ifndef FIPS_MODULE |
20 | # include <openssl/engine.h> | |
21 | #endif | |
df05f2ce MC |
22 | #include <openssl/params.h> |
23 | #include <openssl/core_names.h> | |
6c9bc258 | 24 | #include "internal/cryptlib.h" |
df05f2ce | 25 | #include "internal/provider.h" |
6c9bc258 | 26 | #include "internal/core.h" |
330ff7e6 | 27 | #include "internal/safe_math.h" |
6c9bc258 | 28 | #include "crypto/evp.h" |
706457b7 | 29 | #include "evp_local.h" |
d02b48c6 | 30 | |
330ff7e6 P |
31 | OSSL_SAFE_MATH_SIGNED(int, int) |
32 | ||
df05f2ce | 33 | int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) |
0f113f3e | 34 | { |
df05f2ce | 35 | if (ctx == NULL) |
8baf9968 | 36 | return 1; |
df05f2ce MC |
37 | |
38 | if (ctx->cipher == NULL || ctx->cipher->prov == NULL) | |
39 | goto legacy; | |
40 | ||
7c14d0c1 | 41 | if (ctx->algctx != NULL) { |
df05f2ce | 42 | if (ctx->cipher->freectx != NULL) |
7c14d0c1 SL |
43 | ctx->cipher->freectx(ctx->algctx); |
44 | ctx->algctx = NULL; | |
df05f2ce MC |
45 | } |
46 | if (ctx->fetched_cipher != NULL) | |
550f974a | 47 | EVP_CIPHER_free(ctx->fetched_cipher); |
df05f2ce | 48 | memset(ctx, 0, sizeof(*ctx)); |
b30b45b7 | 49 | ctx->iv_len = -1; |
df05f2ce MC |
50 | |
51 | return 1; | |
52 | ||
0be6cf0c | 53 | /* Remove legacy code below when legacy support is removed. */ |
df05f2ce MC |
54 | legacy: |
55 | ||
56 | if (ctx->cipher != NULL) { | |
57 | if (ctx->cipher->cleanup && !ctx->cipher->cleanup(ctx)) | |
8baf9968 RL |
58 | return 0; |
59 | /* Cleanse cipher context data */ | |
df05f2ce MC |
60 | if (ctx->cipher_data && ctx->cipher->ctx_size) |
61 | OPENSSL_cleanse(ctx->cipher_data, ctx->cipher->ctx_size); | |
8baf9968 | 62 | } |
df05f2ce | 63 | OPENSSL_free(ctx->cipher_data); |
f844f9eb | 64 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
df05f2ce | 65 | ENGINE_finish(ctx->engine); |
8baf9968 | 66 | #endif |
df05f2ce | 67 | memset(ctx, 0, sizeof(*ctx)); |
b9a2f24e | 68 | ctx->iv_len = -1; |
8baf9968 | 69 | return 1; |
0f113f3e | 70 | } |
d02b48c6 | 71 | |
b40228a6 | 72 | EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) |
0f113f3e | 73 | { |
b9a2f24e HL |
74 | EVP_CIPHER_CTX *ctx; |
75 | ||
76 | ctx = OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX)); | |
77 | if (ctx == NULL) | |
78 | return NULL; | |
79 | ||
80 | ctx->iv_len = -1; | |
81 | return ctx; | |
8baf9968 RL |
82 | } |
83 | ||
84 | void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) | |
85 | { | |
543e740b RS |
86 | if (ctx == NULL) |
87 | return; | |
8baf9968 RL |
88 | EVP_CIPHER_CTX_reset(ctx); |
89 | OPENSSL_free(ctx); | |
0f113f3e | 90 | } |
581f1c84 | 91 | |
4b58d9b4 P |
92 | static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, |
93 | const EVP_CIPHER *cipher, | |
94 | ENGINE *impl, const unsigned char *key, | |
95 | const unsigned char *iv, int enc, | |
96 | const OSSL_PARAM params[]) | |
0f113f3e | 97 | { |
c12bf350 | 98 | int n; |
f844f9eb | 99 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
df05f2ce | 100 | ENGINE *tmpimpl = NULL; |
319e518a | 101 | #endif |
b30b45b7 | 102 | |
df05f2ce MC |
103 | /* |
104 | * enc == 1 means we are encrypting. | |
105 | * enc == 0 means we are decrypting. | |
106 | * enc == -1 means, use the previously initialised value for encrypt/decrypt | |
107 | */ | |
108 | if (enc == -1) { | |
0f113f3e | 109 | enc = ctx->encrypt; |
df05f2ce | 110 | } else { |
0f113f3e MC |
111 | if (enc) |
112 | enc = 1; | |
113 | ctx->encrypt = enc; | |
114 | } | |
df05f2ce MC |
115 | |
116 | if (cipher == NULL && ctx->cipher == NULL) { | |
9311d0c4 | 117 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); |
df05f2ce MC |
118 | return 0; |
119 | } | |
120 | ||
0be6cf0c | 121 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce | 122 | |
f844f9eb | 123 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
0f113f3e MC |
124 | /* |
125 | * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so | |
126 | * this context may already have an ENGINE! Try to avoid releasing the | |
127 | * previous handle, re-querying for an ENGINE, and having a | |
0d4fb843 | 128 | * reinitialisation, when it may all be unnecessary. |
0f113f3e | 129 | */ |
f6b94279 | 130 | if (ctx->engine && ctx->cipher |
a7f9e0a4 | 131 | && (cipher == NULL || cipher->nid == ctx->cipher->nid)) |
0f113f3e | 132 | goto skip_to_init; |
df05f2ce MC |
133 | |
134 | if (cipher != NULL && impl == NULL) { | |
135 | /* Ask if an ENGINE is reserved for this job */ | |
136 | tmpimpl = ENGINE_get_cipher_engine(cipher->nid); | |
137 | } | |
0b13e9f0 | 138 | #endif |
df05f2ce MC |
139 | |
140 | /* | |
141 | * If there are engines involved then we should use legacy handling for now. | |
142 | */ | |
143 | if (ctx->engine != NULL | |
f844f9eb | 144 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
319e518a MC |
145 | || tmpimpl != NULL |
146 | #endif | |
25d47ccc MC |
147 | || impl != NULL |
148 | || (cipher != NULL && cipher->origin == EVP_ORIG_METH) | |
149 | || (cipher == NULL && ctx->cipher != NULL | |
150 | && ctx->cipher->origin == EVP_ORIG_METH)) { | |
df05f2ce MC |
151 | if (ctx->cipher == ctx->fetched_cipher) |
152 | ctx->cipher = NULL; | |
550f974a | 153 | EVP_CIPHER_free(ctx->fetched_cipher); |
df05f2ce MC |
154 | ctx->fetched_cipher = NULL; |
155 | goto legacy; | |
156 | } | |
df05f2ce MC |
157 | /* |
158 | * Ensure a context left lying around from last time is cleared | |
159 | * (legacy code) | |
160 | */ | |
161 | if (cipher != NULL && ctx->cipher != NULL) { | |
f817a743 MC |
162 | if (ctx->cipher->cleanup != NULL && !ctx->cipher->cleanup(ctx)) |
163 | return 0; | |
df05f2ce MC |
164 | OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size); |
165 | ctx->cipher_data = NULL; | |
166 | } | |
167 | ||
0be6cf0c | 168 | /* Start of non-legacy code below */ |
df05f2ce MC |
169 | |
170 | /* Ensure a context left lying around from last time is cleared */ | |
171 | if (cipher != NULL && ctx->cipher != NULL) { | |
172 | unsigned long flags = ctx->flags; | |
173 | ||
174 | EVP_CIPHER_CTX_reset(ctx); | |
175 | /* Restore encrypt and flags */ | |
176 | ctx->encrypt = enc; | |
177 | ctx->flags = flags; | |
178 | } | |
179 | ||
7f612b1f | 180 | if (cipher == NULL) |
df05f2ce MC |
181 | cipher = ctx->cipher; |
182 | ||
183 | if (cipher->prov == NULL) { | |
f844f9eb | 184 | #ifdef FIPS_MODULE |
79c44b4e | 185 | /* We only do explicit fetches inside the FIPS module */ |
9311d0c4 | 186 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
319e518a MC |
187 | return 0; |
188 | #else | |
189 | EVP_CIPHER *provciph = | |
068489a2 MC |
190 | EVP_CIPHER_fetch(NULL, |
191 | cipher->nid == NID_undef ? "NULL" | |
192 | : OBJ_nid2sn(cipher->nid), | |
193 | ""); | |
319e518a | 194 | |
ec0ce188 | 195 | if (provciph == NULL) |
df05f2ce | 196 | return 0; |
df05f2ce | 197 | cipher = provciph; |
550f974a | 198 | EVP_CIPHER_free(ctx->fetched_cipher); |
df05f2ce | 199 | ctx->fetched_cipher = provciph; |
319e518a | 200 | #endif |
df05f2ce MC |
201 | } |
202 | ||
8ed76c62 TM |
203 | if (!ossl_assert(cipher->prov != NULL)) { |
204 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
205 | return 0; | |
206 | } | |
207 | ||
208 | if (cipher != ctx->fetched_cipher) { | |
aea01d13 P |
209 | if (!EVP_CIPHER_up_ref((EVP_CIPHER *)cipher)) { |
210 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
211 | return 0; | |
212 | } | |
213 | EVP_CIPHER_free(ctx->fetched_cipher); | |
71b7f349 P |
214 | /* Coverity false positive, the reference counting is confusing it */ |
215 | /* coverity[use_after_free] */ | |
aea01d13 P |
216 | ctx->fetched_cipher = (EVP_CIPHER *)cipher; |
217 | } | |
df05f2ce | 218 | ctx->cipher = cipher; |
7c14d0c1 SL |
219 | if (ctx->algctx == NULL) { |
220 | ctx->algctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov)); | |
221 | if (ctx->algctx == NULL) { | |
9311d0c4 | 222 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
df05f2ce MC |
223 | return 0; |
224 | } | |
225 | } | |
226 | ||
227 | if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) { | |
0f113f3e | 228 | /* |
df05f2ce MC |
229 | * If this ctx was already set up for no padding then we need to tell |
230 | * the new cipher about it. | |
231 | */ | |
232 | if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) | |
233 | return 0; | |
234 | } | |
235 | ||
f3a7e6c0 P |
236 | #ifndef FIPS_MODULE |
237 | /* | |
238 | * Fix for CVE-2023-5363 | |
239 | * Passing in a size as part of the init call takes effect late | |
240 | * so, force such to occur before the initialisation. | |
241 | * | |
242 | * The FIPS provider's internal library context is used in a manner | |
243 | * such that this is not an issue. | |
244 | */ | |
245 | if (params != NULL) { | |
246 | OSSL_PARAM param_lens[3] = { OSSL_PARAM_END, OSSL_PARAM_END, | |
247 | OSSL_PARAM_END }; | |
248 | OSSL_PARAM *q = param_lens; | |
249 | const OSSL_PARAM *p; | |
250 | ||
251 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); | |
252 | if (p != NULL) | |
253 | memcpy(q++, p, sizeof(*q)); | |
254 | ||
255 | /* | |
164a541b | 256 | * Note that OSSL_CIPHER_PARAM_AEAD_IVLEN is a synonym for |
f3a7e6c0 P |
257 | * OSSL_CIPHER_PARAM_IVLEN so both are covered here. |
258 | */ | |
259 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN); | |
260 | if (p != NULL) | |
261 | memcpy(q++, p, sizeof(*q)); | |
262 | ||
263 | if (q != param_lens) { | |
264 | if (!EVP_CIPHER_CTX_set_params(ctx, param_lens)) { | |
265 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH); | |
266 | return 0; | |
267 | } | |
268 | } | |
269 | } | |
270 | #endif | |
271 | ||
df05f2ce MC |
272 | if (enc) { |
273 | if (ctx->cipher->einit == NULL) { | |
9311d0c4 | 274 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
df05f2ce MC |
275 | return 0; |
276 | } | |
277 | ||
7c14d0c1 | 278 | return ctx->cipher->einit(ctx->algctx, |
344cfa34 | 279 | key, |
33b40a10 | 280 | key == NULL ? 0 |
ed576acd | 281 | : EVP_CIPHER_CTX_get_key_length(ctx), |
344cfa34 | 282 | iv, |
33b40a10 | 283 | iv == NULL ? 0 |
ed576acd | 284 | : EVP_CIPHER_CTX_get_iv_length(ctx), |
4b58d9b4 | 285 | params); |
df05f2ce MC |
286 | } |
287 | ||
288 | if (ctx->cipher->dinit == NULL) { | |
9311d0c4 | 289 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
df05f2ce MC |
290 | return 0; |
291 | } | |
292 | ||
7c14d0c1 | 293 | return ctx->cipher->dinit(ctx->algctx, |
344cfa34 | 294 | key, |
33b40a10 | 295 | key == NULL ? 0 |
ed576acd | 296 | : EVP_CIPHER_CTX_get_key_length(ctx), |
344cfa34 | 297 | iv, |
33b40a10 | 298 | iv == NULL ? 0 |
ed576acd | 299 | : EVP_CIPHER_CTX_get_iv_length(ctx), |
4b58d9b4 | 300 | params); |
df05f2ce | 301 | |
0be6cf0c | 302 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce MC |
303 | legacy: |
304 | ||
305 | if (cipher != NULL) { | |
306 | /* | |
307 | * Ensure a context left lying around from last time is cleared (we | |
308 | * previously attempted to avoid this if the same ENGINE and | |
0f113f3e MC |
309 | * EVP_CIPHER could be used). |
310 | */ | |
311 | if (ctx->cipher) { | |
312 | unsigned long flags = ctx->flags; | |
c0ca39bd | 313 | EVP_CIPHER_CTX_reset(ctx); |
0f113f3e MC |
314 | /* Restore encrypt and flags */ |
315 | ctx->encrypt = enc; | |
316 | ctx->flags = flags; | |
317 | } | |
f844f9eb | 318 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
df05f2ce | 319 | if (impl != NULL) { |
0f113f3e | 320 | if (!ENGINE_init(impl)) { |
9311d0c4 | 321 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
0f113f3e MC |
322 | return 0; |
323 | } | |
df05f2ce MC |
324 | } else { |
325 | impl = tmpimpl; | |
326 | } | |
327 | if (impl != NULL) { | |
0f113f3e MC |
328 | /* There's an ENGINE for this job ... (apparently) */ |
329 | const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); | |
df05f2ce MC |
330 | |
331 | if (c == NULL) { | |
0f113f3e MC |
332 | /* |
333 | * One positive side-effect of US's export control history, | |
334 | * is that we should at least be able to avoid using US | |
0d4fb843 | 335 | * misspellings of "initialisation"? |
0f113f3e | 336 | */ |
9311d0c4 | 337 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
0f113f3e MC |
338 | return 0; |
339 | } | |
340 | /* We'll use the ENGINE's private cipher definition */ | |
341 | cipher = c; | |
342 | /* | |
343 | * Store the ENGINE functional reference so we know 'cipher' came | |
344 | * from an ENGINE and we need to release it when done. | |
345 | */ | |
346 | ctx->engine = impl; | |
df05f2ce | 347 | } else { |
0f113f3e | 348 | ctx->engine = NULL; |
df05f2ce | 349 | } |
0b13e9f0 | 350 | #endif |
544a2aea | 351 | |
0f113f3e MC |
352 | ctx->cipher = cipher; |
353 | if (ctx->cipher->ctx_size) { | |
b51bce94 | 354 | ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size); |
90945fa3 | 355 | if (ctx->cipher_data == NULL) { |
273a0218 | 356 | ctx->cipher = NULL; |
0f113f3e MC |
357 | return 0; |
358 | } | |
359 | } else { | |
360 | ctx->cipher_data = NULL; | |
361 | } | |
362 | ctx->key_len = cipher->key_len; | |
363 | /* Preserve wrap enable flag, zero everything else */ | |
364 | ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; | |
365 | if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { | |
d649c51a | 366 | if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL) <= 0) { |
273a0218 | 367 | ctx->cipher = NULL; |
9311d0c4 | 368 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
0f113f3e MC |
369 | return 0; |
370 | } | |
371 | } | |
0f113f3e | 372 | } |
f844f9eb | 373 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
0f113f3e | 374 | skip_to_init: |
0b13e9f0 | 375 | #endif |
1702c500 P |
376 | if (ctx->cipher == NULL) |
377 | return 0; | |
378 | ||
0f113f3e MC |
379 | /* we assume block size is a power of 2 in *cryptUpdate */ |
380 | OPENSSL_assert(ctx->cipher->block_size == 1 | |
381 | || ctx->cipher->block_size == 8 | |
382 | || ctx->cipher->block_size == 16); | |
383 | ||
384 | if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) | |
ed576acd | 385 | && EVP_CIPHER_CTX_get_mode(ctx) == EVP_CIPH_WRAP_MODE) { |
9311d0c4 | 386 | ERR_raise(ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED); |
0f113f3e MC |
387 | return 0; |
388 | } | |
389 | ||
ed576acd | 390 | if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) |
f6c95e46 | 391 | & EVP_CIPH_CUSTOM_IV) == 0) { |
ed576acd | 392 | switch (EVP_CIPHER_CTX_get_mode(ctx)) { |
0f113f3e MC |
393 | |
394 | case EVP_CIPH_STREAM_CIPHER: | |
395 | case EVP_CIPH_ECB_MODE: | |
396 | break; | |
397 | ||
398 | case EVP_CIPH_CFB_MODE: | |
399 | case EVP_CIPH_OFB_MODE: | |
400 | ||
401 | ctx->num = 0; | |
402 | /* fall-through */ | |
403 | ||
404 | case EVP_CIPH_CBC_MODE: | |
ed576acd | 405 | n = EVP_CIPHER_CTX_get_iv_length(ctx); |
d1592f21 P |
406 | if (n < 0 || n > (int)sizeof(ctx->iv)) { |
407 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH); | |
408 | return 0; | |
409 | } | |
cec8854c | 410 | if (iv != NULL) |
69807ab8 P |
411 | memcpy(ctx->oiv, iv, n); |
412 | memcpy(ctx->iv, ctx->oiv, n); | |
0f113f3e MC |
413 | break; |
414 | ||
415 | case EVP_CIPH_CTR_MODE: | |
416 | ctx->num = 0; | |
417 | /* Don't reuse IV for CTR mode */ | |
cec8854c | 418 | if (iv != NULL) { |
d1592f21 P |
419 | n = EVP_CIPHER_CTX_get_iv_length(ctx); |
420 | if (n <= 0 || n > (int)sizeof(ctx->iv)) { | |
421 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH); | |
cec8854c | 422 | return 0; |
d1592f21 | 423 | } |
cec8854c P |
424 | memcpy(ctx->iv, iv, n); |
425 | } | |
0f113f3e MC |
426 | break; |
427 | ||
428 | default: | |
429 | return 0; | |
0f113f3e MC |
430 | } |
431 | } | |
432 | ||
cec8854c | 433 | if (key != NULL || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { |
0f113f3e MC |
434 | if (!ctx->cipher->init(ctx, key, iv, enc)) |
435 | return 0; | |
436 | } | |
437 | ctx->buf_len = 0; | |
438 | ctx->final_used = 0; | |
439 | ctx->block_mask = ctx->cipher->block_size - 1; | |
440 | return 1; | |
441 | } | |
d02b48c6 | 442 | |
4b58d9b4 P |
443 | int EVP_CipherInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
444 | const unsigned char *key, const unsigned char *iv, | |
445 | int enc, const OSSL_PARAM params[]) | |
446 | { | |
447 | return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, params); | |
448 | } | |
449 | ||
450 | int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | |
451 | const unsigned char *key, const unsigned char *iv, int enc) | |
452 | { | |
453 | if (cipher != NULL) | |
454 | EVP_CIPHER_CTX_reset(ctx); | |
455 | return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, NULL); | |
456 | } | |
457 | ||
458 | int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | |
459 | ENGINE *impl, const unsigned char *key, | |
460 | const unsigned char *iv, int enc) | |
461 | { | |
462 | return evp_cipher_init_internal(ctx, cipher, impl, key, iv, enc, NULL); | |
463 | } | |
464 | ||
be06a934 | 465 | int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
0f113f3e MC |
466 | const unsigned char *in, int inl) |
467 | { | |
468 | if (ctx->encrypt) | |
469 | return EVP_EncryptUpdate(ctx, out, outl, in, inl); | |
470 | else | |
471 | return EVP_DecryptUpdate(ctx, out, outl, in, inl); | |
472 | } | |
d02b48c6 | 473 | |
581f1c84 | 474 | int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
0f113f3e MC |
475 | { |
476 | if (ctx->encrypt) | |
477 | return EVP_EncryptFinal_ex(ctx, out, outl); | |
478 | else | |
479 | return EVP_DecryptFinal_ex(ctx, out, outl); | |
480 | } | |
581f1c84 | 481 | |
6b691a5c | 482 | int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
0f113f3e MC |
483 | { |
484 | if (ctx->encrypt) | |
485 | return EVP_EncryptFinal(ctx, out, outl); | |
486 | else | |
487 | return EVP_DecryptFinal(ctx, out, outl); | |
488 | } | |
d02b48c6 | 489 | |
be06a934 | 490 | int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
0f113f3e MC |
491 | const unsigned char *key, const unsigned char *iv) |
492 | { | |
493 | return EVP_CipherInit(ctx, cipher, key, iv, 1); | |
494 | } | |
18eda732 | 495 | |
0f113f3e MC |
496 | int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
497 | ENGINE *impl, const unsigned char *key, | |
498 | const unsigned char *iv) | |
499 | { | |
500 | return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); | |
501 | } | |
d02b48c6 | 502 | |
4b58d9b4 P |
503 | int EVP_EncryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
504 | const unsigned char *key, const unsigned char *iv, | |
505 | const OSSL_PARAM params[]) | |
506 | { | |
507 | return EVP_CipherInit_ex2(ctx, cipher, key, iv, 1, params); | |
508 | } | |
509 | ||
be06a934 | 510 | int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
0f113f3e MC |
511 | const unsigned char *key, const unsigned char *iv) |
512 | { | |
513 | return EVP_CipherInit(ctx, cipher, key, iv, 0); | |
514 | } | |
18eda732 | 515 | |
0f113f3e MC |
516 | int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
517 | ENGINE *impl, const unsigned char *key, | |
518 | const unsigned char *iv) | |
519 | { | |
520 | return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); | |
521 | } | |
d02b48c6 | 522 | |
4b58d9b4 P |
523 | int EVP_DecryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
524 | const unsigned char *key, const unsigned char *iv, | |
525 | const OSSL_PARAM params[]) | |
526 | { | |
527 | return EVP_CipherInit_ex2(ctx, cipher, key, iv, 0, params); | |
528 | } | |
529 | ||
c3a73daf AP |
530 | /* |
531 | * According to the letter of standard difference between pointers | |
532 | * is specified to be valid only within same object. This makes | |
533 | * it formally challenging to determine if input and output buffers | |
534 | * are not partially overlapping with standard pointer arithmetic. | |
535 | */ | |
536 | #ifdef PTRDIFF_T | |
537 | # undef PTRDIFF_T | |
538 | #endif | |
539 | #if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE==64 | |
540 | /* | |
541 | * Then we have VMS that distinguishes itself by adhering to | |
5fc77684 AP |
542 | * sizeof(size_t)==4 even in 64-bit builds, which means that |
543 | * difference between two pointers might be truncated to 32 bits. | |
544 | * In the context one can even wonder how comparison for | |
545 | * equality is implemented. To be on the safe side we adhere to | |
546 | * PTRDIFF_T even for comparison for equality. | |
c3a73daf AP |
547 | */ |
548 | # define PTRDIFF_T uint64_t | |
549 | #else | |
550 | # define PTRDIFF_T size_t | |
551 | #endif | |
552 | ||
6d777689 | 553 | int ossl_is_partially_overlapping(const void *ptr1, const void *ptr2, int len) |
c3a73daf AP |
554 | { |
555 | PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2; | |
556 | /* | |
557 | * Check for partially overlapping buffers. [Binary logical | |
558 | * operations are used instead of boolean to minimize number | |
559 | * of conditional branches.] | |
560 | */ | |
83151b73 AP |
561 | int overlapped = (len > 0) & (diff != 0) & ((diff < (PTRDIFF_T)len) | |
562 | (diff > (0 - (PTRDIFF_T)len))); | |
b153f092 | 563 | |
83151b73 | 564 | return overlapped; |
c3a73daf AP |
565 | } |
566 | ||
a8bf2f8f RL |
567 | static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, |
568 | unsigned char *out, int *outl, | |
569 | const unsigned char *in, int inl) | |
0f113f3e | 570 | { |
64846096 LP |
571 | int i, j, bl, cmpl = inl; |
572 | ||
573 | if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) | |
330ff7e6 | 574 | cmpl = safe_div_round_up_int(cmpl, 8, NULL); |
0f113f3e | 575 | |
7141ba31 MC |
576 | bl = ctx->cipher->block_size; |
577 | ||
0f113f3e | 578 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { |
7141ba31 | 579 | /* If block size > 1 then the cipher will have to do this check */ |
6d777689 | 580 | if (bl == 1 && ossl_is_partially_overlapping(out, in, cmpl)) { |
9311d0c4 | 581 | ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); |
5fc77684 | 582 | return 0; |
83151b73 | 583 | } |
5fc77684 | 584 | |
0f113f3e MC |
585 | i = ctx->cipher->do_cipher(ctx, out, in, inl); |
586 | if (i < 0) | |
587 | return 0; | |
588 | else | |
589 | *outl = i; | |
590 | return 1; | |
591 | } | |
592 | ||
2c236894 MC |
593 | if (inl <= 0) { |
594 | *outl = 0; | |
595 | return inl == 0; | |
596 | } | |
6d777689 | 597 | if (ossl_is_partially_overlapping(out + ctx->buf_len, in, cmpl)) { |
9311d0c4 | 598 | ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); |
5fc77684 | 599 | return 0; |
83151b73 | 600 | } |
0f113f3e MC |
601 | |
602 | if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) { | |
603 | if (ctx->cipher->do_cipher(ctx, out, in, inl)) { | |
604 | *outl = inl; | |
605 | return 1; | |
606 | } else { | |
607 | *outl = 0; | |
608 | return 0; | |
609 | } | |
610 | } | |
611 | i = ctx->buf_len; | |
0f113f3e MC |
612 | OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); |
613 | if (i != 0) { | |
3f358213 | 614 | if (bl - i > inl) { |
0f113f3e MC |
615 | memcpy(&(ctx->buf[i]), in, inl); |
616 | ctx->buf_len += inl; | |
617 | *outl = 0; | |
618 | return 1; | |
619 | } else { | |
620 | j = bl - i; | |
c9fb704c MC |
621 | |
622 | /* | |
623 | * Once we've processed the first j bytes from in, the amount of | |
624 | * data left that is a multiple of the block length is: | |
625 | * (inl - j) & ~(bl - 1) | |
626 | * We must ensure that this amount of data, plus the one block that | |
627 | * we process from ctx->buf does not exceed INT_MAX | |
628 | */ | |
629 | if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) { | |
630 | ERR_raise(ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW); | |
631 | return 0; | |
632 | } | |
0f113f3e | 633 | memcpy(&(ctx->buf[i]), in, j); |
0f113f3e MC |
634 | inl -= j; |
635 | in += j; | |
5fc77684 AP |
636 | if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl)) |
637 | return 0; | |
0f113f3e MC |
638 | out += bl; |
639 | *outl = bl; | |
640 | } | |
641 | } else | |
642 | *outl = 0; | |
643 | i = inl & (bl - 1); | |
644 | inl -= i; | |
645 | if (inl > 0) { | |
646 | if (!ctx->cipher->do_cipher(ctx, out, in, inl)) | |
647 | return 0; | |
648 | *outl += inl; | |
649 | } | |
650 | ||
651 | if (i != 0) | |
652 | memcpy(ctx->buf, &(in[inl]), i); | |
653 | ctx->buf_len = i; | |
654 | return 1; | |
655 | } | |
d02b48c6 | 656 | |
a8bf2f8f RL |
657 | |
658 | int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |
659 | const unsigned char *in, int inl) | |
660 | { | |
df05f2ce | 661 | int ret; |
1832bb0f | 662 | size_t soutl, inl_ = (size_t)inl; |
3b94944c | 663 | int blocksize; |
df05f2ce | 664 | |
f1e0c945 | 665 | if (ossl_likely(outl != NULL)) { |
3d4c81b0 | 666 | *outl = 0; |
667 | } else { | |
9311d0c4 | 668 | ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); |
3d4c81b0 | 669 | return 0; |
670 | } | |
671 | ||
a8bf2f8f | 672 | /* Prevent accidental use of decryption context when encrypting */ |
f1e0c945 | 673 | if (ossl_unlikely(!ctx->encrypt)) { |
9311d0c4 | 674 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); |
a8bf2f8f RL |
675 | return 0; |
676 | } | |
677 | ||
f1e0c945 | 678 | if (ossl_unlikely(ctx->cipher == NULL)) { |
9311d0c4 | 679 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); |
d4d89a07 SS |
680 | return 0; |
681 | } | |
682 | ||
f1e0c945 | 683 | if (ossl_unlikely(ctx->cipher->prov == NULL)) |
df05f2ce MC |
684 | goto legacy; |
685 | ||
30af356d | 686 | blocksize = ctx->cipher->block_size; |
3b94944c | 687 | |
f1e0c945 | 688 | if (ossl_unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) { |
9311d0c4 | 689 | ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); |
df05f2ce MC |
690 | return 0; |
691 | } | |
1832bb0f | 692 | |
7c14d0c1 | 693 | ret = ctx->cipher->cupdate(ctx->algctx, out, &soutl, |
1832bb0f HL |
694 | inl_ + (size_t)(blocksize == 1 ? 0 : blocksize), |
695 | in, inl_); | |
df05f2ce | 696 | |
f1e0c945 | 697 | if (ossl_likely(ret)) { |
36e619d7 | 698 | if (soutl > INT_MAX) { |
9311d0c4 | 699 | ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); |
36e619d7 GV |
700 | return 0; |
701 | } | |
702 | *outl = soutl; | |
df05f2ce | 703 | } |
36e619d7 | 704 | |
df05f2ce MC |
705 | return ret; |
706 | ||
0be6cf0c | 707 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce MC |
708 | legacy: |
709 | ||
a8bf2f8f RL |
710 | return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl); |
711 | } | |
712 | ||
be06a934 | 713 | int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
0f113f3e MC |
714 | { |
715 | int ret; | |
716 | ret = EVP_EncryptFinal_ex(ctx, out, outl); | |
717 | return ret; | |
718 | } | |
581f1c84 DSH |
719 | |
720 | int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | |
0f113f3e MC |
721 | { |
722 | int n, ret; | |
723 | unsigned int i, b, bl; | |
df05f2ce | 724 | size_t soutl; |
3b94944c | 725 | int blocksize; |
0f113f3e | 726 | |
3d4c81b0 | 727 | if (outl != NULL) { |
728 | *outl = 0; | |
729 | } else { | |
9311d0c4 | 730 | ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); |
3d4c81b0 | 731 | return 0; |
732 | } | |
733 | ||
a8bf2f8f RL |
734 | /* Prevent accidental use of decryption context when encrypting */ |
735 | if (!ctx->encrypt) { | |
9311d0c4 | 736 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); |
a8bf2f8f RL |
737 | return 0; |
738 | } | |
739 | ||
4894dcad | 740 | if (ctx->cipher == NULL) { |
9311d0c4 | 741 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); |
4894dcad P |
742 | return 0; |
743 | } | |
744 | if (ctx->cipher->prov == NULL) | |
df05f2ce MC |
745 | goto legacy; |
746 | ||
ed576acd | 747 | blocksize = EVP_CIPHER_CTX_get_block_size(ctx); |
3b94944c MC |
748 | |
749 | if (blocksize < 1 || ctx->cipher->cfinal == NULL) { | |
9311d0c4 | 750 | ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); |
df05f2ce MC |
751 | return 0; |
752 | } | |
753 | ||
7c14d0c1 | 754 | ret = ctx->cipher->cfinal(ctx->algctx, out, &soutl, |
3b94944c | 755 | blocksize == 1 ? 0 : blocksize); |
df05f2ce | 756 | |
36e619d7 GV |
757 | if (ret) { |
758 | if (soutl > INT_MAX) { | |
9311d0c4 | 759 | ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); |
36e619d7 GV |
760 | return 0; |
761 | } | |
762 | *outl = soutl; | |
df05f2ce | 763 | } |
df05f2ce MC |
764 | |
765 | return ret; | |
766 | ||
0be6cf0c | 767 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce MC |
768 | legacy: |
769 | ||
0f113f3e MC |
770 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { |
771 | ret = ctx->cipher->do_cipher(ctx, out, NULL, 0); | |
772 | if (ret < 0) | |
773 | return 0; | |
774 | else | |
775 | *outl = ret; | |
776 | return 1; | |
777 | } | |
778 | ||
779 | b = ctx->cipher->block_size; | |
cbe29648 | 780 | OPENSSL_assert(b <= sizeof(ctx->buf)); |
0f113f3e MC |
781 | if (b == 1) { |
782 | *outl = 0; | |
783 | return 1; | |
784 | } | |
785 | bl = ctx->buf_len; | |
786 | if (ctx->flags & EVP_CIPH_NO_PADDING) { | |
787 | if (bl) { | |
9311d0c4 | 788 | ERR_raise(ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); |
0f113f3e MC |
789 | return 0; |
790 | } | |
791 | *outl = 0; | |
792 | return 1; | |
793 | } | |
794 | ||
795 | n = b - bl; | |
796 | for (i = bl; i < b; i++) | |
797 | ctx->buf[i] = n; | |
798 | ret = ctx->cipher->do_cipher(ctx, out, ctx->buf, b); | |
799 | ||
800 | if (ret) | |
801 | *outl = b; | |
802 | ||
803 | return ret; | |
804 | } | |
d02b48c6 | 805 | |
be06a934 | 806 | int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
0f113f3e MC |
807 | const unsigned char *in, int inl) |
808 | { | |
df05f2ce | 809 | int fix_len, cmpl = inl, ret; |
0f113f3e | 810 | unsigned int b; |
1832bb0f | 811 | size_t soutl, inl_ = (size_t)inl; |
3b94944c | 812 | int blocksize; |
0f113f3e | 813 | |
f1e0c945 | 814 | if (ossl_likely(outl != NULL)) { |
3d4c81b0 | 815 | *outl = 0; |
816 | } else { | |
9311d0c4 | 817 | ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); |
3d4c81b0 | 818 | return 0; |
819 | } | |
820 | ||
a8bf2f8f | 821 | /* Prevent accidental use of encryption context when decrypting */ |
f1e0c945 | 822 | if (ossl_unlikely(ctx->encrypt)) { |
9311d0c4 | 823 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); |
a8bf2f8f RL |
824 | return 0; |
825 | } | |
826 | ||
f1e0c945 | 827 | if (ossl_unlikely(ctx->cipher == NULL)) { |
9311d0c4 | 828 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); |
d2c2e49e P |
829 | return 0; |
830 | } | |
f1e0c945 | 831 | if (ossl_unlikely(ctx->cipher->prov == NULL)) |
df05f2ce MC |
832 | goto legacy; |
833 | ||
ed576acd | 834 | blocksize = EVP_CIPHER_CTX_get_block_size(ctx); |
3b94944c | 835 | |
f1e0c945 | 836 | if (ossl_unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) { |
9311d0c4 | 837 | ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); |
df05f2ce MC |
838 | return 0; |
839 | } | |
7c14d0c1 | 840 | ret = ctx->cipher->cupdate(ctx->algctx, out, &soutl, |
1832bb0f HL |
841 | inl_ + (size_t)(blocksize == 1 ? 0 : blocksize), |
842 | in, inl_); | |
df05f2ce | 843 | |
f1e0c945 | 844 | if (ossl_likely(ret)) { |
df05f2ce | 845 | if (soutl > INT_MAX) { |
9311d0c4 | 846 | ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); |
df05f2ce MC |
847 | return 0; |
848 | } | |
849 | *outl = soutl; | |
850 | } | |
851 | ||
852 | return ret; | |
853 | ||
0be6cf0c | 854 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce MC |
855 | legacy: |
856 | ||
7141ba31 MC |
857 | b = ctx->cipher->block_size; |
858 | ||
64846096 | 859 | if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) |
330ff7e6 | 860 | cmpl = safe_div_round_up_int(cmpl, 8, NULL); |
64846096 | 861 | |
0f113f3e | 862 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { |
6d777689 | 863 | if (b == 1 && ossl_is_partially_overlapping(out, in, cmpl)) { |
9311d0c4 | 864 | ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); |
5fc77684 | 865 | return 0; |
83151b73 | 866 | } |
5fc77684 | 867 | |
0f113f3e MC |
868 | fix_len = ctx->cipher->do_cipher(ctx, out, in, inl); |
869 | if (fix_len < 0) { | |
870 | *outl = 0; | |
871 | return 0; | |
872 | } else | |
873 | *outl = fix_len; | |
874 | return 1; | |
875 | } | |
876 | ||
2c236894 MC |
877 | if (inl <= 0) { |
878 | *outl = 0; | |
879 | return inl == 0; | |
880 | } | |
881 | ||
0f113f3e | 882 | if (ctx->flags & EVP_CIPH_NO_PADDING) |
a8bf2f8f | 883 | return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl); |
0f113f3e | 884 | |
cbe29648 | 885 | OPENSSL_assert(b <= sizeof(ctx->final)); |
0f113f3e MC |
886 | |
887 | if (ctx->final_used) { | |
5fc77684 AP |
888 | /* see comment about PTRDIFF_T comparison above */ |
889 | if (((PTRDIFF_T)out == (PTRDIFF_T)in) | |
6d777689 | 890 | || ossl_is_partially_overlapping(out, in, b)) { |
9311d0c4 | 891 | ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); |
5fc77684 | 892 | return 0; |
83151b73 | 893 | } |
c9fb704c MC |
894 | /* |
895 | * final_used is only ever set if buf_len is 0. Therefore the maximum | |
896 | * length output we will ever see from evp_EncryptDecryptUpdate is | |
897 | * the maximum multiple of the block length that is <= inl, or just: | |
898 | * inl & ~(b - 1) | |
899 | * Since final_used has been set then the final output length is: | |
900 | * (inl & ~(b - 1)) + b | |
901 | * This must never exceed INT_MAX | |
902 | */ | |
903 | if ((inl & ~(b - 1)) > INT_MAX - b) { | |
904 | ERR_raise(ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW); | |
905 | return 0; | |
906 | } | |
0f113f3e MC |
907 | memcpy(out, ctx->final, b); |
908 | out += b; | |
909 | fix_len = 1; | |
910 | } else | |
911 | fix_len = 0; | |
912 | ||
a8bf2f8f | 913 | if (!evp_EncryptDecryptUpdate(ctx, out, outl, in, inl)) |
0f113f3e MC |
914 | return 0; |
915 | ||
916 | /* | |
917 | * if we have 'decrypted' a multiple of block size, make sure we have a | |
918 | * copy of this last block | |
919 | */ | |
920 | if (b > 1 && !ctx->buf_len) { | |
921 | *outl -= b; | |
922 | ctx->final_used = 1; | |
923 | memcpy(ctx->final, &out[*outl], b); | |
924 | } else | |
925 | ctx->final_used = 0; | |
926 | ||
927 | if (fix_len) | |
928 | *outl += b; | |
929 | ||
930 | return 1; | |
931 | } | |
d02b48c6 | 932 | |
6b691a5c | 933 | int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
0f113f3e MC |
934 | { |
935 | int ret; | |
936 | ret = EVP_DecryptFinal_ex(ctx, out, outl); | |
937 | return ret; | |
938 | } | |
581f1c84 DSH |
939 | |
940 | int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | |
0f113f3e MC |
941 | { |
942 | int i, n; | |
943 | unsigned int b; | |
df05f2ce MC |
944 | size_t soutl; |
945 | int ret; | |
3b94944c | 946 | int blocksize; |
a8bf2f8f | 947 | |
3d4c81b0 | 948 | if (outl != NULL) { |
949 | *outl = 0; | |
950 | } else { | |
9311d0c4 | 951 | ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); |
3d4c81b0 | 952 | return 0; |
953 | } | |
954 | ||
a8bf2f8f RL |
955 | /* Prevent accidental use of encryption context when decrypting */ |
956 | if (ctx->encrypt) { | |
9311d0c4 | 957 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); |
a8bf2f8f RL |
958 | return 0; |
959 | } | |
960 | ||
d4d89a07 | 961 | if (ctx->cipher == NULL) { |
9311d0c4 | 962 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); |
d4d89a07 SS |
963 | return 0; |
964 | } | |
965 | ||
966 | if (ctx->cipher->prov == NULL) | |
df05f2ce MC |
967 | goto legacy; |
968 | ||
ed576acd | 969 | blocksize = EVP_CIPHER_CTX_get_block_size(ctx); |
3b94944c MC |
970 | |
971 | if (blocksize < 1 || ctx->cipher->cfinal == NULL) { | |
9311d0c4 | 972 | ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); |
df05f2ce MC |
973 | return 0; |
974 | } | |
975 | ||
7c14d0c1 | 976 | ret = ctx->cipher->cfinal(ctx->algctx, out, &soutl, |
3b94944c | 977 | blocksize == 1 ? 0 : blocksize); |
df05f2ce MC |
978 | |
979 | if (ret) { | |
980 | if (soutl > INT_MAX) { | |
9311d0c4 | 981 | ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); |
df05f2ce MC |
982 | return 0; |
983 | } | |
984 | *outl = soutl; | |
985 | } | |
986 | ||
987 | return ret; | |
988 | ||
0be6cf0c | 989 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce MC |
990 | legacy: |
991 | ||
0f113f3e | 992 | *outl = 0; |
0f113f3e MC |
993 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { |
994 | i = ctx->cipher->do_cipher(ctx, out, NULL, 0); | |
995 | if (i < 0) | |
996 | return 0; | |
997 | else | |
998 | *outl = i; | |
999 | return 1; | |
1000 | } | |
1001 | ||
1002 | b = ctx->cipher->block_size; | |
1003 | if (ctx->flags & EVP_CIPH_NO_PADDING) { | |
1004 | if (ctx->buf_len) { | |
9311d0c4 | 1005 | ERR_raise(ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); |
0f113f3e MC |
1006 | return 0; |
1007 | } | |
1008 | *outl = 0; | |
1009 | return 1; | |
1010 | } | |
1011 | if (b > 1) { | |
1012 | if (ctx->buf_len || !ctx->final_used) { | |
9311d0c4 | 1013 | ERR_raise(ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH); |
26a7d938 | 1014 | return 0; |
0f113f3e | 1015 | } |
cbe29648 | 1016 | OPENSSL_assert(b <= sizeof(ctx->final)); |
0f113f3e MC |
1017 | |
1018 | /* | |
1019 | * The following assumes that the ciphertext has been authenticated. | |
1020 | * Otherwise it provides a padding oracle. | |
1021 | */ | |
1022 | n = ctx->final[b - 1]; | |
1023 | if (n == 0 || n > (int)b) { | |
9311d0c4 | 1024 | ERR_raise(ERR_LIB_EVP, EVP_R_BAD_DECRYPT); |
26a7d938 | 1025 | return 0; |
0f113f3e MC |
1026 | } |
1027 | for (i = 0; i < n; i++) { | |
1028 | if (ctx->final[--b] != n) { | |
9311d0c4 | 1029 | ERR_raise(ERR_LIB_EVP, EVP_R_BAD_DECRYPT); |
26a7d938 | 1030 | return 0; |
0f113f3e MC |
1031 | } |
1032 | } | |
1033 | n = ctx->cipher->block_size - n; | |
1034 | for (i = 0; i < n; i++) | |
1035 | out[i] = ctx->final[i]; | |
1036 | *outl = n; | |
1037 | } else | |
1038 | *outl = 0; | |
208fb891 | 1039 | return 1; |
0f113f3e | 1040 | } |
d02b48c6 | 1041 | |
6343829a | 1042 | int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) |
0f113f3e | 1043 | { |
d23adad1 MC |
1044 | if (c->cipher->prov != NULL) { |
1045 | int ok; | |
1046 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | |
70f39a48 | 1047 | size_t len; |
459b15d4 | 1048 | |
ed576acd | 1049 | if (EVP_CIPHER_CTX_get_key_length(c) == keylen) |
d23adad1 MC |
1050 | return 1; |
1051 | ||
1052 | /* Check the cipher actually understands this parameter */ | |
1053 | if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher), | |
0f70d601 TM |
1054 | OSSL_CIPHER_PARAM_KEYLEN) == NULL) { |
1055 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); | |
d23adad1 | 1056 | return 0; |
0f70d601 | 1057 | } |
d23adad1 MC |
1058 | |
1059 | params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len); | |
70f39a48 P |
1060 | if (!OSSL_PARAM_set_int(params, keylen)) |
1061 | return 0; | |
7c14d0c1 | 1062 | ok = evp_do_ciph_ctx_setparams(c->cipher, c->algctx, params); |
70f39a48 P |
1063 | if (ok <= 0) |
1064 | return 0; | |
1065 | c->key_len = keylen; | |
1066 | return 1; | |
d23adad1 | 1067 | } |
13273237 | 1068 | |
0be6cf0c | 1069 | /* Code below to be removed when legacy support is dropped. */ |
d23adad1 MC |
1070 | |
1071 | /* | |
1072 | * Note there have never been any built-in ciphers that define this flag | |
1073 | * since it was first introduced. | |
1074 | */ | |
0f113f3e MC |
1075 | if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) |
1076 | return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); | |
ed576acd | 1077 | if (EVP_CIPHER_CTX_get_key_length(c) == keylen) |
0f113f3e MC |
1078 | return 1; |
1079 | if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { | |
1080 | c->key_len = keylen; | |
1081 | return 1; | |
1082 | } | |
9311d0c4 | 1083 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); |
0f113f3e MC |
1084 | return 0; |
1085 | } | |
49528751 | 1086 | |
f2e5ca84 | 1087 | int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) |
0f113f3e | 1088 | { |
13273237 | 1089 | int ok; |
459b15d4 | 1090 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; |
1c3ace68 | 1091 | unsigned int pd = pad; |
13273237 | 1092 | |
0f113f3e MC |
1093 | if (pad) |
1094 | ctx->flags &= ~EVP_CIPH_NO_PADDING; | |
1095 | else | |
1096 | ctx->flags |= EVP_CIPH_NO_PADDING; | |
df05f2ce | 1097 | |
719bc0e8 SL |
1098 | if (ctx->cipher != NULL && ctx->cipher->prov == NULL) |
1099 | return 1; | |
1c3ace68 | 1100 | params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pd); |
7c14d0c1 | 1101 | ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); |
459b15d4 | 1102 | |
13273237 | 1103 | return ok != 0; |
0f113f3e | 1104 | } |
f2e5ca84 | 1105 | |
49528751 DSH |
1106 | int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) |
1107 | { | |
e870791a | 1108 | int ret = EVP_CTRL_RET_UNSUPPORTED; |
459b15d4 | 1109 | int set_params = 1; |
1c3ace68 | 1110 | size_t sz = arg; |
6a41156c | 1111 | unsigned int i; |
0d2bfe52 SL |
1112 | OSSL_PARAM params[4] = { |
1113 | OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END | |
1114 | }; | |
d91f4568 | 1115 | |
459b15d4 | 1116 | if (ctx == NULL || ctx->cipher == NULL) { |
9311d0c4 | 1117 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); |
0f113f3e MC |
1118 | return 0; |
1119 | } | |
1120 | ||
13273237 RL |
1121 | if (ctx->cipher->prov == NULL) |
1122 | goto legacy; | |
1123 | ||
1124 | switch (type) { | |
1125 | case EVP_CTRL_SET_KEY_LENGTH: | |
eb52450f TM |
1126 | if (arg < 0) |
1127 | return 0; | |
1128 | if (ctx->key_len == arg) | |
1129 | /* Skip calling into provider if unchanged. */ | |
1130 | return 1; | |
1c3ace68 | 1131 | params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &sz); |
70f39a48 | 1132 | ctx->key_len = -1; |
13273237 RL |
1133 | break; |
1134 | case EVP_CTRL_RAND_KEY: /* Used by DES */ | |
4a42e264 SL |
1135 | set_params = 0; |
1136 | params[0] = | |
1137 | OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, | |
1c3ace68 | 1138 | ptr, sz); |
4a42e264 SL |
1139 | break; |
1140 | ||
d6d74cf4 RL |
1141 | case EVP_CTRL_INIT: |
1142 | /* | |
0be6cf0c | 1143 | * EVP_CTRL_INIT is purely legacy, no provider counterpart. |
d6d74cf4 RL |
1144 | * As a matter of fact, this should be dead code, but some caller |
1145 | * might still do a direct control call with this command, so... | |
1146 | * Legacy methods return 1 except for exceptional circumstances, so | |
1147 | * we do the same here to not be disruptive. | |
1148 | */ | |
1149 | return 1; | |
13273237 | 1150 | case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */ |
459b15d4 | 1151 | default: |
6a36f209 | 1152 | goto end; |
459b15d4 SL |
1153 | case EVP_CTRL_AEAD_SET_IVLEN: |
1154 | if (arg < 0) | |
1155 | return 0; | |
eb52450f TM |
1156 | if (ctx->iv_len == arg) |
1157 | /* Skip calling into provider if unchanged. */ | |
1158 | return 1; | |
1c3ace68 | 1159 | params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz); |
b30b45b7 | 1160 | ctx->iv_len = -1; |
13273237 | 1161 | break; |
f5d0c02c SL |
1162 | case EVP_CTRL_CCM_SET_L: |
1163 | if (arg < 2 || arg > 8) | |
1164 | return 0; | |
1165 | sz = 15 - arg; | |
1166 | params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz); | |
b30b45b7 | 1167 | ctx->iv_len = -1; |
f5d0c02c | 1168 | break; |
11b44359 SL |
1169 | case EVP_CTRL_AEAD_SET_IV_FIXED: |
1170 | params[0] = OSSL_PARAM_construct_octet_string( | |
1171 | OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, ptr, sz); | |
1172 | break; | |
1173 | case EVP_CTRL_GCM_IV_GEN: | |
1174 | set_params = 0; | |
1175 | if (arg < 0) | |
1176 | sz = 0; /* special case that uses the iv length */ | |
1177 | params[0] = OSSL_PARAM_construct_octet_string( | |
1178 | OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, ptr, sz); | |
1179 | break; | |
1180 | case EVP_CTRL_GCM_SET_IV_INV: | |
1181 | if (arg < 0) | |
1182 | return 0; | |
1183 | params[0] = OSSL_PARAM_construct_octet_string( | |
1184 | OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, ptr, sz); | |
459b15d4 | 1185 | break; |
6a41156c SL |
1186 | case EVP_CTRL_GET_RC5_ROUNDS: |
1187 | set_params = 0; /* Fall thru */ | |
1188 | case EVP_CTRL_SET_RC5_ROUNDS: | |
1189 | if (arg < 0) | |
1190 | return 0; | |
1191 | i = (unsigned int)arg; | |
1192 | params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i); | |
1193 | break; | |
eb173822 SL |
1194 | case EVP_CTRL_SET_SPEED: |
1195 | if (arg < 0) | |
1196 | return 0; | |
1197 | i = (unsigned int)arg; | |
1198 | params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_SPEED, &i); | |
1199 | break; | |
459b15d4 | 1200 | case EVP_CTRL_AEAD_GET_TAG: |
1c3ace68 SL |
1201 | set_params = 0; /* Fall thru */ |
1202 | case EVP_CTRL_AEAD_SET_TAG: | |
459b15d4 | 1203 | params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, |
1c3ace68 | 1204 | ptr, sz); |
459b15d4 SL |
1205 | break; |
1206 | case EVP_CTRL_AEAD_TLS1_AAD: | |
0d2bfe52 | 1207 | /* This one does a set and a get - since it returns a size */ |
459b15d4 SL |
1208 | params[0] = |
1209 | OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, | |
1c3ace68 | 1210 | ptr, sz); |
7c14d0c1 | 1211 | ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); |
459b15d4 | 1212 | if (ret <= 0) |
6a36f209 | 1213 | goto end; |
459b15d4 SL |
1214 | params[0] = |
1215 | OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, &sz); | |
7c14d0c1 | 1216 | ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); |
459b15d4 | 1217 | if (ret <= 0) |
6a36f209 | 1218 | goto end; |
459b15d4 | 1219 | return sz; |
f816aa47 SL |
1220 | #ifndef OPENSSL_NO_RC2 |
1221 | case EVP_CTRL_GET_RC2_KEY_BITS: | |
1222 | set_params = 0; /* Fall thru */ | |
1223 | case EVP_CTRL_SET_RC2_KEY_BITS: | |
1224 | params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, &sz); | |
1225 | break; | |
1226 | #endif /* OPENSSL_NO_RC2 */ | |
0d2bfe52 SL |
1227 | #if !defined(OPENSSL_NO_MULTIBLOCK) |
1228 | case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: | |
1229 | params[0] = OSSL_PARAM_construct_size_t( | |
1230 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, &sz); | |
7c14d0c1 | 1231 | ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); |
0d2bfe52 SL |
1232 | if (ret <= 0) |
1233 | return 0; | |
1234 | ||
1235 | params[0] = OSSL_PARAM_construct_size_t( | |
1236 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, &sz); | |
1237 | params[1] = OSSL_PARAM_construct_end(); | |
7c14d0c1 | 1238 | ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); |
0d2bfe52 SL |
1239 | if (ret <= 0) |
1240 | return 0; | |
1241 | return sz; | |
1242 | case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: { | |
1243 | EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p = | |
1244 | (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr; | |
1245 | ||
1246 | if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) | |
1247 | return 0; | |
1248 | ||
1249 | params[0] = OSSL_PARAM_construct_octet_string( | |
1250 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, (void*)p->inp, p->len); | |
1251 | params[1] = OSSL_PARAM_construct_uint( | |
1252 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); | |
7c14d0c1 | 1253 | ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); |
0d2bfe52 SL |
1254 | if (ret <= 0) |
1255 | return ret; | |
1256 | /* Retrieve the return values changed by the set */ | |
1257 | params[0] = OSSL_PARAM_construct_size_t( | |
1258 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, &sz); | |
1259 | params[1] = OSSL_PARAM_construct_uint( | |
1260 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); | |
1261 | params[2] = OSSL_PARAM_construct_end(); | |
7c14d0c1 | 1262 | ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); |
0d2bfe52 SL |
1263 | if (ret <= 0) |
1264 | return 0; | |
1265 | return sz; | |
1266 | } | |
1267 | case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: { | |
1268 | EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p = | |
1269 | (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr; | |
1270 | ||
1271 | params[0] = OSSL_PARAM_construct_octet_string( | |
1272 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, p->out, p->len); | |
1273 | ||
1274 | params[1] = OSSL_PARAM_construct_octet_string( | |
1275 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, (void*)p->inp, | |
1276 | p->len); | |
1277 | params[2] = OSSL_PARAM_construct_uint( | |
1278 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); | |
7c14d0c1 | 1279 | ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); |
0d2bfe52 SL |
1280 | if (ret <= 0) |
1281 | return ret; | |
1282 | params[0] = OSSL_PARAM_construct_size_t( | |
1283 | OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, &sz); | |
1284 | params[1] = OSSL_PARAM_construct_end(); | |
7c14d0c1 | 1285 | ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); |
0d2bfe52 SL |
1286 | if (ret <= 0) |
1287 | return 0; | |
1288 | return sz; | |
1289 | } | |
1290 | #endif /* OPENSSL_NO_MULTIBLOCK */ | |
1291 | case EVP_CTRL_AEAD_SET_MAC_KEY: | |
1292 | if (arg < 0) | |
1293 | return -1; | |
1294 | params[0] = OSSL_PARAM_construct_octet_string( | |
1295 | OSSL_CIPHER_PARAM_AEAD_MAC_KEY, ptr, sz); | |
1296 | break; | |
13273237 | 1297 | } |
459b15d4 SL |
1298 | |
1299 | if (set_params) | |
7c14d0c1 | 1300 | ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); |
459b15d4 | 1301 | else |
7c14d0c1 | 1302 | ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); |
6a36f209 | 1303 | goto end; |
13273237 | 1304 | |
0be6cf0c | 1305 | /* Code below to be removed when legacy support is dropped. */ |
459b15d4 SL |
1306 | legacy: |
1307 | if (ctx->cipher->ctrl == NULL) { | |
9311d0c4 | 1308 | ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED); |
0f113f3e MC |
1309 | return 0; |
1310 | } | |
1311 | ||
1312 | ret = ctx->cipher->ctrl(ctx, type, arg, ptr); | |
552be00d | 1313 | |
6a36f209 | 1314 | end: |
e870791a | 1315 | if (ret == EVP_CTRL_RET_UNSUPPORTED) { |
9311d0c4 | 1316 | ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); |
0f113f3e MC |
1317 | return 0; |
1318 | } | |
1319 | return ret; | |
49528751 | 1320 | } |
216659eb | 1321 | |
ae3ff60e RL |
1322 | int EVP_CIPHER_get_params(EVP_CIPHER *cipher, OSSL_PARAM params[]) |
1323 | { | |
1324 | if (cipher != NULL && cipher->get_params != NULL) | |
1325 | return cipher->get_params(params); | |
1326 | return 0; | |
1327 | } | |
1328 | ||
1329 | int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[]) | |
1330 | { | |
70f39a48 P |
1331 | int r = 0; |
1332 | const OSSL_PARAM *p; | |
1333 | ||
b30b45b7 | 1334 | if (ctx->cipher != NULL && ctx->cipher->set_ctx_params != NULL) { |
70f39a48 P |
1335 | r = ctx->cipher->set_ctx_params(ctx->algctx, params); |
1336 | if (r > 0) { | |
1337 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); | |
b9a2f24e | 1338 | if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->key_len)) { |
70f39a48 | 1339 | r = 0; |
b9a2f24e HL |
1340 | ctx->key_len = -1; |
1341 | } | |
70f39a48 P |
1342 | } |
1343 | if (r > 0) { | |
1344 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN); | |
b9a2f24e | 1345 | if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->iv_len)) { |
70f39a48 | 1346 | r = 0; |
b9a2f24e HL |
1347 | ctx->iv_len = -1; |
1348 | } | |
70f39a48 | 1349 | } |
b30b45b7 | 1350 | } |
70f39a48 | 1351 | return r; |
ae3ff60e RL |
1352 | } |
1353 | ||
1354 | int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]) | |
1355 | { | |
92d9d0ae | 1356 | if (ctx->cipher != NULL && ctx->cipher->get_ctx_params != NULL) |
7c14d0c1 | 1357 | return ctx->cipher->get_ctx_params(ctx->algctx, params); |
ae3ff60e RL |
1358 | return 0; |
1359 | } | |
1360 | ||
1361 | const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher) | |
1362 | { | |
1363 | if (cipher != NULL && cipher->gettable_params != NULL) | |
18ec26ba | 1364 | return cipher->gettable_params( |
ed576acd | 1365 | ossl_provider_ctx(EVP_CIPHER_get0_provider(cipher))); |
ae3ff60e RL |
1366 | return NULL; |
1367 | } | |
1368 | ||
41f7ecf3 | 1369 | const OSSL_PARAM *EVP_CIPHER_settable_ctx_params(const EVP_CIPHER *cipher) |
ae3ff60e | 1370 | { |
7c14d0c1 | 1371 | void *provctx; |
292b4184 P |
1372 | |
1373 | if (cipher != NULL && cipher->settable_ctx_params != NULL) { | |
ed576acd | 1374 | provctx = ossl_provider_ctx(EVP_CIPHER_get0_provider(cipher)); |
7c14d0c1 | 1375 | return cipher->settable_ctx_params(NULL, provctx); |
292b4184 | 1376 | } |
ae3ff60e RL |
1377 | return NULL; |
1378 | } | |
1379 | ||
41f7ecf3 | 1380 | const OSSL_PARAM *EVP_CIPHER_gettable_ctx_params(const EVP_CIPHER *cipher) |
ae3ff60e | 1381 | { |
7c14d0c1 | 1382 | void *provctx; |
292b4184 P |
1383 | |
1384 | if (cipher != NULL && cipher->gettable_ctx_params != NULL) { | |
ed576acd | 1385 | provctx = ossl_provider_ctx(EVP_CIPHER_get0_provider(cipher)); |
7c14d0c1 | 1386 | return cipher->gettable_ctx_params(NULL, provctx); |
292b4184 P |
1387 | } |
1388 | return NULL; | |
1389 | } | |
1390 | ||
1391 | const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(EVP_CIPHER_CTX *cctx) | |
1392 | { | |
1393 | void *alg; | |
1394 | ||
1395 | if (cctx != NULL && cctx->cipher->settable_ctx_params != NULL) { | |
ed576acd | 1396 | alg = ossl_provider_ctx(EVP_CIPHER_get0_provider(cctx->cipher)); |
7c14d0c1 | 1397 | return cctx->cipher->settable_ctx_params(cctx->algctx, alg); |
292b4184 P |
1398 | } |
1399 | return NULL; | |
1400 | } | |
1401 | ||
1402 | const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(EVP_CIPHER_CTX *cctx) | |
1403 | { | |
7c14d0c1 | 1404 | void *provctx; |
292b4184 P |
1405 | |
1406 | if (cctx != NULL && cctx->cipher->gettable_ctx_params != NULL) { | |
ed576acd | 1407 | provctx = ossl_provider_ctx(EVP_CIPHER_get0_provider(cctx->cipher)); |
7c14d0c1 | 1408 | return cctx->cipher->gettable_ctx_params(cctx->algctx, provctx); |
292b4184 | 1409 | } |
ae3ff60e RL |
1410 | return NULL; |
1411 | } | |
1412 | ||
11eef7e7 | 1413 | #ifndef FIPS_MODULE |
b4250010 | 1414 | static OSSL_LIB_CTX *EVP_CIPHER_CTX_get_libctx(EVP_CIPHER_CTX *ctx) |
11eef7e7 SL |
1415 | { |
1416 | const EVP_CIPHER *cipher = ctx->cipher; | |
1417 | const OSSL_PROVIDER *prov; | |
1418 | ||
1419 | if (cipher == NULL) | |
1420 | return NULL; | |
1421 | ||
ed576acd | 1422 | prov = EVP_CIPHER_get0_provider(cipher); |
a829b735 | 1423 | return ossl_provider_libctx(prov); |
11eef7e7 SL |
1424 | } |
1425 | #endif | |
1426 | ||
216659eb | 1427 | int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) |
0f113f3e MC |
1428 | { |
1429 | if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) | |
1430 | return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); | |
4a42e264 | 1431 | |
f844f9eb | 1432 | #ifdef FIPS_MODULE |
4a42e264 SL |
1433 | return 0; |
1434 | #else | |
1435 | { | |
1436 | int kl; | |
b4250010 | 1437 | OSSL_LIB_CTX *libctx = EVP_CIPHER_CTX_get_libctx(ctx); |
4a42e264 | 1438 | |
ed576acd | 1439 | kl = EVP_CIPHER_CTX_get_key_length(ctx); |
5cbd2ea3 | 1440 | if (kl <= 0 || RAND_priv_bytes_ex(libctx, key, kl, 0) <= 0) |
4a42e264 SL |
1441 | return 0; |
1442 | return 1; | |
1443 | } | |
f844f9eb | 1444 | #endif /* FIPS_MODULE */ |
0f113f3e | 1445 | } |
216659eb | 1446 | |
4e62f1a3 P |
1447 | EVP_CIPHER_CTX *EVP_CIPHER_CTX_dup(const EVP_CIPHER_CTX *in) |
1448 | { | |
1449 | EVP_CIPHER_CTX *out = EVP_CIPHER_CTX_new(); | |
1450 | ||
1451 | if (out != NULL && !EVP_CIPHER_CTX_copy(out, in)) { | |
1452 | EVP_CIPHER_CTX_free(out); | |
1453 | out = NULL; | |
1454 | } | |
1455 | return out; | |
1456 | } | |
1457 | ||
c2bf7208 | 1458 | int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) |
0f113f3e MC |
1459 | { |
1460 | if ((in == NULL) || (in->cipher == NULL)) { | |
9311d0c4 | 1461 | ERR_raise(ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED); |
0f113f3e MC |
1462 | return 0; |
1463 | } | |
df05f2ce MC |
1464 | |
1465 | if (in->cipher->prov == NULL) | |
1466 | goto legacy; | |
1467 | ||
1468 | if (in->cipher->dupctx == NULL) { | |
9311d0c4 | 1469 | ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); |
df05f2ce MC |
1470 | return 0; |
1471 | } | |
1472 | ||
1473 | EVP_CIPHER_CTX_reset(out); | |
1474 | ||
1475 | *out = *in; | |
7c14d0c1 | 1476 | out->algctx = NULL; |
df05f2ce | 1477 | |
70c35fd1 | 1478 | if (in->fetched_cipher != NULL && !EVP_CIPHER_up_ref(in->fetched_cipher)) { |
df05f2ce MC |
1479 | out->fetched_cipher = NULL; |
1480 | return 0; | |
1481 | } | |
1482 | ||
7c14d0c1 SL |
1483 | out->algctx = in->cipher->dupctx(in->algctx); |
1484 | if (out->algctx == NULL) { | |
9311d0c4 | 1485 | ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); |
df05f2ce MC |
1486 | return 0; |
1487 | } | |
1488 | ||
1489 | return 1; | |
1490 | ||
0be6cf0c | 1491 | /* Code below to be removed when legacy support is dropped. */ |
df05f2ce MC |
1492 | legacy: |
1493 | ||
f844f9eb | 1494 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) |
0f113f3e MC |
1495 | /* Make sure it's safe to copy a cipher context using an ENGINE */ |
1496 | if (in->engine && !ENGINE_init(in->engine)) { | |
9311d0c4 | 1497 | ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); |
0f113f3e MC |
1498 | return 0; |
1499 | } | |
c2bf7208 DSH |
1500 | #endif |
1501 | ||
c0ca39bd | 1502 | EVP_CIPHER_CTX_reset(out); |
b4faea50 | 1503 | memcpy(out, in, sizeof(*out)); |
0f113f3e MC |
1504 | |
1505 | if (in->cipher_data && in->cipher->ctx_size) { | |
1506 | out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); | |
90945fa3 | 1507 | if (out->cipher_data == NULL) { |
273a0218 | 1508 | out->cipher = NULL; |
0f113f3e MC |
1509 | return 0; |
1510 | } | |
1511 | memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); | |
1512 | } | |
1513 | ||
1514 | if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) | |
273a0218 BE |
1515 | if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) { |
1516 | out->cipher = NULL; | |
9311d0c4 | 1517 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
273a0218 BE |
1518 | return 0; |
1519 | } | |
0f113f3e MC |
1520 | return 1; |
1521 | } | |
df05f2ce | 1522 | |
550f974a RL |
1523 | EVP_CIPHER *evp_cipher_new(void) |
1524 | { | |
1525 | EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); | |
1526 | ||
6be83ac1 P |
1527 | if (cipher != NULL && !CRYPTO_NEW_REF(&cipher->refcnt, 1)) { |
1528 | OPENSSL_free(cipher); | |
1529 | return NULL; | |
550f974a RL |
1530 | } |
1531 | return cipher; | |
1532 | } | |
1533 | ||
32040838 RL |
1534 | /* |
1535 | * FIPS module note: since internal fetches will be entirely | |
1536 | * provider based, we know that none of its code depends on legacy | |
1537 | * NIDs or any functionality that use them. | |
1538 | */ | |
f844f9eb | 1539 | #ifndef FIPS_MODULE |
83abd33c | 1540 | /* After removal of legacy support get rid of the need for legacy NIDs */ |
32040838 RL |
1541 | static void set_legacy_nid(const char *name, void *vlegacy_nid) |
1542 | { | |
1543 | int nid; | |
1544 | int *legacy_nid = vlegacy_nid; | |
6a835fcf RL |
1545 | /* |
1546 | * We use lowest level function to get the associated method, because | |
1547 | * higher level functions such as EVP_get_cipherbyname() have changed | |
1548 | * to look at providers too. | |
1549 | */ | |
1550 | const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); | |
32040838 RL |
1551 | |
1552 | if (*legacy_nid == -1) /* We found a clash already */ | |
1553 | return; | |
6a835fcf | 1554 | if (legacy_method == NULL) |
32040838 | 1555 | return; |
ed576acd | 1556 | nid = EVP_CIPHER_get_nid(legacy_method); |
32040838 RL |
1557 | if (*legacy_nid != NID_undef && *legacy_nid != nid) { |
1558 | *legacy_nid = -1; | |
1559 | return; | |
1560 | } | |
1561 | *legacy_nid = nid; | |
1562 | } | |
1563 | #endif | |
1564 | ||
309a78aa RL |
1565 | static void *evp_cipher_from_algorithm(const int name_id, |
1566 | const OSSL_ALGORITHM *algodef, | |
1567 | OSSL_PROVIDER *prov) | |
df05f2ce | 1568 | { |
309a78aa | 1569 | const OSSL_DISPATCH *fns = algodef->implementation; |
df05f2ce MC |
1570 | EVP_CIPHER *cipher = NULL; |
1571 | int fnciphcnt = 0, fnctxcnt = 0; | |
1572 | ||
f7c16d48 | 1573 | if ((cipher = evp_cipher_new()) == NULL) { |
e077455e | 1574 | ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); |
df05f2ce | 1575 | return NULL; |
6b9e3724 | 1576 | } |
df05f2ce | 1577 | |
f844f9eb | 1578 | #ifndef FIPS_MODULE |
32040838 | 1579 | cipher->nid = NID_undef; |
d84f5515 MC |
1580 | if (!evp_names_do_all(prov, name_id, set_legacy_nid, &cipher->nid) |
1581 | || cipher->nid == -1) { | |
32040838 RL |
1582 | ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); |
1583 | EVP_CIPHER_free(cipher); | |
1584 | return NULL; | |
f7c16d48 | 1585 | } |
ed71e917 MC |
1586 | #endif |
1587 | ||
32040838 | 1588 | cipher->name_id = name_id; |
6c9bc258 TM |
1589 | if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { |
1590 | EVP_CIPHER_free(cipher); | |
1591 | return NULL; | |
1592 | } | |
309a78aa | 1593 | cipher->description = algodef->algorithm_description; |
32040838 | 1594 | |
df05f2ce MC |
1595 | for (; fns->function_id != 0; fns++) { |
1596 | switch (fns->function_id) { | |
1597 | case OSSL_FUNC_CIPHER_NEWCTX: | |
1598 | if (cipher->newctx != NULL) | |
1599 | break; | |
363b1e5d | 1600 | cipher->newctx = OSSL_FUNC_cipher_newctx(fns); |
df05f2ce MC |
1601 | fnctxcnt++; |
1602 | break; | |
1603 | case OSSL_FUNC_CIPHER_ENCRYPT_INIT: | |
1604 | if (cipher->einit != NULL) | |
1605 | break; | |
363b1e5d | 1606 | cipher->einit = OSSL_FUNC_cipher_encrypt_init(fns); |
df05f2ce MC |
1607 | fnciphcnt++; |
1608 | break; | |
1609 | case OSSL_FUNC_CIPHER_DECRYPT_INIT: | |
1610 | if (cipher->dinit != NULL) | |
1611 | break; | |
363b1e5d | 1612 | cipher->dinit = OSSL_FUNC_cipher_decrypt_init(fns); |
df05f2ce MC |
1613 | fnciphcnt++; |
1614 | break; | |
1615 | case OSSL_FUNC_CIPHER_UPDATE: | |
1616 | if (cipher->cupdate != NULL) | |
1617 | break; | |
363b1e5d | 1618 | cipher->cupdate = OSSL_FUNC_cipher_update(fns); |
df05f2ce MC |
1619 | fnciphcnt++; |
1620 | break; | |
1621 | case OSSL_FUNC_CIPHER_FINAL: | |
1622 | if (cipher->cfinal != NULL) | |
1623 | break; | |
363b1e5d | 1624 | cipher->cfinal = OSSL_FUNC_cipher_final(fns); |
df05f2ce MC |
1625 | fnciphcnt++; |
1626 | break; | |
718b133a MC |
1627 | case OSSL_FUNC_CIPHER_CIPHER: |
1628 | if (cipher->ccipher != NULL) | |
1629 | break; | |
363b1e5d | 1630 | cipher->ccipher = OSSL_FUNC_cipher_cipher(fns); |
718b133a | 1631 | break; |
df05f2ce MC |
1632 | case OSSL_FUNC_CIPHER_FREECTX: |
1633 | if (cipher->freectx != NULL) | |
1634 | break; | |
363b1e5d | 1635 | cipher->freectx = OSSL_FUNC_cipher_freectx(fns); |
df05f2ce MC |
1636 | fnctxcnt++; |
1637 | break; | |
1638 | case OSSL_FUNC_CIPHER_DUPCTX: | |
1639 | if (cipher->dupctx != NULL) | |
1640 | break; | |
363b1e5d | 1641 | cipher->dupctx = OSSL_FUNC_cipher_dupctx(fns); |
df05f2ce | 1642 | break; |
df05f2ce MC |
1643 | case OSSL_FUNC_CIPHER_GET_PARAMS: |
1644 | if (cipher->get_params != NULL) | |
1645 | break; | |
363b1e5d | 1646 | cipher->get_params = OSSL_FUNC_cipher_get_params(fns); |
df05f2ce | 1647 | break; |
92d9d0ae RL |
1648 | case OSSL_FUNC_CIPHER_GET_CTX_PARAMS: |
1649 | if (cipher->get_ctx_params != NULL) | |
718b133a | 1650 | break; |
363b1e5d | 1651 | cipher->get_ctx_params = OSSL_FUNC_cipher_get_ctx_params(fns); |
718b133a | 1652 | break; |
92d9d0ae RL |
1653 | case OSSL_FUNC_CIPHER_SET_CTX_PARAMS: |
1654 | if (cipher->set_ctx_params != NULL) | |
df05f2ce | 1655 | break; |
363b1e5d | 1656 | cipher->set_ctx_params = OSSL_FUNC_cipher_set_ctx_params(fns); |
df05f2ce | 1657 | break; |
ae3ff60e RL |
1658 | case OSSL_FUNC_CIPHER_GETTABLE_PARAMS: |
1659 | if (cipher->gettable_params != NULL) | |
1660 | break; | |
363b1e5d | 1661 | cipher->gettable_params = OSSL_FUNC_cipher_gettable_params(fns); |
ae3ff60e RL |
1662 | break; |
1663 | case OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS: | |
1664 | if (cipher->gettable_ctx_params != NULL) | |
1665 | break; | |
1666 | cipher->gettable_ctx_params = | |
363b1e5d | 1667 | OSSL_FUNC_cipher_gettable_ctx_params(fns); |
ae3ff60e RL |
1668 | break; |
1669 | case OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS: | |
1670 | if (cipher->settable_ctx_params != NULL) | |
1671 | break; | |
1672 | cipher->settable_ctx_params = | |
363b1e5d | 1673 | OSSL_FUNC_cipher_settable_ctx_params(fns); |
ae3ff60e | 1674 | break; |
df05f2ce MC |
1675 | } |
1676 | } | |
718b133a MC |
1677 | if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4) |
1678 | || (fnciphcnt == 0 && cipher->ccipher == NULL) | |
13273237 | 1679 | || fnctxcnt != 2) { |
df05f2ce MC |
1680 | /* |
1681 | * In order to be a consistent set of functions we must have at least | |
1682 | * a complete set of "encrypt" functions, or a complete set of "decrypt" | |
11dbdc07 MC |
1683 | * functions, or a single "cipher" function. In all cases we need both |
1684 | * the "newctx" and "freectx" functions. | |
df05f2ce | 1685 | */ |
550f974a | 1686 | EVP_CIPHER_free(cipher); |
9311d0c4 | 1687 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); |
df05f2ce MC |
1688 | return NULL; |
1689 | } | |
1690 | cipher->prov = prov; | |
1691 | if (prov != NULL) | |
7c95390e | 1692 | ossl_provider_up_ref(prov); |
df05f2ce | 1693 | |
ae69da05 MC |
1694 | if (!evp_cipher_cache_constants(cipher)) { |
1695 | EVP_CIPHER_free(cipher); | |
1696 | ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED); | |
1697 | cipher = NULL; | |
1698 | } | |
1699 | ||
df05f2ce MC |
1700 | return cipher; |
1701 | } | |
1702 | ||
70c35fd1 | 1703 | static int evp_cipher_up_ref(void *cipher) |
df05f2ce | 1704 | { |
70c35fd1 | 1705 | return EVP_CIPHER_up_ref(cipher); |
df05f2ce MC |
1706 | } |
1707 | ||
1708 | static void evp_cipher_free(void *cipher) | |
1709 | { | |
550f974a | 1710 | EVP_CIPHER_free(cipher); |
df05f2ce MC |
1711 | } |
1712 | ||
b4250010 | 1713 | EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, |
df05f2ce MC |
1714 | const char *properties) |
1715 | { | |
0211740f RL |
1716 | EVP_CIPHER *cipher = |
1717 | evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties, | |
309a78aa | 1718 | evp_cipher_from_algorithm, evp_cipher_up_ref, |
0211740f RL |
1719 | evp_cipher_free); |
1720 | ||
0211740f | 1721 | return cipher; |
df05f2ce | 1722 | } |
c540f00f | 1723 | |
550f974a RL |
1724 | int EVP_CIPHER_up_ref(EVP_CIPHER *cipher) |
1725 | { | |
1726 | int ref = 0; | |
1727 | ||
f6c95e46 | 1728 | if (cipher->origin == EVP_ORIG_DYNAMIC) |
6be83ac1 | 1729 | CRYPTO_UP_REF(&cipher->refcnt, &ref); |
550f974a RL |
1730 | return 1; |
1731 | } | |
1732 | ||
f6c95e46 RS |
1733 | void evp_cipher_free_int(EVP_CIPHER *cipher) |
1734 | { | |
6c9bc258 | 1735 | OPENSSL_free(cipher->type_name); |
f6c95e46 | 1736 | ossl_provider_free(cipher->prov); |
6be83ac1 | 1737 | CRYPTO_FREE_REF(&cipher->refcnt); |
f6c95e46 RS |
1738 | OPENSSL_free(cipher); |
1739 | } | |
1740 | ||
550f974a RL |
1741 | void EVP_CIPHER_free(EVP_CIPHER *cipher) |
1742 | { | |
1743 | int i; | |
1744 | ||
f6c95e46 | 1745 | if (cipher == NULL || cipher->origin != EVP_ORIG_DYNAMIC) |
550f974a RL |
1746 | return; |
1747 | ||
6be83ac1 | 1748 | CRYPTO_DOWN_REF(&cipher->refcnt, &i); |
550f974a RL |
1749 | if (i > 0) |
1750 | return; | |
f6c95e46 | 1751 | evp_cipher_free_int(cipher); |
550f974a RL |
1752 | } |
1753 | ||
b4250010 | 1754 | void EVP_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, |
251e610c RL |
1755 | void (*fn)(EVP_CIPHER *mac, void *arg), |
1756 | void *arg) | |
c540f00f RL |
1757 | { |
1758 | evp_generic_do_all(libctx, OSSL_OP_CIPHER, | |
1759 | (void (*)(void *, void *))fn, arg, | |
cd770738 RL |
1760 | evp_cipher_from_algorithm, evp_cipher_up_ref, |
1761 | evp_cipher_free); | |
c540f00f | 1762 | } |