xref: /freebsd/crypto/openssl/providers/implementations/ciphers/cipher_aes_ocb.c (revision 78e936b2d0b5e6554425009199be31e76bc67c10)
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  * AES low level APIs are deprecated for public use, but still ok for internal
12  * use where we're using them to implement the higher level EVP interface, as is
13  * the case here.
14  */
15 #include "internal/deprecated.h"
16 
17 #include <openssl/proverr.h>
18 #include "cipher_aes_ocb.h"
19 #include "prov/providercommon.h"
20 #include "prov/ciphercommon_aead.h"
21 #include "prov/implementations.h"
22 
23 #define AES_OCB_FLAGS AEAD_FLAGS
24 
25 #define OCB_DEFAULT_TAG_LEN 16
26 #define OCB_DEFAULT_IV_LEN 12
27 #define OCB_MIN_IV_LEN 1
28 #define OCB_MAX_IV_LEN 15
29 
30 PROV_CIPHER_FUNC(int, ocb_cipher, (PROV_AES_OCB_CTX *ctx, const unsigned char *in, unsigned char *out, size_t nextblock));
31 /* forward declarations */
32 static OSSL_FUNC_cipher_encrypt_init_fn aes_ocb_einit;
33 static OSSL_FUNC_cipher_decrypt_init_fn aes_ocb_dinit;
34 static OSSL_FUNC_cipher_update_fn aes_ocb_block_update;
35 static OSSL_FUNC_cipher_final_fn aes_ocb_block_final;
36 static OSSL_FUNC_cipher_cipher_fn aes_ocb_cipher;
37 static OSSL_FUNC_cipher_freectx_fn aes_ocb_freectx;
38 static OSSL_FUNC_cipher_dupctx_fn aes_ocb_dupctx;
39 static OSSL_FUNC_cipher_get_ctx_params_fn aes_ocb_get_ctx_params;
40 static OSSL_FUNC_cipher_set_ctx_params_fn aes_ocb_set_ctx_params;
41 static OSSL_FUNC_cipher_gettable_ctx_params_fn cipher_ocb_gettable_ctx_params;
42 static OSSL_FUNC_cipher_settable_ctx_params_fn cipher_ocb_settable_ctx_params;
43 
44 /*
45  * The following methods could be moved into PROV_AES_OCB_HW if
46  * multiple hardware implementations are ever needed.
47  */
aes_generic_ocb_setiv(PROV_AES_OCB_CTX * ctx,const unsigned char * iv,size_t ivlen,size_t taglen)48 static ossl_inline int aes_generic_ocb_setiv(PROV_AES_OCB_CTX *ctx,
49     const unsigned char *iv,
50     size_t ivlen, size_t taglen)
51 {
52     return (CRYPTO_ocb128_setiv(&ctx->ocb, iv, ivlen, taglen) == 1);
53 }
54 
aes_generic_ocb_setaad(PROV_AES_OCB_CTX * ctx,const unsigned char * aad,size_t alen)55 static ossl_inline int aes_generic_ocb_setaad(PROV_AES_OCB_CTX *ctx,
56     const unsigned char *aad,
57     size_t alen)
58 {
59     return CRYPTO_ocb128_aad(&ctx->ocb, aad, alen) == 1;
60 }
61 
aes_generic_ocb_gettag(PROV_AES_OCB_CTX * ctx,unsigned char * tag,size_t tlen)62 static ossl_inline int aes_generic_ocb_gettag(PROV_AES_OCB_CTX *ctx,
63     unsigned char *tag, size_t tlen)
64 {
65     return CRYPTO_ocb128_tag(&ctx->ocb, tag, tlen) > 0;
66 }
67 
aes_generic_ocb_final(PROV_AES_OCB_CTX * ctx)68 static ossl_inline int aes_generic_ocb_final(PROV_AES_OCB_CTX *ctx)
69 {
70     return (CRYPTO_ocb128_finish(&ctx->ocb, ctx->tag, ctx->taglen) == 0);
71 }
72 
aes_generic_ocb_cleanup(PROV_AES_OCB_CTX * ctx)73 static ossl_inline void aes_generic_ocb_cleanup(PROV_AES_OCB_CTX *ctx)
74 {
75     CRYPTO_ocb128_cleanup(&ctx->ocb);
76 }
77 
aes_generic_ocb_cipher(PROV_AES_OCB_CTX * ctx,const unsigned char * in,unsigned char * out,size_t len)78 static ossl_inline int aes_generic_ocb_cipher(PROV_AES_OCB_CTX *ctx,
79     const unsigned char *in,
80     unsigned char *out, size_t len)
81 {
82     if (ctx->base.enc) {
83         if (!CRYPTO_ocb128_encrypt(&ctx->ocb, in, out, len))
84             return 0;
85     } else {
86         if (!CRYPTO_ocb128_decrypt(&ctx->ocb, in, out, len))
87             return 0;
88     }
89     return 1;
90 }
91 
aes_generic_ocb_copy_ctx(PROV_AES_OCB_CTX * dst,PROV_AES_OCB_CTX * src)92 static ossl_inline int aes_generic_ocb_copy_ctx(PROV_AES_OCB_CTX *dst,
93     PROV_AES_OCB_CTX *src)
94 {
95     return CRYPTO_ocb128_copy_ctx(&dst->ocb, &src->ocb,
96         &dst->ksenc.ks, &dst->ksdec.ks);
97 }
98 
99 /*-
100  * Provider dispatch functions
101  */
aes_ocb_init(void * vctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[],int enc)102 static int aes_ocb_init(void *vctx, const unsigned char *key, size_t keylen,
103     const unsigned char *iv, size_t ivlen,
104     const OSSL_PARAM params[], int enc)
105 {
106     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
107 
108     if (!ossl_prov_is_running())
109         return 0;
110 
111     ctx->aad_buf_len = 0;
112     ctx->data_buf_len = 0;
113     ctx->base.enc = enc;
114 
115     if (iv != NULL) {
116         if (ivlen != ctx->base.ivlen) {
117             /* IV len must be 1 to 15 */
118             if (ivlen < OCB_MIN_IV_LEN || ivlen > OCB_MAX_IV_LEN) {
119                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
120                 return 0;
121             }
122             ctx->base.ivlen = ivlen;
123         }
124         if (!ossl_cipher_generic_initiv(&ctx->base, iv, ivlen))
125             return 0;
126         ctx->iv_state = IV_STATE_BUFFERED;
127     }
128     if (key != NULL) {
129         if (keylen != ctx->base.keylen) {
130             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
131             return 0;
132         }
133         if (!ctx->base.hw->init(&ctx->base, key, keylen))
134             return 0;
135     }
136     return aes_ocb_set_ctx_params(ctx, params);
137 }
138 
aes_ocb_einit(void * vctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])139 static int aes_ocb_einit(void *vctx, const unsigned char *key, size_t keylen,
140     const unsigned char *iv, size_t ivlen,
141     const OSSL_PARAM params[])
142 {
143     return aes_ocb_init(vctx, key, keylen, iv, ivlen, params, 1);
144 }
145 
aes_ocb_dinit(void * vctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])146 static int aes_ocb_dinit(void *vctx, const unsigned char *key, size_t keylen,
147     const unsigned char *iv, size_t ivlen,
148     const OSSL_PARAM params[])
149 {
150     return aes_ocb_init(vctx, key, keylen, iv, ivlen, params, 0);
151 }
152 
153 /*
154  * Because of the way OCB works, both the AAD and data are buffered in the
155  * same way. Only the last block can be a partial block.
156  */
aes_ocb_block_update_internal(PROV_AES_OCB_CTX * ctx,unsigned char * buf,size_t * bufsz,unsigned char * out,size_t * outl,size_t outsize,const unsigned char * in,size_t inl,OSSL_ocb_cipher_fn ciph)157 static int aes_ocb_block_update_internal(PROV_AES_OCB_CTX *ctx,
158     unsigned char *buf, size_t *bufsz,
159     unsigned char *out, size_t *outl,
160     size_t outsize, const unsigned char *in,
161     size_t inl, OSSL_ocb_cipher_fn ciph)
162 {
163     size_t nextblocks;
164     size_t outlint = 0;
165 
166     if (*bufsz != 0)
167         nextblocks = ossl_cipher_fillblock(buf, bufsz, AES_BLOCK_SIZE, &in, &inl);
168     else
169         nextblocks = inl & ~(AES_BLOCK_SIZE - 1);
170 
171     if (*bufsz == AES_BLOCK_SIZE) {
172         if (outsize < AES_BLOCK_SIZE) {
173             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
174             return 0;
175         }
176         if (!ciph(ctx, buf, out, AES_BLOCK_SIZE)) {
177             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
178             return 0;
179         }
180         *bufsz = 0;
181         outlint = AES_BLOCK_SIZE;
182         if (out != NULL)
183             out += AES_BLOCK_SIZE;
184     }
185     if (nextblocks > 0) {
186         outlint += nextblocks;
187         if (outsize < outlint) {
188             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
189             return 0;
190         }
191         if (!ciph(ctx, in, out, nextblocks)) {
192             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
193             return 0;
194         }
195         in += nextblocks;
196         inl -= nextblocks;
197     }
198     if (inl != 0
199         && !ossl_cipher_trailingdata(buf, bufsz, AES_BLOCK_SIZE, &in, &inl)) {
200         /* PROVerr already called */
201         return 0;
202     }
203 
204     *outl = outlint;
205     return inl == 0;
206 }
207 
208 /* A wrapper function that has the same signature as cipher */
cipher_updateaad(PROV_AES_OCB_CTX * ctx,const unsigned char * in,unsigned char * out,size_t len)209 static int cipher_updateaad(PROV_AES_OCB_CTX *ctx, const unsigned char *in,
210     unsigned char *out, size_t len)
211 {
212     return aes_generic_ocb_setaad(ctx, in, len);
213 }
214 
update_iv(PROV_AES_OCB_CTX * ctx)215 static int update_iv(PROV_AES_OCB_CTX *ctx)
216 {
217     if (ctx->iv_state == IV_STATE_FINISHED
218         || ctx->iv_state == IV_STATE_UNINITIALISED)
219         return 0;
220     if (ctx->iv_state == IV_STATE_BUFFERED) {
221         if (!aes_generic_ocb_setiv(ctx, ctx->base.iv, ctx->base.ivlen,
222                 ctx->taglen))
223             return 0;
224         ctx->iv_state = IV_STATE_COPIED;
225     }
226     return 1;
227 }
228 
aes_ocb_block_update(void * vctx,unsigned char * out,size_t * outl,size_t outsize,const unsigned char * in,size_t inl)229 static int aes_ocb_block_update(void *vctx, unsigned char *out, size_t *outl,
230     size_t outsize, const unsigned char *in,
231     size_t inl)
232 {
233     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
234     unsigned char *buf;
235     size_t *buflen;
236     OSSL_ocb_cipher_fn fn;
237 
238     if (!ctx->key_set || !update_iv(ctx))
239         return 0;
240 
241     if (inl == 0) {
242         *outl = 0;
243         return 1;
244     }
245 
246     /* Are we dealing with AAD or normal data here? */
247     if (out == NULL) {
248         buf = ctx->aad_buf;
249         buflen = &ctx->aad_buf_len;
250         fn = cipher_updateaad;
251     } else {
252         buf = ctx->data_buf;
253         buflen = &ctx->data_buf_len;
254         fn = aes_generic_ocb_cipher;
255     }
256     return aes_ocb_block_update_internal(ctx, buf, buflen, out, outl, outsize,
257         in, inl, fn);
258 }
259 
aes_ocb_block_final(void * vctx,unsigned char * out,size_t * outl,size_t outsize)260 static int aes_ocb_block_final(void *vctx, unsigned char *out, size_t *outl,
261     size_t outsize)
262 {
263     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
264 
265     if (!ossl_prov_is_running())
266         return 0;
267 
268     /* If no block_update has run then the iv still needs to be set */
269     if (!ctx->key_set || !update_iv(ctx))
270         return 0;
271 
272     /*
273      * Empty the buffer of any partial block that we might have been provided,
274      * both for data and AAD
275      */
276     *outl = 0;
277     if (ctx->data_buf_len > 0) {
278         if (!aes_generic_ocb_cipher(ctx, ctx->data_buf, out, ctx->data_buf_len))
279             return 0;
280         *outl = ctx->data_buf_len;
281         ctx->data_buf_len = 0;
282     }
283     if (ctx->aad_buf_len > 0) {
284         if (!aes_generic_ocb_setaad(ctx, ctx->aad_buf, ctx->aad_buf_len))
285             return 0;
286         ctx->aad_buf_len = 0;
287     }
288     if (ctx->base.enc) {
289         /* If encrypting then just get the tag */
290         if (!aes_generic_ocb_gettag(ctx, ctx->tag, ctx->taglen))
291             return 0;
292     } else {
293         /* If decrypting then verify */
294         if (ctx->taglen == 0)
295             return 0;
296         if (!aes_generic_ocb_final(ctx))
297             return 0;
298     }
299     /* Don't reuse the IV */
300     ctx->iv_state = IV_STATE_FINISHED;
301     return 1;
302 }
303 
aes_ocb_newctx(void * provctx,size_t kbits,size_t blkbits,size_t ivbits,unsigned int mode,uint64_t flags)304 static void *aes_ocb_newctx(void *provctx, size_t kbits, size_t blkbits,
305     size_t ivbits, unsigned int mode, uint64_t flags)
306 {
307     PROV_AES_OCB_CTX *ctx;
308 
309     if (!ossl_prov_is_running())
310         return NULL;
311 
312     ctx = OPENSSL_zalloc(sizeof(*ctx));
313     if (ctx != NULL) {
314         ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags,
315             ossl_prov_cipher_hw_aes_ocb(kbits), NULL);
316         ctx->taglen = OCB_DEFAULT_TAG_LEN;
317     }
318     return ctx;
319 }
320 
aes_ocb_freectx(void * vctx)321 static void aes_ocb_freectx(void *vctx)
322 {
323     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
324 
325     if (ctx != NULL) {
326         aes_generic_ocb_cleanup(ctx);
327         ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
328         OPENSSL_clear_free(ctx, sizeof(*ctx));
329     }
330 }
331 
aes_ocb_dupctx(void * vctx)332 static void *aes_ocb_dupctx(void *vctx)
333 {
334     PROV_AES_OCB_CTX *in = (PROV_AES_OCB_CTX *)vctx;
335     PROV_AES_OCB_CTX *ret;
336 
337     if (!ossl_prov_is_running())
338         return NULL;
339 
340     ret = OPENSSL_malloc(sizeof(*ret));
341     if (ret == NULL)
342         return NULL;
343     *ret = *in;
344     if (!aes_generic_ocb_copy_ctx(ret, in)) {
345         OPENSSL_free(ret);
346         ret = NULL;
347     }
348     return ret;
349 }
350 
aes_ocb_set_ctx_params(void * vctx,const OSSL_PARAM params[])351 static int aes_ocb_set_ctx_params(void *vctx, const OSSL_PARAM params[])
352 {
353     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
354     const OSSL_PARAM *p;
355     size_t sz;
356 
357     if (ossl_param_is_empty(params))
358         return 1;
359 
360     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG);
361     if (p != NULL) {
362         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
363             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
364             return 0;
365         }
366         if (p->data == NULL) {
367             /* Tag len must be 0 to 16 */
368             if (p->data_size > OCB_MAX_TAG_LEN) {
369                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH);
370                 return 0;
371             }
372             ctx->taglen = p->data_size;
373         } else {
374             if (ctx->base.enc) {
375                 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
376                 return 0;
377             }
378             if (p->data_size != ctx->taglen) {
379                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH);
380                 return 0;
381             }
382             memcpy(ctx->tag, p->data, p->data_size);
383         }
384     }
385     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN);
386     if (p != NULL) {
387         if (!OSSL_PARAM_get_size_t(p, &sz)) {
388             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
389             return 0;
390         }
391         /* IV len must be 1 to 15 */
392         if (sz < OCB_MIN_IV_LEN || sz > OCB_MAX_IV_LEN)
393             return 0;
394         if (ctx->base.ivlen != sz) {
395             ctx->base.ivlen = sz;
396             ctx->iv_state = IV_STATE_UNINITIALISED;
397         }
398     }
399     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
400     if (p != NULL) {
401         size_t keylen;
402 
403         if (!OSSL_PARAM_get_size_t(p, &keylen)) {
404             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
405             return 0;
406         }
407         if (ctx->base.keylen != keylen) {
408             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
409             return 0;
410         }
411     }
412     return 1;
413 }
414 
aes_ocb_get_ctx_params(void * vctx,OSSL_PARAM params[])415 static int aes_ocb_get_ctx_params(void *vctx, OSSL_PARAM params[])
416 {
417     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
418     OSSL_PARAM *p;
419 
420     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
421     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.ivlen)) {
422         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
423         return 0;
424     }
425     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
426     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.keylen)) {
427         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
428         return 0;
429     }
430     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN);
431     if (p != NULL) {
432         if (!OSSL_PARAM_set_size_t(p, ctx->taglen)) {
433             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
434             return 0;
435         }
436     }
437 
438     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
439     if (p != NULL) {
440         if (ctx->base.ivlen > p->data_size) {
441             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
442             return 0;
443         }
444         if (!OSSL_PARAM_set_octet_string(p, ctx->base.oiv, ctx->base.ivlen)
445             && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.oiv, ctx->base.ivlen)) {
446             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
447             return 0;
448         }
449     }
450     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
451     if (p != NULL) {
452         if (ctx->base.ivlen > p->data_size) {
453             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
454             return 0;
455         }
456         if (!OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen)
457             && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.iv, ctx->base.ivlen)) {
458             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
459             return 0;
460         }
461     }
462     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG);
463     if (p != NULL) {
464         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
465             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
466             return 0;
467         }
468         if (!ctx->base.enc || p->data_size != ctx->taglen) {
469             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH);
470             return 0;
471         }
472         memcpy(p->data, ctx->tag, ctx->taglen);
473     }
474     return 1;
475 }
476 
477 static const OSSL_PARAM cipher_ocb_known_gettable_ctx_params[] = {
478     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
479     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
480     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
481     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
482     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
483     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
484     OSSL_PARAM_END
485 };
cipher_ocb_gettable_ctx_params(ossl_unused void * cctx,ossl_unused void * p_ctx)486 static const OSSL_PARAM *cipher_ocb_gettable_ctx_params(ossl_unused void *cctx,
487     ossl_unused void *p_ctx)
488 {
489     return cipher_ocb_known_gettable_ctx_params;
490 }
491 
492 static const OSSL_PARAM cipher_ocb_known_settable_ctx_params[] = {
493     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
494     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
495     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
496     OSSL_PARAM_END
497 };
cipher_ocb_settable_ctx_params(ossl_unused void * cctx,ossl_unused void * p_ctx)498 static const OSSL_PARAM *cipher_ocb_settable_ctx_params(ossl_unused void *cctx,
499     ossl_unused void *p_ctx)
500 {
501     return cipher_ocb_known_settable_ctx_params;
502 }
503 
aes_ocb_cipher(void * vctx,unsigned char * out,size_t * outl,size_t outsize,const unsigned char * in,size_t inl)504 static int aes_ocb_cipher(void *vctx, unsigned char *out, size_t *outl,
505     size_t outsize, const unsigned char *in, size_t inl)
506 {
507     PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
508 
509     if (!ossl_prov_is_running())
510         return 0;
511 
512     /* NULL input indicates Final, which must generate or check the tag. */
513     if (in == NULL)
514         return aes_ocb_block_final(vctx, out, outl, outsize);
515 
516     if (outsize < inl) {
517         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
518         return 0;
519     }
520 
521     /*
522      * Mirror the streaming handler: refuse if the key has not been set,
523      * and push the buffered IV into the OCB context before any data is
524      * processed.  Without this, CRYPTO_ocb128_encrypt/decrypt runs with
525      * Offset_0 = 0 regardless of the caller's IV -- catastrophic
526      * (key, nonce) reuse, and a subsequent EVP_*Final_ex() emits a tag
527      * that is a function of (key, iv) only.
528      */
529     if (!ctx->key_set || !update_iv(ctx)) {
530         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
531         return 0;
532     }
533 
534     if (!aes_generic_ocb_cipher(ctx, in, out, inl)) {
535         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
536         return 0;
537     }
538 
539     *outl = inl;
540     return 1;
541 }
542 
543 #define IMPLEMENT_cipher(mode, UCMODE, flags, kbits, blkbits, ivbits)           \
544     static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##mode##_get_params;    \
545     static int aes_##kbits##_##mode##_get_params(OSSL_PARAM params[])           \
546     {                                                                           \
547         return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \
548             flags, kbits, blkbits, ivbits);                                     \
549     }                                                                           \
550     static OSSL_FUNC_cipher_newctx_fn aes_##kbits##_##mode##_newctx;            \
551     static void *aes_##kbits##_##mode##_newctx(void *provctx)                   \
552     {                                                                           \
553         return aes_##mode##_newctx(provctx, kbits, blkbits, ivbits,             \
554             EVP_CIPH_##UCMODE##_MODE, flags);                                   \
555     }                                                                           \
556     const OSSL_DISPATCH ossl_##aes##kbits##mode##_functions[] = {               \
557         { OSSL_FUNC_CIPHER_NEWCTX,                                              \
558             (void (*)(void))aes_##kbits##_##mode##_newctx },                    \
559         { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_##mode##_einit },  \
560         { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_##mode##_dinit },  \
561         { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_##mode##_block_update }, \
562         { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_##mode##_block_final },   \
563         { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_ocb_cipher },            \
564         { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_##mode##_freectx },     \
565         { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_##mode##_dupctx },       \
566         { OSSL_FUNC_CIPHER_GET_PARAMS,                                          \
567             (void (*)(void))aes_##kbits##_##mode##_get_params },                \
568         { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                      \
569             (void (*)(void))aes_##mode##_get_ctx_params },                      \
570         { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                      \
571             (void (*)(void))aes_##mode##_set_ctx_params },                      \
572         { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                     \
573             (void (*)(void))ossl_cipher_generic_gettable_params },              \
574         { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                 \
575             (void (*)(void))cipher_ocb_gettable_ctx_params },                   \
576         { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                 \
577             (void (*)(void))cipher_ocb_settable_ctx_params },                   \
578         OSSL_DISPATCH_END                                                       \
579     }
580 
581 IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 256, 128, OCB_DEFAULT_IV_LEN * 8);
582 IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 192, 128, OCB_DEFAULT_IV_LEN * 8);
583 IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 128, 128, OCB_DEFAULT_IV_LEN * 8);
584