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