diff options
-rw-r--r-- | src/lib/libcrypto/evp/evp_enc.c | 122 |
1 files changed, 63 insertions, 59 deletions
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c index e8944dc9a4..edc15fdab4 100644 --- a/src/lib/libcrypto/evp/evp_enc.c +++ b/src/lib/libcrypto/evp/evp_enc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: evp_enc.c,v 1.60 2023/12/15 13:33:10 tb Exp $ */ | 1 | /* $OpenBSD: evp_enc.c,v 1.61 2023/12/16 09:46:06 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -265,11 +265,39 @@ EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, | |||
265 | return ctx->cipher->do_cipher(ctx, out, in, inl); | 265 | return ctx->cipher->do_cipher(ctx, out, in, inl); |
266 | } | 266 | } |
267 | 267 | ||
268 | static int | ||
269 | evp_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len, | ||
270 | const unsigned char *in, int in_len) | ||
271 | { | ||
272 | int len; | ||
273 | |||
274 | *out_len = 0; | ||
275 | |||
276 | if (in_len < 0) | ||
277 | return 0; | ||
278 | |||
279 | if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) { | ||
280 | if ((len = ctx->cipher->do_cipher(ctx, out, in, in_len)) < 0) | ||
281 | return 0; | ||
282 | |||
283 | *out_len = len; | ||
284 | return 1; | ||
285 | } | ||
286 | |||
287 | if (!ctx->cipher->do_cipher(ctx, out, in, in_len)) | ||
288 | return 0; | ||
289 | |||
290 | *out_len = in_len; | ||
291 | |||
292 | return 1; | ||
293 | } | ||
294 | |||
268 | int | 295 | int |
269 | EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 296 | EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, |
270 | const unsigned char *in, int inl) | 297 | const unsigned char *in, int inl) |
271 | { | 298 | { |
272 | int i, j, bl; | 299 | int i, j, bl; |
300 | int len = 0, total_len = 0; | ||
273 | 301 | ||
274 | *outl = 0; | 302 | *outl = 0; |
275 | 303 | ||
@@ -279,36 +307,22 @@ EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
279 | if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE) | 307 | if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE) |
280 | return 1; | 308 | return 1; |
281 | 309 | ||
282 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { | 310 | if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) |
283 | i = ctx->cipher->do_cipher(ctx, out, in, inl); | 311 | return evp_cipher(ctx, out, outl, in, inl); |
284 | if (i < 0) | 312 | |
285 | return 0; | 313 | if (ctx->buf_len == 0 && (inl & ctx->block_mask) == 0) |
286 | else | 314 | return evp_cipher(ctx, out, outl, in, inl); |
287 | *outl = i; | ||
288 | return 1; | ||
289 | } | ||
290 | 315 | ||
291 | if (ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { | ||
292 | if (ctx->cipher->do_cipher(ctx, out, in, inl)) { | ||
293 | *outl = inl; | ||
294 | return 1; | ||
295 | } else { | ||
296 | *outl = 0; | ||
297 | return 0; | ||
298 | } | ||
299 | } | ||
300 | i = ctx->buf_len; | 316 | i = ctx->buf_len; |
301 | bl = ctx->cipher->block_size; | 317 | bl = ctx->cipher->block_size; |
302 | if ((size_t)bl > sizeof(ctx->buf)) { | 318 | if ((size_t)bl > sizeof(ctx->buf)) { |
303 | EVPerror(EVP_R_BAD_BLOCK_LENGTH); | 319 | EVPerror(EVP_R_BAD_BLOCK_LENGTH); |
304 | *outl = 0; | ||
305 | return 0; | 320 | return 0; |
306 | } | 321 | } |
307 | if (i != 0) { | 322 | if (i != 0) { |
308 | if (bl - i > inl) { | 323 | if (bl - i > inl) { |
309 | memcpy(&(ctx->buf[i]), in, inl); | 324 | memcpy(&(ctx->buf[i]), in, inl); |
310 | ctx->buf_len += inl; | 325 | ctx->buf_len += inl; |
311 | *outl = 0; | ||
312 | return 1; | 326 | return 1; |
313 | } else { | 327 | } else { |
314 | j = bl - i; | 328 | j = bl - i; |
@@ -324,26 +338,37 @@ EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
324 | return 0; | 338 | return 0; |
325 | } | 339 | } |
326 | memcpy(&(ctx->buf[i]), in, j); | 340 | memcpy(&(ctx->buf[i]), in, j); |
327 | if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl)) | 341 | |
342 | len = 0; | ||
343 | if (!evp_cipher(ctx, out, &len, ctx->buf, bl)) | ||
328 | return 0; | 344 | return 0; |
345 | total_len = len; | ||
346 | |||
329 | inl -= j; | 347 | inl -= j; |
330 | in += j; | 348 | in += j; |
331 | out += bl; | 349 | out += len; |
332 | *outl = bl; | ||
333 | } | 350 | } |
334 | } else | 351 | } |
335 | *outl = 0; | 352 | |
336 | i = inl&(bl - 1); | 353 | i = inl&(bl - 1); |
337 | inl -= i; | 354 | inl -= i; |
338 | if (inl > 0) { | 355 | if (inl > 0) { |
339 | if (!ctx->cipher->do_cipher(ctx, out, in, inl)) | 356 | if (INT_MAX - inl < total_len) |
357 | return 0; | ||
358 | len = 0; | ||
359 | if (!evp_cipher(ctx, out, &len, in, inl)) | ||
340 | return 0; | 360 | return 0; |
341 | *outl += inl; | 361 | if (INT_MAX - len < total_len) |
362 | return 0; | ||
363 | total_len += len; | ||
342 | } | 364 | } |
343 | 365 | ||
344 | if (i != 0) | 366 | if (i != 0) |
345 | memcpy(ctx->buf, &(in[inl]), i); | 367 | memcpy(ctx->buf, &(in[inl]), i); |
346 | ctx->buf_len = i; | 368 | ctx->buf_len = i; |
369 | |||
370 | *outl = total_len; | ||
371 | |||
347 | return 1; | 372 | return 1; |
348 | } | 373 | } |
349 | 374 | ||
@@ -356,17 +381,13 @@ EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | |||
356 | int | 381 | int |
357 | EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | 382 | EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) |
358 | { | 383 | { |
359 | int n, ret; | 384 | int n; |
360 | unsigned int i, b, bl; | 385 | unsigned int i, b, bl; |
361 | 386 | ||
362 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { | 387 | *outl = 0; |
363 | ret = ctx->cipher->do_cipher(ctx, out, NULL, 0); | 388 | |
364 | if (ret < 0) | 389 | if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) |
365 | return 0; | 390 | return evp_cipher(ctx, out, outl, NULL, 0); |
366 | else | ||
367 | *outl = ret; | ||
368 | return 1; | ||
369 | } | ||
370 | 391 | ||
371 | b = ctx->cipher->block_size; | 392 | b = ctx->cipher->block_size; |
372 | if (b > sizeof ctx->buf) { | 393 | if (b > sizeof ctx->buf) { |
@@ -390,13 +411,8 @@ EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | |||
390 | n = b - bl; | 411 | n = b - bl; |
391 | for (i = bl; i < b; i++) | 412 | for (i = bl; i < b; i++) |
392 | ctx->buf[i] = n; | 413 | ctx->buf[i] = n; |
393 | ret = ctx->cipher->do_cipher(ctx, out, ctx->buf, b); | ||
394 | |||
395 | 414 | ||
396 | if (ret) | 415 | return evp_cipher(ctx, out, outl, ctx->buf, b); |
397 | *outl = b; | ||
398 | |||
399 | return ret; | ||
400 | } | 416 | } |
401 | 417 | ||
402 | int | 418 | int |
@@ -414,15 +430,8 @@ EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
414 | if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE) | 430 | if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE) |
415 | return 1; | 431 | return 1; |
416 | 432 | ||
417 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { | 433 | if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) |
418 | fix_len = ctx->cipher->do_cipher(ctx, out, in, inl); | 434 | return evp_cipher(ctx, out, outl, in, inl); |
419 | if (fix_len < 0) { | ||
420 | *outl = 0; | ||
421 | return 0; | ||
422 | } else | ||
423 | *outl = fix_len; | ||
424 | return 1; | ||
425 | } | ||
426 | 435 | ||
427 | if (ctx->flags & EVP_CIPH_NO_PADDING) | 436 | if (ctx->flags & EVP_CIPH_NO_PADDING) |
428 | return EVP_EncryptUpdate(ctx, out, outl, in, inl); | 437 | return EVP_EncryptUpdate(ctx, out, outl, in, inl); |
@@ -480,16 +489,11 @@ EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) | |||
480 | { | 489 | { |
481 | int i, n; | 490 | int i, n; |
482 | unsigned int b; | 491 | unsigned int b; |
492 | |||
483 | *outl = 0; | 493 | *outl = 0; |
484 | 494 | ||
485 | if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { | 495 | if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) |
486 | i = ctx->cipher->do_cipher(ctx, out, NULL, 0); | 496 | return evp_cipher(ctx, out, outl, NULL, 0); |
487 | if (i < 0) | ||
488 | return 0; | ||
489 | else | ||
490 | *outl = i; | ||
491 | return 1; | ||
492 | } | ||
493 | 497 | ||
494 | b = ctx->cipher->block_size; | 498 | b = ctx->cipher->block_size; |
495 | if (ctx->flags & EVP_CIPH_NO_PADDING) { | 499 | if (ctx->flags & EVP_CIPH_NO_PADDING) { |