Explain why RSA PKCS1 implicit rejection isn't used#126887
Explain why RSA PKCS1 implicit rejection isn't used#126887PranavSenthilnathan wants to merge 1 commit intodotnet:mainfrom
Conversation
|
Tagging subscribers to this area: @bartonjs, @vcsjones, @dotnet/area-system-security |
There was a problem hiding this comment.
Pull request overview
Expands the in-source documentation in the OpenSSL RSA interop layer to explain why .NET disables OpenSSL’s PKCS#1 RSA “implicit rejection” behavior (and attempts to turn it off via rsa_pkcs1_implicit_rejection).
Changes:
- Replaces the existing brief explanation with a more detailed comment describing OpenSSL’s implicit rejection behavior and the motivation for disabling it.
- Adds additional rationale bullets covering compatibility/spec alignment and security considerations.
| // padding (software keys only), OpenSSL synthesizes a deterministic random value derived from the | ||
| // private key and ciphertext, leaving callers to handle it with constant-time comparison. This | ||
| // was intended to mitigate Bleichenbacher-style padding oracle attacks. |
There was a problem hiding this comment.
I feel like it's understandable in context.
| // was intended to mitigate Bleichenbacher-style padding oracle attacks. | ||
| // | ||
| // Some Linux distributions (notably CentOS/RHEL via Red Hat backports) applied this change to | ||
| // earlier OpenSSL versions (e.g. 3.1), which broke some .NET tests. | ||
| // | ||
| // We disable this feature ("implicit rejection") for several reasons: | ||
| // 1. Platform consistency: other platforms (Windows, macOS) and hardware-backed keys still | ||
| // return explicit errors; callers should see the same behavior everywhere. | ||
| // 2. It deviates from RSA specifications and OpenSSL itself had to disable it to pass FIPS | ||
| // conformance tests. | ||
| // 3. It broke OpenSSL's own CMS (EnvelopedCMS) implementation, so OpenSSL turns it off | ||
| // internally when doing CMS operations. | ||
| // 4. It does not fully solve the Bleichenbacher problem; it converts a "FFT" oracle into a | ||
| // "FFF" oracle. While FFF is ~1000x harder to exploit, the attack is not eliminated. | ||
| // | ||
| // Therefore we revert to the prior behavior: invalid padding produces an explicit error code | ||
| // and .NET throws an exception. This is a best-effort flag; if the running OpenSSL version does | ||
| // not recognize it, we silently ignore the failure (see ERR_set_mark / ERR_pop_to_mark below). |
There was a problem hiding this comment.
I disagree with Copilot's suggestion.
| // was intended to mitigate Bleichenbacher-style padding oracle attacks. | ||
| // | ||
| // Some Linux distributions (notably CentOS/RHEL via Red Hat backports) applied this change to | ||
| // earlier OpenSSL versions (e.g. 3.1), which broke some .NET tests. |
There was a problem hiding this comment.
I disagree with Copilot's suggestion.
| // was intended to mitigate Bleichenbacher-style padding oracle attacks. | ||
| // | ||
| // Some Linux distributions (notably CentOS/RHEL via Red Hat backports) applied this change to | ||
| // earlier OpenSSL versions (e.g. 3.1), which broke some .NET tests. | ||
| // | ||
| // We disable this feature ("implicit rejection") for several reasons: | ||
| // 1. Platform consistency: other platforms (Windows, macOS) and hardware-backed keys still | ||
| // return explicit errors; callers should see the same behavior everywhere. | ||
| // 2. It deviates from RSA specifications and OpenSSL itself had to disable it to pass FIPS | ||
| // conformance tests. | ||
| // 3. It broke OpenSSL's own CMS (EnvelopedCMS) implementation, so OpenSSL turns it off | ||
| // internally when doing CMS operations. | ||
| // 4. It does not fully solve the Bleichenbacher problem; it converts a "FFT" oracle into a | ||
| // "FFF" oracle. While FFF is ~1000x harder to exploit, the attack is not eliminated. | ||
| // | ||
| // Therefore we revert to the prior behavior: invalid padding produces an explicit error code | ||
| // and .NET throws an exception. This is a best-effort flag; if the running OpenSSL version does | ||
| // not recognize it, we silently ignore the failure (see ERR_set_mark / ERR_pop_to_mark below). |
There was a problem hiding this comment.
I disagree with Copilot's suggestion.
| // was intended to mitigate Bleichenbacher-style padding oracle attacks. | ||
| // | ||
| // Some Linux distributions (notably CentOS/RHEL via Red Hat backports) applied this change to | ||
| // earlier OpenSSL versions (e.g. 3.1), which broke some .NET tests. |
There was a problem hiding this comment.
I disagree with Copilot's suggestion.
| // padding (software keys only), OpenSSL synthesizes a deterministic random value derived from the | ||
| // private key and ciphertext, leaving callers to handle it with constant-time comparison. This | ||
| // was intended to mitigate Bleichenbacher-style padding oracle attacks. |
There was a problem hiding this comment.
I feel like it's understandable in context.
Expands comments on why we don't use implicit rejection for RSA PKCS#1.