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