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