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