1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2019-2021 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/*
11e1051a39Sopenharmony_ci * Generic dispatch table functions for ciphers.
12e1051a39Sopenharmony_ci */
13e1051a39Sopenharmony_ci
14e1051a39Sopenharmony_ci/* For SSL3_VERSION */
15e1051a39Sopenharmony_ci#include <openssl/prov_ssl.h>
16e1051a39Sopenharmony_ci#include <openssl/proverr.h>
17e1051a39Sopenharmony_ci#include "ciphercommon_local.h"
18e1051a39Sopenharmony_ci#include "prov/provider_ctx.h"
19e1051a39Sopenharmony_ci#include "prov/providercommon.h"
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ci/*-
22e1051a39Sopenharmony_ci * Generic cipher functions for OSSL_PARAM gettables and settables
23e1051a39Sopenharmony_ci */
24e1051a39Sopenharmony_cistatic const OSSL_PARAM cipher_known_gettable_params[] = {
25e1051a39Sopenharmony_ci    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL),
26e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
27e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
28e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
29e1051a39Sopenharmony_ci    OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL),
30e1051a39Sopenharmony_ci    OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL),
31e1051a39Sopenharmony_ci    OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL),
32e1051a39Sopenharmony_ci    OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL),
33e1051a39Sopenharmony_ci    OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL),
34e1051a39Sopenharmony_ci    OSSL_PARAM_END
35e1051a39Sopenharmony_ci};
36e1051a39Sopenharmony_ciconst OSSL_PARAM *ossl_cipher_generic_gettable_params(ossl_unused void *provctx)
37e1051a39Sopenharmony_ci{
38e1051a39Sopenharmony_ci    return cipher_known_gettable_params;
39e1051a39Sopenharmony_ci}
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_ciint ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
42e1051a39Sopenharmony_ci                                   uint64_t flags,
43e1051a39Sopenharmony_ci                                   size_t kbits, size_t blkbits, size_t ivbits)
44e1051a39Sopenharmony_ci{
45e1051a39Sopenharmony_ci    OSSL_PARAM *p;
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
48e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_uint(p, md)) {
49e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
50e1051a39Sopenharmony_ci        return 0;
51e1051a39Sopenharmony_ci    }
52e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD);
53e1051a39Sopenharmony_ci    if (p != NULL
54e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) {
55e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
56e1051a39Sopenharmony_ci        return 0;
57e1051a39Sopenharmony_ci    }
58e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV);
59e1051a39Sopenharmony_ci    if (p != NULL
60e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) {
61e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
62e1051a39Sopenharmony_ci        return 0;
63e1051a39Sopenharmony_ci    }
64e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS);
65e1051a39Sopenharmony_ci    if (p != NULL
66e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) {
67e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
68e1051a39Sopenharmony_ci        return 0;
69e1051a39Sopenharmony_ci    }
70e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK);
71e1051a39Sopenharmony_ci    if (p != NULL
72e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) {
73e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
74e1051a39Sopenharmony_ci        return 0;
75e1051a39Sopenharmony_ci    }
76e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY);
77e1051a39Sopenharmony_ci    if (p != NULL
78e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) {
79e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
80e1051a39Sopenharmony_ci        return 0;
81e1051a39Sopenharmony_ci    }
82e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
83e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) {
84e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
85e1051a39Sopenharmony_ci        return 0;
86e1051a39Sopenharmony_ci    }
87e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
88e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) {
89e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
90e1051a39Sopenharmony_ci        return 0;
91e1051a39Sopenharmony_ci    }
92e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
93e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) {
94e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
95e1051a39Sopenharmony_ci        return 0;
96e1051a39Sopenharmony_ci    }
97e1051a39Sopenharmony_ci    return 1;
98e1051a39Sopenharmony_ci}
99e1051a39Sopenharmony_ci
100e1051a39Sopenharmony_ciCIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic)
101e1051a39Sopenharmony_ci{ OSSL_CIPHER_PARAM_TLS_MAC, OSSL_PARAM_OCTET_PTR, NULL, 0, OSSL_PARAM_UNMODIFIED },
102e1051a39Sopenharmony_ciCIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_cipher_generic)
103e1051a39Sopenharmony_ci
104e1051a39Sopenharmony_ciCIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_generic)
105e1051a39Sopenharmony_ciOSSL_PARAM_uint(OSSL_CIPHER_PARAM_USE_BITS, NULL),
106e1051a39Sopenharmony_ciOSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL),
107e1051a39Sopenharmony_ciOSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL),
108e1051a39Sopenharmony_ciCIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_generic)
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_ci/*
111e1051a39Sopenharmony_ci * Variable key length cipher functions for OSSL_PARAM settables
112e1051a39Sopenharmony_ci */
113e1051a39Sopenharmony_ciint ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[])
114e1051a39Sopenharmony_ci{
115e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
116e1051a39Sopenharmony_ci    const OSSL_PARAM *p;
117e1051a39Sopenharmony_ci
118e1051a39Sopenharmony_ci    if (params == NULL)
119e1051a39Sopenharmony_ci        return 1;
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    if (!ossl_cipher_generic_set_ctx_params(vctx, params))
122e1051a39Sopenharmony_ci        return 0;
123e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
124e1051a39Sopenharmony_ci    if (p != NULL) {
125e1051a39Sopenharmony_ci        size_t keylen;
126e1051a39Sopenharmony_ci
127e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_size_t(p, &keylen)) {
128e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
129e1051a39Sopenharmony_ci            return 0;
130e1051a39Sopenharmony_ci        }
131e1051a39Sopenharmony_ci        ctx->keylen = keylen;
132e1051a39Sopenharmony_ci    }
133e1051a39Sopenharmony_ci    return 1;
134e1051a39Sopenharmony_ci}
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ciCIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_var_keylen)
137e1051a39Sopenharmony_ciOSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
138e1051a39Sopenharmony_ciCIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_var_keylen)
139e1051a39Sopenharmony_ci
140e1051a39Sopenharmony_ci/*-
141e1051a39Sopenharmony_ci * AEAD cipher functions for OSSL_PARAM gettables and settables
142e1051a39Sopenharmony_ci */
143e1051a39Sopenharmony_cistatic const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
144e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
145e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
146e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
147e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
148e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
149e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
150e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
151e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
152e1051a39Sopenharmony_ci    OSSL_PARAM_END
153e1051a39Sopenharmony_ci};
154e1051a39Sopenharmony_ciconst OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params(
155e1051a39Sopenharmony_ci        ossl_unused void *cctx, ossl_unused void *provctx
156e1051a39Sopenharmony_ci    )
157e1051a39Sopenharmony_ci{
158e1051a39Sopenharmony_ci    return cipher_aead_known_gettable_ctx_params;
159e1051a39Sopenharmony_ci}
160e1051a39Sopenharmony_ci
161e1051a39Sopenharmony_cistatic const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
162e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
163e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
164e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
165e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
166e1051a39Sopenharmony_ci    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0),
167e1051a39Sopenharmony_ci    OSSL_PARAM_END
168e1051a39Sopenharmony_ci};
169e1051a39Sopenharmony_ciconst OSSL_PARAM *ossl_cipher_aead_settable_ctx_params(
170e1051a39Sopenharmony_ci        ossl_unused void *cctx, ossl_unused void *provctx
171e1051a39Sopenharmony_ci    )
172e1051a39Sopenharmony_ci{
173e1051a39Sopenharmony_ci    return cipher_aead_known_settable_ctx_params;
174e1051a39Sopenharmony_ci}
175e1051a39Sopenharmony_ci
176e1051a39Sopenharmony_civoid ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx)
177e1051a39Sopenharmony_ci{
178e1051a39Sopenharmony_ci    if (ctx != NULL && ctx->alloced) {
179e1051a39Sopenharmony_ci        OPENSSL_free(ctx->tlsmac);
180e1051a39Sopenharmony_ci        ctx->alloced = 0;
181e1051a39Sopenharmony_ci        ctx->tlsmac = NULL;
182e1051a39Sopenharmony_ci    }
183e1051a39Sopenharmony_ci}
184e1051a39Sopenharmony_ci
185e1051a39Sopenharmony_cistatic int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
186e1051a39Sopenharmony_ci                                        const unsigned char *key, size_t keylen,
187e1051a39Sopenharmony_ci                                        const unsigned char *iv, size_t ivlen,
188e1051a39Sopenharmony_ci                                        const OSSL_PARAM params[], int enc)
189e1051a39Sopenharmony_ci{
190e1051a39Sopenharmony_ci    ctx->num = 0;
191e1051a39Sopenharmony_ci    ctx->bufsz = 0;
192e1051a39Sopenharmony_ci    ctx->updated = 0;
193e1051a39Sopenharmony_ci    ctx->enc = enc ? 1 : 0;
194e1051a39Sopenharmony_ci
195e1051a39Sopenharmony_ci    if (!ossl_prov_is_running())
196e1051a39Sopenharmony_ci        return 0;
197e1051a39Sopenharmony_ci
198e1051a39Sopenharmony_ci    if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
199e1051a39Sopenharmony_ci        if (!ossl_cipher_generic_initiv(ctx, iv, ivlen))
200e1051a39Sopenharmony_ci            return 0;
201e1051a39Sopenharmony_ci    }
202e1051a39Sopenharmony_ci    if (iv == NULL && ctx->iv_set
203e1051a39Sopenharmony_ci        && (ctx->mode == EVP_CIPH_CBC_MODE
204e1051a39Sopenharmony_ci            || ctx->mode == EVP_CIPH_CFB_MODE
205e1051a39Sopenharmony_ci            || ctx->mode == EVP_CIPH_OFB_MODE))
206e1051a39Sopenharmony_ci        /* reset IV for these modes to keep compatibility with 1.1.1 */
207e1051a39Sopenharmony_ci        memcpy(ctx->iv, ctx->oiv, ctx->ivlen);
208e1051a39Sopenharmony_ci
209e1051a39Sopenharmony_ci    if (key != NULL) {
210e1051a39Sopenharmony_ci        if (ctx->variable_keylength == 0) {
211e1051a39Sopenharmony_ci            if (keylen != ctx->keylen) {
212e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
213e1051a39Sopenharmony_ci                return 0;
214e1051a39Sopenharmony_ci            }
215e1051a39Sopenharmony_ci        } else {
216e1051a39Sopenharmony_ci            ctx->keylen = keylen;
217e1051a39Sopenharmony_ci        }
218e1051a39Sopenharmony_ci        if (!ctx->hw->init(ctx, key, ctx->keylen))
219e1051a39Sopenharmony_ci            return 0;
220e1051a39Sopenharmony_ci    }
221e1051a39Sopenharmony_ci    return ossl_cipher_generic_set_ctx_params(ctx, params);
222e1051a39Sopenharmony_ci}
223e1051a39Sopenharmony_ci
224e1051a39Sopenharmony_ciint ossl_cipher_generic_einit(void *vctx, const unsigned char *key,
225e1051a39Sopenharmony_ci                              size_t keylen, const unsigned char *iv,
226e1051a39Sopenharmony_ci                              size_t ivlen, const OSSL_PARAM params[])
227e1051a39Sopenharmony_ci{
228e1051a39Sopenharmony_ci    return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
229e1051a39Sopenharmony_ci                                        iv, ivlen, params, 1);
230e1051a39Sopenharmony_ci}
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ciint ossl_cipher_generic_dinit(void *vctx, const unsigned char *key,
233e1051a39Sopenharmony_ci                              size_t keylen, const unsigned char *iv,
234e1051a39Sopenharmony_ci                              size_t ivlen, const OSSL_PARAM params[])
235e1051a39Sopenharmony_ci{
236e1051a39Sopenharmony_ci    return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
237e1051a39Sopenharmony_ci                                        iv, ivlen, params, 0);
238e1051a39Sopenharmony_ci}
239e1051a39Sopenharmony_ci
240e1051a39Sopenharmony_ci/* Max padding including padding length byte */
241e1051a39Sopenharmony_ci#define MAX_PADDING 256
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ciint ossl_cipher_generic_block_update(void *vctx, unsigned char *out,
244e1051a39Sopenharmony_ci                                     size_t *outl, size_t outsize,
245e1051a39Sopenharmony_ci                                     const unsigned char *in, size_t inl)
246e1051a39Sopenharmony_ci{
247e1051a39Sopenharmony_ci    size_t outlint = 0;
248e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
249e1051a39Sopenharmony_ci    size_t blksz = ctx->blocksize;
250e1051a39Sopenharmony_ci    size_t nextblocks;
251e1051a39Sopenharmony_ci
252e1051a39Sopenharmony_ci    if (ctx->tlsversion > 0) {
253e1051a39Sopenharmony_ci        /*
254e1051a39Sopenharmony_ci         * Each update call corresponds to a TLS record and is individually
255e1051a39Sopenharmony_ci         * padded
256e1051a39Sopenharmony_ci         */
257e1051a39Sopenharmony_ci
258e1051a39Sopenharmony_ci        /* Sanity check inputs */
259e1051a39Sopenharmony_ci        if (in == NULL
260e1051a39Sopenharmony_ci                || in != out
261e1051a39Sopenharmony_ci                || outsize < inl
262e1051a39Sopenharmony_ci                || !ctx->pad) {
263e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
264e1051a39Sopenharmony_ci            return 0;
265e1051a39Sopenharmony_ci        }
266e1051a39Sopenharmony_ci
267e1051a39Sopenharmony_ci        if (ctx->enc) {
268e1051a39Sopenharmony_ci            unsigned char padval;
269e1051a39Sopenharmony_ci            size_t padnum, loop;
270e1051a39Sopenharmony_ci
271e1051a39Sopenharmony_ci            /* Add padding */
272e1051a39Sopenharmony_ci
273e1051a39Sopenharmony_ci            padnum = blksz - (inl % blksz);
274e1051a39Sopenharmony_ci
275e1051a39Sopenharmony_ci            if (outsize < inl + padnum) {
276e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
277e1051a39Sopenharmony_ci                return 0;
278e1051a39Sopenharmony_ci            }
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_ci            if (padnum > MAX_PADDING) {
281e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
282e1051a39Sopenharmony_ci                return 0;
283e1051a39Sopenharmony_ci            }
284e1051a39Sopenharmony_ci            padval = (unsigned char)(padnum - 1);
285e1051a39Sopenharmony_ci            if (ctx->tlsversion == SSL3_VERSION) {
286e1051a39Sopenharmony_ci                if (padnum > 1)
287e1051a39Sopenharmony_ci                    memset(out + inl, 0, padnum - 1);
288e1051a39Sopenharmony_ci                *(out + inl + padnum - 1) = padval;
289e1051a39Sopenharmony_ci            } else {
290e1051a39Sopenharmony_ci                /* we need to add 'padnum' padding bytes of value padval */
291e1051a39Sopenharmony_ci                for (loop = inl; loop < inl + padnum; loop++)
292e1051a39Sopenharmony_ci                    out[loop] = padval;
293e1051a39Sopenharmony_ci            }
294e1051a39Sopenharmony_ci            inl += padnum;
295e1051a39Sopenharmony_ci        }
296e1051a39Sopenharmony_ci
297e1051a39Sopenharmony_ci        if ((inl % blksz) != 0) {
298e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
299e1051a39Sopenharmony_ci            return 0;
300e1051a39Sopenharmony_ci        }
301e1051a39Sopenharmony_ci
302e1051a39Sopenharmony_ci
303e1051a39Sopenharmony_ci        /* Shouldn't normally fail */
304e1051a39Sopenharmony_ci        if (!ctx->hw->cipher(ctx, out, in, inl)) {
305e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
306e1051a39Sopenharmony_ci            return 0;
307e1051a39Sopenharmony_ci        }
308e1051a39Sopenharmony_ci
309e1051a39Sopenharmony_ci        if (ctx->alloced) {
310e1051a39Sopenharmony_ci            OPENSSL_free(ctx->tlsmac);
311e1051a39Sopenharmony_ci            ctx->alloced = 0;
312e1051a39Sopenharmony_ci            ctx->tlsmac = NULL;
313e1051a39Sopenharmony_ci        }
314e1051a39Sopenharmony_ci
315e1051a39Sopenharmony_ci        /* This only fails if padding is publicly invalid */
316e1051a39Sopenharmony_ci        *outl = inl;
317e1051a39Sopenharmony_ci        if (!ctx->enc
318e1051a39Sopenharmony_ci            && !ossl_cipher_tlsunpadblock(ctx->libctx, ctx->tlsversion,
319e1051a39Sopenharmony_ci                                          out, outl,
320e1051a39Sopenharmony_ci                                          blksz, &ctx->tlsmac, &ctx->alloced,
321e1051a39Sopenharmony_ci                                          ctx->tlsmacsize, 0)) {
322e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
323e1051a39Sopenharmony_ci            return 0;
324e1051a39Sopenharmony_ci        }
325e1051a39Sopenharmony_ci        return 1;
326e1051a39Sopenharmony_ci    }
327e1051a39Sopenharmony_ci
328e1051a39Sopenharmony_ci    if (ctx->bufsz != 0)
329e1051a39Sopenharmony_ci        nextblocks = ossl_cipher_fillblock(ctx->buf, &ctx->bufsz, blksz,
330e1051a39Sopenharmony_ci                                           &in, &inl);
331e1051a39Sopenharmony_ci    else
332e1051a39Sopenharmony_ci        nextblocks = inl & ~(blksz-1);
333e1051a39Sopenharmony_ci
334e1051a39Sopenharmony_ci    /*
335e1051a39Sopenharmony_ci     * If we're decrypting and we end an update on a block boundary we hold
336e1051a39Sopenharmony_ci     * the last block back in case this is the last update call and the last
337e1051a39Sopenharmony_ci     * block is padded.
338e1051a39Sopenharmony_ci     */
339e1051a39Sopenharmony_ci    if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
340e1051a39Sopenharmony_ci        if (outsize < blksz) {
341e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
342e1051a39Sopenharmony_ci            return 0;
343e1051a39Sopenharmony_ci        }
344e1051a39Sopenharmony_ci        if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
345e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
346e1051a39Sopenharmony_ci            return 0;
347e1051a39Sopenharmony_ci        }
348e1051a39Sopenharmony_ci        ctx->bufsz = 0;
349e1051a39Sopenharmony_ci        outlint = blksz;
350e1051a39Sopenharmony_ci        out += blksz;
351e1051a39Sopenharmony_ci    }
352e1051a39Sopenharmony_ci    if (nextblocks > 0) {
353e1051a39Sopenharmony_ci        if (!ctx->enc && ctx->pad && nextblocks == inl) {
354e1051a39Sopenharmony_ci            if (!ossl_assert(inl >= blksz)) {
355e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
356e1051a39Sopenharmony_ci                return 0;
357e1051a39Sopenharmony_ci            }
358e1051a39Sopenharmony_ci            nextblocks -= blksz;
359e1051a39Sopenharmony_ci        }
360e1051a39Sopenharmony_ci        outlint += nextblocks;
361e1051a39Sopenharmony_ci        if (outsize < outlint) {
362e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
363e1051a39Sopenharmony_ci            return 0;
364e1051a39Sopenharmony_ci        }
365e1051a39Sopenharmony_ci    }
366e1051a39Sopenharmony_ci    if (nextblocks > 0) {
367e1051a39Sopenharmony_ci        if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
368e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
369e1051a39Sopenharmony_ci            return 0;
370e1051a39Sopenharmony_ci        }
371e1051a39Sopenharmony_ci        in += nextblocks;
372e1051a39Sopenharmony_ci        inl -= nextblocks;
373e1051a39Sopenharmony_ci    }
374e1051a39Sopenharmony_ci    if (inl != 0
375e1051a39Sopenharmony_ci        && !ossl_cipher_trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
376e1051a39Sopenharmony_ci        /* ERR_raise already called */
377e1051a39Sopenharmony_ci        return 0;
378e1051a39Sopenharmony_ci    }
379e1051a39Sopenharmony_ci
380e1051a39Sopenharmony_ci    *outl = outlint;
381e1051a39Sopenharmony_ci    return inl == 0;
382e1051a39Sopenharmony_ci}
383e1051a39Sopenharmony_ci
384e1051a39Sopenharmony_ciint ossl_cipher_generic_block_final(void *vctx, unsigned char *out,
385e1051a39Sopenharmony_ci                                    size_t *outl, size_t outsize)
386e1051a39Sopenharmony_ci{
387e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
388e1051a39Sopenharmony_ci    size_t blksz = ctx->blocksize;
389e1051a39Sopenharmony_ci
390e1051a39Sopenharmony_ci    if (!ossl_prov_is_running())
391e1051a39Sopenharmony_ci        return 0;
392e1051a39Sopenharmony_ci
393e1051a39Sopenharmony_ci    if (ctx->tlsversion > 0) {
394e1051a39Sopenharmony_ci        /* We never finalize TLS, so this is an error */
395e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
396e1051a39Sopenharmony_ci        return 0;
397e1051a39Sopenharmony_ci    }
398e1051a39Sopenharmony_ci
399e1051a39Sopenharmony_ci    if (ctx->enc) {
400e1051a39Sopenharmony_ci        if (ctx->pad) {
401e1051a39Sopenharmony_ci            ossl_cipher_padblock(ctx->buf, &ctx->bufsz, blksz);
402e1051a39Sopenharmony_ci        } else if (ctx->bufsz == 0) {
403e1051a39Sopenharmony_ci            *outl = 0;
404e1051a39Sopenharmony_ci            return 1;
405e1051a39Sopenharmony_ci        } else if (ctx->bufsz != blksz) {
406e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
407e1051a39Sopenharmony_ci            return 0;
408e1051a39Sopenharmony_ci        }
409e1051a39Sopenharmony_ci
410e1051a39Sopenharmony_ci        if (outsize < blksz) {
411e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
412e1051a39Sopenharmony_ci            return 0;
413e1051a39Sopenharmony_ci        }
414e1051a39Sopenharmony_ci        if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
415e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
416e1051a39Sopenharmony_ci            return 0;
417e1051a39Sopenharmony_ci        }
418e1051a39Sopenharmony_ci        ctx->bufsz = 0;
419e1051a39Sopenharmony_ci        *outl = blksz;
420e1051a39Sopenharmony_ci        return 1;
421e1051a39Sopenharmony_ci    }
422e1051a39Sopenharmony_ci
423e1051a39Sopenharmony_ci    /* Decrypting */
424e1051a39Sopenharmony_ci    if (ctx->bufsz != blksz) {
425e1051a39Sopenharmony_ci        if (ctx->bufsz == 0 && !ctx->pad) {
426e1051a39Sopenharmony_ci            *outl = 0;
427e1051a39Sopenharmony_ci            return 1;
428e1051a39Sopenharmony_ci        }
429e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
430e1051a39Sopenharmony_ci        return 0;
431e1051a39Sopenharmony_ci    }
432e1051a39Sopenharmony_ci
433e1051a39Sopenharmony_ci    if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
434e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
435e1051a39Sopenharmony_ci        return 0;
436e1051a39Sopenharmony_ci    }
437e1051a39Sopenharmony_ci
438e1051a39Sopenharmony_ci    if (ctx->pad && !ossl_cipher_unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
439e1051a39Sopenharmony_ci        /* ERR_raise already called */
440e1051a39Sopenharmony_ci        return 0;
441e1051a39Sopenharmony_ci    }
442e1051a39Sopenharmony_ci
443e1051a39Sopenharmony_ci    if (outsize < ctx->bufsz) {
444e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
445e1051a39Sopenharmony_ci        return 0;
446e1051a39Sopenharmony_ci    }
447e1051a39Sopenharmony_ci    memcpy(out, ctx->buf, ctx->bufsz);
448e1051a39Sopenharmony_ci    *outl = ctx->bufsz;
449e1051a39Sopenharmony_ci    ctx->bufsz = 0;
450e1051a39Sopenharmony_ci    return 1;
451e1051a39Sopenharmony_ci}
452e1051a39Sopenharmony_ci
453e1051a39Sopenharmony_ciint ossl_cipher_generic_stream_update(void *vctx, unsigned char *out,
454e1051a39Sopenharmony_ci                                      size_t *outl, size_t outsize,
455e1051a39Sopenharmony_ci                                      const unsigned char *in, size_t inl)
456e1051a39Sopenharmony_ci{
457e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
458e1051a39Sopenharmony_ci
459e1051a39Sopenharmony_ci    if (inl == 0) {
460e1051a39Sopenharmony_ci        *outl = 0;
461e1051a39Sopenharmony_ci        return 1;
462e1051a39Sopenharmony_ci    }
463e1051a39Sopenharmony_ci
464e1051a39Sopenharmony_ci    if (outsize < inl) {
465e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
466e1051a39Sopenharmony_ci        return 0;
467e1051a39Sopenharmony_ci    }
468e1051a39Sopenharmony_ci
469e1051a39Sopenharmony_ci    if (!ctx->hw->cipher(ctx, out, in, inl)) {
470e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
471e1051a39Sopenharmony_ci        return 0;
472e1051a39Sopenharmony_ci    }
473e1051a39Sopenharmony_ci
474e1051a39Sopenharmony_ci    *outl = inl;
475e1051a39Sopenharmony_ci    if (!ctx->enc && ctx->tlsversion > 0) {
476e1051a39Sopenharmony_ci        /*
477e1051a39Sopenharmony_ci        * Remove any TLS padding. Only used by cipher_aes_cbc_hmac_sha1_hw.c and
478e1051a39Sopenharmony_ci        * cipher_aes_cbc_hmac_sha256_hw.c
479e1051a39Sopenharmony_ci        */
480e1051a39Sopenharmony_ci        if (ctx->removetlspad) {
481e1051a39Sopenharmony_ci            /*
482e1051a39Sopenharmony_ci             * We should have already failed in the cipher() call above if this
483e1051a39Sopenharmony_ci             * isn't true.
484e1051a39Sopenharmony_ci             */
485e1051a39Sopenharmony_ci            if (!ossl_assert(*outl >= (size_t)(out[inl - 1] + 1)))
486e1051a39Sopenharmony_ci                return 0;
487e1051a39Sopenharmony_ci            /* The actual padding length */
488e1051a39Sopenharmony_ci            *outl -= out[inl - 1] + 1;
489e1051a39Sopenharmony_ci        }
490e1051a39Sopenharmony_ci
491e1051a39Sopenharmony_ci        /* TLS MAC and explicit IV if relevant. We should have already failed
492e1051a39Sopenharmony_ci         * in the cipher() call above if *outl is too short.
493e1051a39Sopenharmony_ci         */
494e1051a39Sopenharmony_ci        if (!ossl_assert(*outl >= ctx->removetlsfixed))
495e1051a39Sopenharmony_ci            return 0;
496e1051a39Sopenharmony_ci        *outl -= ctx->removetlsfixed;
497e1051a39Sopenharmony_ci
498e1051a39Sopenharmony_ci        /* Extract the MAC if there is one */
499e1051a39Sopenharmony_ci        if (ctx->tlsmacsize > 0) {
500e1051a39Sopenharmony_ci            if (*outl < ctx->tlsmacsize)
501e1051a39Sopenharmony_ci                return 0;
502e1051a39Sopenharmony_ci
503e1051a39Sopenharmony_ci            ctx->tlsmac = out + *outl - ctx->tlsmacsize;
504e1051a39Sopenharmony_ci            *outl -= ctx->tlsmacsize;
505e1051a39Sopenharmony_ci        }
506e1051a39Sopenharmony_ci    }
507e1051a39Sopenharmony_ci
508e1051a39Sopenharmony_ci    return 1;
509e1051a39Sopenharmony_ci}
510e1051a39Sopenharmony_ciint ossl_cipher_generic_stream_final(void *vctx, unsigned char *out,
511e1051a39Sopenharmony_ci                                     size_t *outl, size_t outsize)
512e1051a39Sopenharmony_ci{
513e1051a39Sopenharmony_ci    if (!ossl_prov_is_running())
514e1051a39Sopenharmony_ci        return 0;
515e1051a39Sopenharmony_ci
516e1051a39Sopenharmony_ci    *outl = 0;
517e1051a39Sopenharmony_ci    return 1;
518e1051a39Sopenharmony_ci}
519e1051a39Sopenharmony_ci
520e1051a39Sopenharmony_ciint ossl_cipher_generic_cipher(void *vctx, unsigned char *out, size_t *outl,
521e1051a39Sopenharmony_ci                               size_t outsize, const unsigned char *in,
522e1051a39Sopenharmony_ci                               size_t inl)
523e1051a39Sopenharmony_ci{
524e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
525e1051a39Sopenharmony_ci
526e1051a39Sopenharmony_ci    if (!ossl_prov_is_running())
527e1051a39Sopenharmony_ci        return 0;
528e1051a39Sopenharmony_ci
529e1051a39Sopenharmony_ci    if (outsize < inl) {
530e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
531e1051a39Sopenharmony_ci        return 0;
532e1051a39Sopenharmony_ci    }
533e1051a39Sopenharmony_ci
534e1051a39Sopenharmony_ci    if (!ctx->hw->cipher(ctx, out, in, inl)) {
535e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
536e1051a39Sopenharmony_ci        return 0;
537e1051a39Sopenharmony_ci    }
538e1051a39Sopenharmony_ci
539e1051a39Sopenharmony_ci    *outl = inl;
540e1051a39Sopenharmony_ci    return 1;
541e1051a39Sopenharmony_ci}
542e1051a39Sopenharmony_ci
543e1051a39Sopenharmony_ciint ossl_cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
544e1051a39Sopenharmony_ci{
545e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
546e1051a39Sopenharmony_ci    OSSL_PARAM *p;
547e1051a39Sopenharmony_ci
548e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
549e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
550e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
551e1051a39Sopenharmony_ci        return 0;
552e1051a39Sopenharmony_ci    }
553e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
554e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) {
555e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
556e1051a39Sopenharmony_ci        return 0;
557e1051a39Sopenharmony_ci    }
558e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
559e1051a39Sopenharmony_ci    if (p != NULL
560e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
561e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
562e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
563e1051a39Sopenharmony_ci        return 0;
564e1051a39Sopenharmony_ci    }
565e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
566e1051a39Sopenharmony_ci    if (p != NULL
567e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
568e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
569e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
570e1051a39Sopenharmony_ci        return 0;
571e1051a39Sopenharmony_ci    }
572e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
573e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) {
574e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
575e1051a39Sopenharmony_ci        return 0;
576e1051a39Sopenharmony_ci    }
577e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
578e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
579e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
580e1051a39Sopenharmony_ci        return 0;
581e1051a39Sopenharmony_ci    }
582e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC);
583e1051a39Sopenharmony_ci    if (p != NULL
584e1051a39Sopenharmony_ci        && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) {
585e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
586e1051a39Sopenharmony_ci        return 0;
587e1051a39Sopenharmony_ci    }
588e1051a39Sopenharmony_ci    return 1;
589e1051a39Sopenharmony_ci}
590e1051a39Sopenharmony_ci
591e1051a39Sopenharmony_ciint ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
592e1051a39Sopenharmony_ci{
593e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
594e1051a39Sopenharmony_ci    const OSSL_PARAM *p;
595e1051a39Sopenharmony_ci
596e1051a39Sopenharmony_ci    if (params == NULL)
597e1051a39Sopenharmony_ci        return 1;
598e1051a39Sopenharmony_ci
599e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
600e1051a39Sopenharmony_ci    if (p != NULL) {
601e1051a39Sopenharmony_ci        unsigned int pad;
602e1051a39Sopenharmony_ci
603e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_uint(p, &pad)) {
604e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
605e1051a39Sopenharmony_ci            return 0;
606e1051a39Sopenharmony_ci        }
607e1051a39Sopenharmony_ci        ctx->pad = pad ? 1 : 0;
608e1051a39Sopenharmony_ci    }
609e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_USE_BITS);
610e1051a39Sopenharmony_ci    if (p != NULL) {
611e1051a39Sopenharmony_ci        unsigned int bits;
612e1051a39Sopenharmony_ci
613e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_uint(p, &bits)) {
614e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
615e1051a39Sopenharmony_ci            return 0;
616e1051a39Sopenharmony_ci        }
617e1051a39Sopenharmony_ci        ctx->use_bits = bits ? 1 : 0;
618e1051a39Sopenharmony_ci    }
619e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
620e1051a39Sopenharmony_ci    if (p != NULL) {
621e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) {
622e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
623e1051a39Sopenharmony_ci            return 0;
624e1051a39Sopenharmony_ci        }
625e1051a39Sopenharmony_ci    }
626e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE);
627e1051a39Sopenharmony_ci    if (p != NULL) {
628e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) {
629e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
630e1051a39Sopenharmony_ci            return 0;
631e1051a39Sopenharmony_ci        }
632e1051a39Sopenharmony_ci    }
633e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
634e1051a39Sopenharmony_ci    if (p != NULL) {
635e1051a39Sopenharmony_ci        unsigned int num;
636e1051a39Sopenharmony_ci
637e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_uint(p, &num)) {
638e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
639e1051a39Sopenharmony_ci            return 0;
640e1051a39Sopenharmony_ci        }
641e1051a39Sopenharmony_ci        ctx->num = num;
642e1051a39Sopenharmony_ci    }
643e1051a39Sopenharmony_ci    return 1;
644e1051a39Sopenharmony_ci}
645e1051a39Sopenharmony_ci
646e1051a39Sopenharmony_ciint ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
647e1051a39Sopenharmony_ci                               size_t ivlen)
648e1051a39Sopenharmony_ci{
649e1051a39Sopenharmony_ci    if (ivlen != ctx->ivlen
650e1051a39Sopenharmony_ci        || ivlen > sizeof(ctx->iv)) {
651e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
652e1051a39Sopenharmony_ci        return 0;
653e1051a39Sopenharmony_ci    }
654e1051a39Sopenharmony_ci    ctx->iv_set = 1;
655e1051a39Sopenharmony_ci    memcpy(ctx->iv, iv, ivlen);
656e1051a39Sopenharmony_ci    memcpy(ctx->oiv, iv, ivlen);
657e1051a39Sopenharmony_ci    return 1;
658e1051a39Sopenharmony_ci}
659e1051a39Sopenharmony_ci
660e1051a39Sopenharmony_civoid ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
661e1051a39Sopenharmony_ci                                 size_t ivbits, unsigned int mode,
662e1051a39Sopenharmony_ci                                 uint64_t flags, const PROV_CIPHER_HW *hw,
663e1051a39Sopenharmony_ci                                 void *provctx)
664e1051a39Sopenharmony_ci{
665e1051a39Sopenharmony_ci    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
666e1051a39Sopenharmony_ci
667e1051a39Sopenharmony_ci    if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0)
668e1051a39Sopenharmony_ci        ctx->inverse_cipher = 1;
669e1051a39Sopenharmony_ci    if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0)
670e1051a39Sopenharmony_ci        ctx->variable_keylength = 1;
671e1051a39Sopenharmony_ci
672e1051a39Sopenharmony_ci    ctx->pad = 1;
673e1051a39Sopenharmony_ci    ctx->keylen = ((kbits) / 8);
674e1051a39Sopenharmony_ci    ctx->ivlen = ((ivbits) / 8);
675e1051a39Sopenharmony_ci    ctx->hw = hw;
676e1051a39Sopenharmony_ci    ctx->mode = mode;
677e1051a39Sopenharmony_ci    ctx->blocksize = blkbits / 8;
678e1051a39Sopenharmony_ci    if (provctx != NULL)
679e1051a39Sopenharmony_ci        ctx->libctx = PROV_LIBCTX_OF(provctx); /* used for rand */
680e1051a39Sopenharmony_ci}
681