xref: /freebsd/crypto/openssl/providers/implementations/ciphers/ciphercommon.c (revision e7be843b4a162e68651d3911f0357ed464915629)
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 
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 
23 /*-
24  * Generic cipher functions for OSSL_PARAM gettables and settables
25  */
26 static const OSSL_PARAM cipher_known_gettable_params[] = {
27     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL),
28     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
29     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
30     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
31     OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL),
32     OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL),
33     OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL),
34     OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL),
35     OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL),
36     OSSL_PARAM_END
37 };
ossl_cipher_generic_gettable_params(ossl_unused void * provctx)38 const OSSL_PARAM *ossl_cipher_generic_gettable_params(ossl_unused void *provctx)
39 {
40     return cipher_known_gettable_params;
41 }
42 
ossl_cipher_generic_get_params(OSSL_PARAM params[],unsigned int md,uint64_t flags,size_t kbits,size_t blkbits,size_t ivbits)43 int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
44                                    uint64_t flags,
45                                    size_t kbits, size_t blkbits, size_t ivbits)
46 {
47     OSSL_PARAM *p;
48 
49     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
50     if (p != NULL && !OSSL_PARAM_set_uint(p, md)) {
51         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
52         return 0;
53     }
54     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD);
55     if (p != NULL
56         && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) {
57         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
58         return 0;
59     }
60     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV);
61     if (p != NULL
62         && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) {
63         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
64         return 0;
65     }
66     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS);
67     if (p != NULL
68         && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) {
69         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
70         return 0;
71     }
72     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK);
73     if (p != NULL
74         && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) {
75         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
76         return 0;
77     }
78     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY);
79     if (p != NULL
80         && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) {
81         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
82         return 0;
83     }
84     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
85     if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) {
86         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
87         return 0;
88     }
89     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
90     if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) {
91         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
92         return 0;
93     }
94     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
95     if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) {
96         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
97         return 0;
98     }
99     return 1;
100 }
101 
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic)102 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic)
103 { 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     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
150     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
151     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
152     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
153     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
154     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
155     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
156     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
157     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_AEAD_IV_GENERATED, NULL),
158     OSSL_PARAM_END
159 };
ossl_cipher_aead_gettable_ctx_params(ossl_unused void * cctx,ossl_unused void * provctx)160 const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params(
161         ossl_unused void *cctx, ossl_unused void *provctx
162     )
163 {
164     return cipher_aead_known_gettable_ctx_params;
165 }
166 
167 static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
168     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
169     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
170     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
171     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
172     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0),
173     OSSL_PARAM_END
174 };
ossl_cipher_aead_settable_ctx_params(ossl_unused void * cctx,ossl_unused void * provctx)175 const OSSL_PARAM *ossl_cipher_aead_settable_ctx_params(
176         ossl_unused void *cctx, ossl_unused void *provctx
177     )
178 {
179     return cipher_aead_known_settable_ctx_params;
180 }
181 
ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX * ctx)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 
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)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 
ossl_cipher_generic_einit(void * vctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])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 
ossl_cipher_generic_dinit(void * vctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])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 
ossl_cipher_generic_skey_einit(void * vctx,void * skeydata,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])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 
ossl_cipher_generic_skey_dinit(void * vctx,void * skeydata,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])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 
ossl_cipher_generic_block_update(void * vctx,unsigned char * out,size_t * outl,size_t outsize,const unsigned char * in,size_t inl)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 
337         /* Shouldn't normally fail */
338         if (!ctx->hw->cipher(ctx, out, in, inl)) {
339             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
340             return 0;
341         }
342 
343         if (ctx->alloced) {
344             OPENSSL_free(ctx->tlsmac);
345             ctx->alloced = 0;
346             ctx->tlsmac = NULL;
347         }
348 
349         /* This only fails if padding is publicly invalid */
350         *outl = inl;
351         if (!ctx->enc
352             && !ossl_cipher_tlsunpadblock(ctx->libctx, ctx->tlsversion,
353                                           out, outl,
354                                           blksz, &ctx->tlsmac, &ctx->alloced,
355                                           ctx->tlsmacsize, 0)) {
356             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
357             return 0;
358         }
359         return 1;
360     }
361 
362     if (ctx->bufsz != 0)
363         nextblocks = ossl_cipher_fillblock(ctx->buf, &ctx->bufsz, blksz,
364                                            &in, &inl);
365     else
366         nextblocks = inl & ~(blksz-1);
367 
368     /*
369      * If we're decrypting and we end an update on a block boundary we hold
370      * the last block back in case this is the last update call and the last
371      * block is padded.
372      */
373     if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
374         if (outsize < blksz) {
375             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
376             return 0;
377         }
378         if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
379             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
380             return 0;
381         }
382         ctx->bufsz = 0;
383         outlint = blksz;
384         out += blksz;
385     }
386     if (nextblocks > 0) {
387         if (!ctx->enc && ctx->pad && nextblocks == inl) {
388             if (!ossl_assert(inl >= blksz)) {
389                 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
390                 return 0;
391             }
392             nextblocks -= blksz;
393         }
394         outlint += nextblocks;
395         if (outsize < outlint) {
396             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
397             return 0;
398         }
399     }
400     if (nextblocks > 0) {
401         if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
402             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
403             return 0;
404         }
405         in += nextblocks;
406         inl -= nextblocks;
407     }
408     if (inl != 0
409         && !ossl_cipher_trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
410         /* ERR_raise already called */
411         return 0;
412     }
413 
414     *outl = outlint;
415     return inl == 0;
416 }
417 
ossl_cipher_generic_block_final(void * vctx,unsigned char * out,size_t * outl,size_t outsize)418 int ossl_cipher_generic_block_final(void *vctx, unsigned char *out,
419                                     size_t *outl, size_t outsize)
420 {
421     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
422     size_t blksz = ctx->blocksize;
423 
424     if (!ossl_prov_is_running())
425         return 0;
426 
427     if (!ctx->key_set) {
428         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
429         return 0;
430     }
431 
432     if (ctx->tlsversion > 0) {
433         /* We never finalize TLS, so this is an error */
434         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
435         return 0;
436     }
437 
438     if (ctx->enc) {
439         if (ctx->pad) {
440             ossl_cipher_padblock(ctx->buf, &ctx->bufsz, blksz);
441         } else if (ctx->bufsz == 0) {
442             *outl = 0;
443             return 1;
444         } else if (ctx->bufsz != blksz) {
445             ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
446             return 0;
447         }
448 
449         if (outsize < blksz) {
450             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
451             return 0;
452         }
453         if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
454             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
455             return 0;
456         }
457         ctx->bufsz = 0;
458         *outl = blksz;
459         return 1;
460     }
461 
462     /* Decrypting */
463     if (ctx->bufsz != blksz) {
464         if (ctx->bufsz == 0 && !ctx->pad) {
465             *outl = 0;
466             return 1;
467         }
468         ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
469         return 0;
470     }
471 
472     if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
473         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
474         return 0;
475     }
476 
477     if (ctx->pad && !ossl_cipher_unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
478         /* ERR_raise already called */
479         return 0;
480     }
481 
482     if (outsize < ctx->bufsz) {
483         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
484         return 0;
485     }
486     memcpy(out, ctx->buf, ctx->bufsz);
487     *outl = ctx->bufsz;
488     ctx->bufsz = 0;
489     return 1;
490 }
491 
ossl_cipher_generic_stream_update(void * vctx,unsigned char * out,size_t * outl,size_t outsize,const unsigned char * in,size_t inl)492 int ossl_cipher_generic_stream_update(void *vctx, unsigned char *out,
493                                       size_t *outl, size_t outsize,
494                                       const unsigned char *in, size_t inl)
495 {
496     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
497 
498     if (!ctx->key_set) {
499         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
500         return 0;
501     }
502 
503     if (inl == 0) {
504         *outl = 0;
505         return 1;
506     }
507 
508     if (outsize < inl) {
509         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
510         return 0;
511     }
512 
513     if (!ctx->hw->cipher(ctx, out, in, inl)) {
514         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
515         return 0;
516     }
517 
518     *outl = inl;
519     if (!ctx->enc && ctx->tlsversion > 0) {
520         /*
521         * Remove any TLS padding. Only used by cipher_aes_cbc_hmac_sha1_hw.c and
522         * cipher_aes_cbc_hmac_sha256_hw.c
523         */
524         if (ctx->removetlspad) {
525             /*
526              * We should have already failed in the cipher() call above if this
527              * isn't true.
528              */
529             if (!ossl_assert(*outl >= (size_t)(out[inl - 1] + 1)))
530                 return 0;
531             /* The actual padding length */
532             *outl -= out[inl - 1] + 1;
533         }
534 
535         /* TLS MAC and explicit IV if relevant. We should have already failed
536          * in the cipher() call above if *outl is too short.
537          */
538         if (!ossl_assert(*outl >= ctx->removetlsfixed))
539             return 0;
540         *outl -= ctx->removetlsfixed;
541 
542         /* Extract the MAC if there is one */
543         if (ctx->tlsmacsize > 0) {
544             if (*outl < ctx->tlsmacsize)
545                 return 0;
546 
547             ctx->tlsmac = out + *outl - ctx->tlsmacsize;
548             *outl -= ctx->tlsmacsize;
549         }
550     }
551 
552     return 1;
553 }
ossl_cipher_generic_stream_final(void * vctx,unsigned char * out,size_t * outl,size_t outsize)554 int ossl_cipher_generic_stream_final(void *vctx, unsigned char *out,
555                                      size_t *outl, size_t outsize)
556 {
557     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
558 
559     if (!ossl_prov_is_running())
560         return 0;
561 
562     if (!ctx->key_set) {
563         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
564         return 0;
565     }
566 
567     *outl = 0;
568     return 1;
569 }
570 
ossl_cipher_generic_cipher(void * vctx,unsigned char * out,size_t * outl,size_t outsize,const unsigned char * in,size_t inl)571 int ossl_cipher_generic_cipher(void *vctx, unsigned char *out, size_t *outl,
572                                size_t outsize, const unsigned char *in,
573                                size_t inl)
574 {
575     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
576 
577     if (!ossl_prov_is_running())
578         return 0;
579 
580     if (!ctx->key_set) {
581         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
582         return 0;
583     }
584 
585     if (outsize < inl) {
586         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
587         return 0;
588     }
589 
590     if (!ctx->hw->cipher(ctx, out, in, inl)) {
591         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
592         return 0;
593     }
594 
595     *outl = inl;
596     return 1;
597 }
598 
ossl_cipher_generic_get_ctx_params(void * vctx,OSSL_PARAM params[])599 int ossl_cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
600 {
601     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
602     OSSL_PARAM *p;
603 
604     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
605     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
606         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
607         return 0;
608     }
609     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
610     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) {
611         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
612         return 0;
613     }
614     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
615     if (p != NULL
616         && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
617         && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
618         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
619         return 0;
620     }
621     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
622     if (p != NULL
623         && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
624         && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
625         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
626         return 0;
627     }
628     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
629     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) {
630         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
631         return 0;
632     }
633     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
634     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
635         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
636         return 0;
637     }
638     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC);
639     if (p != NULL
640         && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) {
641         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
642         return 0;
643     }
644     return 1;
645 }
646 
ossl_cipher_generic_set_ctx_params(void * vctx,const OSSL_PARAM params[])647 int ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
648 {
649     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
650     const OSSL_PARAM *p;
651 
652     if (ossl_param_is_empty(params))
653         return 1;
654 
655     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
656     if (p != NULL) {
657         unsigned int pad;
658 
659         if (!OSSL_PARAM_get_uint(p, &pad)) {
660             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
661             return 0;
662         }
663         ctx->pad = pad ? 1 : 0;
664     }
665     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_USE_BITS);
666     if (p != NULL) {
667         unsigned int bits;
668 
669         if (!OSSL_PARAM_get_uint(p, &bits)) {
670             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
671             return 0;
672         }
673         ctx->use_bits = bits ? 1 : 0;
674     }
675     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
676     if (p != NULL) {
677         if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) {
678             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
679             return 0;
680         }
681     }
682     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE);
683     if (p != NULL) {
684         if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) {
685             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
686             return 0;
687         }
688     }
689     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
690     if (p != NULL) {
691         unsigned int num;
692 
693         if (!OSSL_PARAM_get_uint(p, &num)) {
694             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
695             return 0;
696         }
697         ctx->num = num;
698     }
699     return 1;
700 }
701 
ossl_cipher_generic_initiv(PROV_CIPHER_CTX * ctx,const unsigned char * iv,size_t ivlen)702 int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
703                                size_t ivlen)
704 {
705     if (ivlen != ctx->ivlen
706         || ivlen > sizeof(ctx->iv)) {
707         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
708         return 0;
709     }
710     ctx->iv_set = 1;
711     memcpy(ctx->iv, iv, ivlen);
712     memcpy(ctx->oiv, iv, ivlen);
713     return 1;
714 }
715 
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)716 void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
717                                  size_t ivbits, unsigned int mode,
718                                  uint64_t flags, const PROV_CIPHER_HW *hw,
719                                  void *provctx)
720 {
721     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
722 
723     if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0)
724         ctx->inverse_cipher = 1;
725     if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0)
726         ctx->variable_keylength = 1;
727 
728     ctx->pad = 1;
729     ctx->keylen = ((kbits) / 8);
730     ctx->ivlen = ((ivbits) / 8);
731     ctx->hw = hw;
732     ctx->mode = mode;
733     ctx->blocksize = blkbits / 8;
734     if (provctx != NULL)
735         ctx->libctx = PROV_LIBCTX_OF(provctx); /* used for rand */
736 }
737