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