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