Skip to content

Commit a758923

Browse files
jogmet8m
authored andcommitted
Fix OCB AES-NI/HW stream path unauthenticated/unencrypted trailing bytes
When ctx->stream (e.g., AES‑NI or ARMv8 CE) is available, the fast path encrypts/decrypts full blocks but does not advance in/out pointers. The tail-handling code then operates on the base pointers, effectively reprocessing the beginning of the buffer while leaving the actual trailing bytes unencrypted (encryption) or using the wrong plaintext (decryption). The authentication checksum excludes the true tail. CVE-2025-69418 Fixes: openssl/srt#58 Signed-off-by: Norbert Pocs <norbertp@openssl.org> Reviewed-by: Saša Nedvědický <sashan@openssl.org> Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> MergeDate: Mon Jan 26 19:48:35 2026 (cherry picked from commit be9375d)
1 parent 3ed1f75 commit a758923

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

‎crypto/modes/ocb128.c‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
337337

338338
if (num_blocks && all_num_blocks == (size_t)all_num_blocks
339339
&& ctx->stream != NULL) {
340-
size_t max_idx = 0, top = (size_t)all_num_blocks;
340+
size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0;
341341

342342
/*
343343
* See how many L_{i} entries we need to process data at hand
@@ -351,6 +351,9 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
351351
ctx->stream(in, out, num_blocks, ctx->keyenc,
352352
(size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,
353353
(const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);
354+
processed_bytes = num_blocks * 16;
355+
in += processed_bytes;
356+
out += processed_bytes;
354357
} else {
355358
/* Loop through all full blocks to be encrypted */
356359
for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) {
@@ -429,7 +432,7 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
429432

430433
if (num_blocks && all_num_blocks == (size_t)all_num_blocks
431434
&& ctx->stream != NULL) {
432-
size_t max_idx = 0, top = (size_t)all_num_blocks;
435+
size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0;
433436

434437
/*
435438
* See how many L_{i} entries we need to process data at hand
@@ -443,6 +446,9 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
443446
ctx->stream(in, out, num_blocks, ctx->keydec,
444447
(size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,
445448
(const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);
449+
processed_bytes = num_blocks * 16;
450+
in += processed_bytes;
451+
out += processed_bytes;
446452
} else {
447453
OCB_BLOCK tmp;
448454

0 commit comments

Comments
 (0)