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