Bug 2462011 (CVE-2026-71225)

Summary: CVE-2026-71225 libkcapi: IV reuse in libkcapi one-shot symmetric cipher chunking causes cipher state reset across chunk boundaries
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: akhatavk, aos-team-art-private, asdas, dpaolell, jdelft, jupierce, lgarciaa, mbiarnes, ppalepu, ppostler, prdhamdh, rhel-process-autobot, security-response-team, sghai, sidsharm, suppawar, vlaad, watson-tool-maintainers
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in libkcapi. When performing one-shot symmetric cipher operations on large inputs (over 64 KiB) in stateful modes such as Counter (CTR) or Cipher Block Chaining (CBC), the library improperly reuses the Initialization Vector (IV) for each internal data chunk. A remote attacker could potentially exploit this by making an application that uses libkcapi process specially crafted large inputs. This can lead to a significant weakening of data confidentiality, as the repeated IV use can expose relationships in encrypted plaintext, and may also affect data integrity by causing incorrect cryptographic processing.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 2511445    
Bug Blocks:    

Description OSIDB Bzimport 2026-04-26 18:00:55 UTC
AI_ONLY_REPORT
package: libkcapi-1.5.0-3.el10
------
Summary: IV Reuse in Symmetric Cipher Chunking: large one-shot symmetric  
cipher operations can resend the original IV for each internal chunk,  
restarting cipher state and breaking expected continuous-message behavior.
Requirements to exploit: An attacker must be able to make an application  
using `libkcapi-1.5.0-3.el10` call the one-shot symmetric cipher APIs on  
data larger than `sysconf(_SC_PAGESIZE) * ALG_MAX_PAGES` (typically 64 KiB)  
in an affected stateful mode such as `ctr` or `cbc`, and observe the  
resulting ciphertext or decryption behavior. Reachability depends on the  
consuming application; the available evidence does not establish that every  
deployment exposes this path.
Component affected: `libkcapi-1.5.0-3.el10`, `lib/kcapi-sym.c`,  
`lib/kcapi-kernel-if.c`, one-shot symmetric cipher path  
(`kcapi_cipher_encrypt`, `kcapi_cipher_decrypt`,  
`_kcapi_cipher_crypt_chunk`, `_kcapi_common_send_meta`)
Version affected: `libkcapi-1.5.0-3.el10`
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
CVSS: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - 6.8 (MEDIUM)
AV:N - In the worst-case deployment, a remote caller can trigger the  
affected one-shot API through a network-facing application that uses this  
library for large-buffer encryption or decryption.
AC:H - Exploitation depends on specific application behavior: the  
one-shot path must be used, the input must cross the internal chunk  
threshold, and the mode must be one whose security depends on continuous  
IV/chaining state.
PR:N - No privileges are inherent to the flaw itself.
UI:N - No user interaction is required once the application processes  
the crafted large input.
S:U - The impact remains within the vulnerable cryptographic operation  
and does not cross a separate security boundary.
C:H - For `ctr`, restarting the keystream at chunk boundaries can  
expose plaintext relationships and materially weaken confidentiality.
I:L - Resetting state across chunk boundaries can cause applications to  
process data with different cryptographic semantics than a continuous  
message, which can affect integrity expectations in some uses.
A:N - No direct availability impact is established from the available  
evidence.
Impact: Moderate. Based on Red Hat severity guidance, this flaw can cause a  
meaningful confidentiality loss or cryptographic semantic break in  
applications that use the affected large-buffer one-shot path, but  
exploitation depends on specific API usage patterns and affected modes  
rather than presenting an easily exploitable default remote compromise path  
in this SRPM package.
Embargo: no
Reason: The currently supported impact is use-dependent, practical  
mitigations exist, and the available evidence does not show an easily  
weaponized default exposure that would normally justify embargo handling.
Acknowledgement: Aisle Research
Vulnerability Details: The one-shot symmetric cipher entry points store the  
caller-provided IV once and then pass the request into  
`_kcapi_cipher_crypt_chunk()`. For inputs larger than `handle->pagesize *  
ALG_MAX_PAGES`, `_kcapi_cipher_crypt_chunk()` splits the request into  
multiple chunks and calls `_kcapi_cipher_crypt()` for each chunk. Each  
`_kcapi_cipher_crypt()` call sends fresh operation metadata, and  
`_kcapi_common_send_meta()` copies `handle->cipher.iv` into `ALG_SET_IV`  
every time. No IV advancement is visible between chunks, so each chunk is  
processed as a new operation with the same IV instead of as a continuation  
of one message.
```c
handle->cipher.iv = iv;
return _kcapi_cipher_crypt_chunk(handle, in, inlen, out, outlen, access,  
ALG_OP_ENCRYPT /* or DECRYPT */);
```
```c
while (inlen && outlen) {
...
ret = _kcapi_cipher_crypt(handle, in, inprocess, out, outprocess,  
access, enc);
...
}
```
```c
if (handle->cipher.iv) {
...
memcpy(alg_iv->iv, handle->cipher.iv, tfm->info.ivsize);
}
```
For `ctr`, this restarts the keystream at each chunk boundary and can  
expose plaintext relationships across chunks. For `cbc`, the chaining  
value is reset at each boundary, so large one-shot processing no longer  
matches the behavior of one continuous CBC message. Based on the available  
evidence, this report is limited to the one-shot symmetric cipher path  
described above.
Steps to reproduce:
1. Initialize a `ctr(aes)` handle and set the key.
2. Prepare `131072` bytes of plaintext, with block `0` identical to the  
block at offset `65536`.
3. Encrypt the buffer with the one-shot API `kcapi_cipher_encrypt()` using  
a fixed IV.
4. Encrypt the same plaintext as one continuous message using  
`kcapi_cipher_stream_init_enc()`, repeated `kcapi_cipher_stream_update()`,  
`kcapi_cipher_stream_update_last()`, and `kcapi_cipher_stream_op()`.
5. Compare the outputs. The observed condition is `out_oneshot !=  
out_stream`, even though both operations are intended to represent the same  
continuous-message semantics.
6. For `ctr(aes)`, verify that `out_oneshot[0:16] ==  
out_oneshot[65536:65552]` when the corresponding plaintext blocks are  
equal. This indicates keystream restart at the chunk boundary.
7. Repeat with `cbc(aes)` and observe a mismatch versus the  
continuous-stream result at the chunk boundary.
Mitigation: Until a fix is available, avoid using the one-shot symmetric  
cipher APIs for inputs larger than `sysconf(_SC_PAGESIZE) * ALG_MAX_PAGES`  
when continuous-message semantics matter. Prefer the streaming interface  
for long messages, or keep one-shot inputs below the internal chunking  
threshold so the IV is applied only once per operation.
Proposed Fix: Send operation metadata and IV only for the first internal  
chunk, then keep the AF_ALG operation open and send only data for  
subsequent chunks so cipher state is preserved across the full message.
```diff
diff --git a/lib/kcapi-kernel-if.c b/lib/kcapi-kernel-if.c
@@
ssize_t _kcapi_cipher_crypt_chunk(struct kcapi_handle *handle,
const uint8_t *in, size_t inlen,
uint8_t *out, size_t outlen,
int access, unsigned int enc)
{
+    bool first = true;
ssize_t totallen = 0;
@@
while (inlen && outlen) {
size_t inprocess = inlen;
size_t outprocess = outlen;
+        bool last;
+        struct iovec iov;
@@
if (inlen > maxprocess)
inprocess = maxprocess;
if (outlen > maxprocess)
outprocess = maxprocess;
+        last = (inlen <= maxprocess);
       ret = _kcapi_cipher_crypt(handle, in, inprocess, out, outprocess,  
access, enc);
+        if (first) {
+            if ((access == KCAPI_ACCESS_HEURISTIC && inprocess <= (1<<13))  
||
+                access == KCAPI_ACCESS_SENDMSG) {
+                iov.iov_base = (void *)(uintptr_t)in;
+                iov.iov_len = inprocess;
+                ret = _kcapi_common_send_meta(handle, &iov, 1, enc, last ?  
0 : MSG_MORE);
+            } else {
+                ret = _kcapi_common_send_meta(handle, NULL, 0, enc,  
MSG_MORE);
+                if (ret >= 0)
+                    ret = _kcapi_common_vmsplice_chunk(handle, in,  
inprocess,
+                                                       last ? 0 :  
SPLICE_F_MORE);
+            }
+            first = false;
+        } else {
+            if ((access == KCAPI_ACCESS_HEURISTIC && inprocess <= (1<<13))  
||
+                access == KCAPI_ACCESS_SENDMSG) {
+                iov.iov_base = (void *)(uintptr_t)in;
+                iov.iov_len = inprocess;
+                ret = _kcapi_common_send_data(handle, &iov, 1, last ? 0 :  
MSG_MORE);
+            } else {
+                ret = _kcapi_common_vmsplice_chunk(handle, in, inprocess,
+                                                   last ? 0 :  
SPLICE_F_MORE);
+            }
+        }
          if (ret < 0)
              return ret;
+        ret = _kcapi_common_read_data(handle, out, outprocess);
+        if (ret < 0)
+            return ret;
@@
      }
      return totallen;
  }
```


------
This report was generated using AI technology. Always review AI-generated  
content prior to use