Don't copy buffers for low-risk PSA operations #795

Open
opened 2026-05-28 07:44:29 -05:00 by gilles-peskine-arm · 0 comments
gilles-peskine-arm commented 2026-05-28 07:44:29 -05:00 (Migrated from github.com)

The compilation option MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS has advantages and downsides:

  • Without it, PSA API functions allocate intermediate buffers on the heap. This increases memory requirements and is a point of failure.
  • Without it, some PSA API functions do not handle overlap of input and output buffers correctly.
  • Without it, some PSA API functions are insecure if their input or output buffers are in shared memory (as is the case in client-server builds of PSA crypto). The risk is that the implementation of the algorithm may read the same input fragment multiple times (an untrusted client may have changed it), or may write intermediate values to the output buffer (where an untrusted client may read or change it).

We added this use of intermediate buffers to solve the security issue in Mbed TLS 3.6.0. (Fixing bugs with overlapping buffers was a welcome side effect.) Due to a lack of time, we made it systematic.

The goal of this issue is to stop using intermediate buffers for some functions where there is no practical security risk and no problem with buffer overlap. Going by operation type:

  • Hash: no risk. There is no plausible hash implementation that would process a given byte of input more than once, or that would do anything with the output buffer other than writing the final result.
  • MAC: no risk. There is no plausible hash implementation that would process a given byte of input more than once. There may be plausible implementations that use store a temporary value in the output buffer, but that wouldn't work if the buffer is only large enough for a truncated MAC, which we do support, so we use an internal buffer for the untruncated output from the underlying algorithm anyway.
  • cipher: risky. There are definitely problems with overlap of input and output buffers.
  • AEAD: risky. There are definitely problems with overlap of input and output buffers. When decrypting, releasing unauthenticated candidate plaintext may be a concern in some cases.
  • Signature: risky. Some algorithms may process the input multiple times. Our low-level RSA code writes an intermediate value in its output buffer before applying the public-key or private-key transformation.
  • Asymmetric encryption/decryption: risky. Some algorithms may process the input multiple times. Our low-level RSA code writes an intermediate value in its output buffer before applying the public-key or private-key transformation.
  • Key derivation: risky. Each API functions only take one input or one output buffer at most. There is no risk of using the output buffer for temporary values since it is variable-size. However, for some algorithms, there might be a temptation to read the input more than once.
  • PAKE: I'm not sure, so if in doubt, risky.
  • XOF: no risk. Similar to hashes.

This is both an optimization and a risk reduction (fewer failures to handle), so as discussed internally, we will also do this in LTS branches.

Out of scope:

  • Improvements to scripts related to test wrappers. Tracked in https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/701.
  • Test improvements. We'll just stop doing buffer sharing tests for the selected functions.
  • Per-buffer or even per-function choice. Here we're only doing whole categories.
The compilation option `MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS` has advantages and downsides: * Without it, PSA API functions allocate intermediate buffers on the heap. This increases memory requirements and is a point of failure. * Without it, some PSA API functions do not handle overlap of input and output buffers correctly. * Without it, some PSA API functions are insecure if their input or output buffers are in shared memory (as is the case in client-server builds of PSA crypto). The risk is that the implementation of the algorithm may read the same input fragment multiple times (an untrusted client may have changed it), or may write intermediate values to the output buffer (where an untrusted client may read or change it). We added this use of intermediate buffers to solve the security issue in Mbed TLS 3.6.0. (Fixing bugs with overlapping buffers was a welcome side effect.) Due to a lack of time, we made it systematic. The goal of this issue is to stop using intermediate buffers for some functions where there is no practical security risk and no problem with buffer overlap. Going by operation type: * **Hash**: no risk. There is no plausible hash implementation that would process a given byte of input more than once, or that would do anything with the output buffer other than writing the final result. * **MAC**: no risk. There is no plausible hash implementation that would process a given byte of input more than once. There may be plausible implementations that use store a temporary value in the output buffer, but that wouldn't work if the buffer is only large enough for a truncated MAC, which we do support, so we use an internal buffer for the untruncated output from the underlying algorithm anyway. * cipher: risky. There are definitely problems with overlap of input and output buffers. * AEAD: risky. There are definitely problems with overlap of input and output buffers. When decrypting, releasing unauthenticated candidate plaintext may be a concern in some cases. * Signature: risky. Some algorithms may process the input multiple times. Our low-level RSA code writes an intermediate value in its output buffer before applying the public-key or private-key transformation. * Asymmetric encryption/decryption: risky. Some algorithms may process the input multiple times. Our low-level RSA code writes an intermediate value in its output buffer before applying the public-key or private-key transformation. * Key derivation: risky. Each API functions only take one input or one output buffer at most. There is no risk of using the output buffer for temporary values since it is variable-size. However, for some algorithms, there might be a temptation to read the input more than once. * PAKE: I'm not sure, so if in doubt, risky. * **XOF**: no risk. Similar to hashes. This is both an optimization and a risk reduction (fewer failures to handle), so as discussed internally, we will also do this in LTS branches. Out of scope: * Improvements to scripts related to test wrappers. Tracked in https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/701. * Test improvements. We'll just stop doing buffer sharing tests for the selected functions. * Per-buffer or even per-function choice. Here we're only doing whole categories.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-Mbed-TLS/TF-PSA-Crypto#795
No description provided.