|
| 1 | +From 3adfe1f39f64b4cde3b4c2b2f3c3a1bc50ad4ffe Mon Sep 17 00:00:00 2001 |
| 2 | +From: Norbert Pocs <norbertp@openssl.org> |
| 3 | +Date: Thu, 8 Jan 2026 15:04:54 +0100 |
| 4 | +Subject: [PATCH] Fix OCB AES-NI/HW stream path unauthenticated/unencrypted |
| 5 | + trailing bytes |
| 6 | +MIME-Version: 1.0 |
| 7 | +Content-Type: text/plain; charset=UTF-8 |
| 8 | +Content-Transfer-Encoding: 8bit |
| 9 | + |
| 10 | +When ctx->stream (e.g., AES‑NI or ARMv8 CE) is available, the fast path |
| 11 | +encrypts/decrypts full blocks but does not advance in/out pointers. The |
| 12 | +tail-handling code then operates on the base pointers, effectively reprocessing |
| 13 | +the beginning of the buffer while leaving the actual trailing bytes |
| 14 | +unencrypted (encryption) or using the wrong plaintext (decryption). The |
| 15 | +authentication checksum excludes the true tail. |
| 16 | + |
| 17 | +CVE-2025-69418 |
| 18 | + |
| 19 | +Fixes: https://github.com/openssl/srt/issues/58 |
| 20 | + |
| 21 | +Signed-off-by: Norbert Pocs <norbertp@openssl.org> |
| 22 | + |
| 23 | +Reviewed-by: Saša Nedvědický <sashan@openssl.org> |
| 24 | +Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org> |
| 25 | +Reviewed-by: Tomas Mraz <tomas@openssl.org> |
| 26 | +MergeDate: Mon Jan 26 19:48:35 2026 |
| 27 | +(cherry picked from commit be9375d5d45dfaf897b56ef148a0b58402491fcb) |
| 28 | +Signed-off-by: rpm-build <rpm-build> |
| 29 | +Upstream-reference: https://github.com/openssl/openssl/commit/52d23c86a54adab5ee9f80e48b242b52c4cc2347.patch |
| 30 | +--- |
| 31 | + .../Library/OpensslLib/openssl/crypto/modes/ocb128.c | 10 ++++++++-- |
| 32 | + 1 file changed, 8 insertions(+), 2 deletions(-) |
| 33 | + |
| 34 | +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c |
| 35 | +index b5202ba..95601da 100644 |
| 36 | +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c |
| 37 | ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c |
| 38 | +@@ -342,7 +342,7 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, |
| 39 | + |
| 40 | + if (num_blocks && all_num_blocks == (size_t)all_num_blocks |
| 41 | + && ctx->stream != NULL) { |
| 42 | +- size_t max_idx = 0, top = (size_t)all_num_blocks; |
| 43 | ++ size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0; |
| 44 | + |
| 45 | + /* |
| 46 | + * See how many L_{i} entries we need to process data at hand |
| 47 | +@@ -356,6 +356,9 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, |
| 48 | + ctx->stream(in, out, num_blocks, ctx->keyenc, |
| 49 | + (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c, |
| 50 | + (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c); |
| 51 | ++ processed_bytes = num_blocks * 16; |
| 52 | ++ in += processed_bytes; |
| 53 | ++ out += processed_bytes; |
| 54 | + } else { |
| 55 | + /* Loop through all full blocks to be encrypted */ |
| 56 | + for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) { |
| 57 | +@@ -434,7 +437,7 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, |
| 58 | + |
| 59 | + if (num_blocks && all_num_blocks == (size_t)all_num_blocks |
| 60 | + && ctx->stream != NULL) { |
| 61 | +- size_t max_idx = 0, top = (size_t)all_num_blocks; |
| 62 | ++ size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0; |
| 63 | + |
| 64 | + /* |
| 65 | + * See how many L_{i} entries we need to process data at hand |
| 66 | +@@ -448,6 +451,9 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, |
| 67 | + ctx->stream(in, out, num_blocks, ctx->keydec, |
| 68 | + (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c, |
| 69 | + (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c); |
| 70 | ++ processed_bytes = num_blocks * 16; |
| 71 | ++ in += processed_bytes; |
| 72 | ++ out += processed_bytes; |
| 73 | + } else { |
| 74 | + OCB_BLOCK tmp; |
| 75 | + |
| 76 | +-- |
| 77 | +2.45.4 |
| 78 | + |
0 commit comments