Backport FIPS compliance fix for ManagedAuthenticatedEncryptor to release/10.0#65322
Backport FIPS compliance fix for ManagedAuthenticatedEncryptor to release/10.0#65322Copilot wants to merge 2 commits intorelease/10.0from
Conversation
…A512 Co-authored-by: DeagleGross <31598696+DeagleGross@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR backports a critical FIPS compliance fix from main to release/10.0. The fix addresses a regression in .NET 10 where ASP.NET Core Data Protection APIs fail with cryptographic errors when FIPS mode is enabled on Ubuntu 22.04. The issue stems from an optimization introduced in PR #59424 that uses HMACSHA512.TryHashData, which fails in FIPS mode when the key is shorter than 14 bytes (112 bits - the FIPS minimum).
Changes:
- Modified
ManagedSP800_108_CTR_HMACSHA512.DeriveKeysto pad keys shorter than 14 bytes with zeros before callingHMACSHA512.TryHashData - Added a test case to verify the fix works with empty KDK (the primary problematic scenario in
CreateContextHeader())
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/DataProtection/DataProtection/src/SP800_108/ManagedSP800_108_CTR_HMACSHA512.cs | Implements FIPS-compliant key padding logic for keys shorter than 14 bytes, ensuring compatibility with FIPS-enabled environments |
| src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SP800_108/SP800_108Tests.cs | Adds test coverage for the empty KDK scenario that triggers the FIPS issue during context header creation |
| // When you provide a key to HMAC that is shorter than the algorithm's internal block size, | ||
| // the HMAC algorithm internally pads the key with zeros to reach the block size. |
There was a problem hiding this comment.
The comment states that HMAC pads keys to "reach the block size," but this is somewhat imprecise in this context. HMAC internally pads keys shorter than the block size (128 bytes for HMACSHA512) with zeros. However, the 14-byte padding here is specifically to meet the FIPS minimum key length requirement (112 bits), not to reach the HMAC block size. Consider clarifying that this padding is to meet the FIPS minimum requirement, and that HMAC will subsequently pad to its block size internally.
| // When you provide a key to HMAC that is shorter than the algorithm's internal block size, | |
| // the HMAC algorithm internally pads the key with zeros to reach the block size. | |
| // For FIPS-compliant scenarios, ensure the key is at least 112 bits (FipsMinimumKeyLengthInBytes). | |
| // HMACSHA512 will then internally pad this key up to its block size (128 bytes) as part of its algorithm. |
| public void DeriveKeys_EmptyKdk_Managed_ShouldSucceed(int numDerivedBytes, string expectedDerivedSubkeyAsBase64) | ||
| { | ||
| // Arrange - this mimics CreateContextHeader() behavior | ||
| byte[] kdk = Array.Empty<byte>(); | ||
| byte[] label = Array.Empty<byte>(); | ||
| byte[] contextHeader = Array.Empty<byte>(); | ||
| byte[] context = Array.Empty<byte>(); | ||
|
|
||
| // Act | ||
| var derivedSubkey = new byte[numDerivedBytes]; | ||
| ManagedSP800_108_CTR_HMACSHA512.DeriveKeys( | ||
| kdk: kdk, | ||
| label: label, | ||
| contextHeader: contextHeader, | ||
| contextData: context, | ||
| operationSubkey: derivedSubkey.AsSpan(0, numDerivedBytes / 2), | ||
| validationSubkey: derivedSubkey.AsSpan(numDerivedBytes / 2)); | ||
|
|
||
| // Assert | ||
| Assert.Equal(expectedDerivedSubkeyAsBase64, Convert.ToBase64String(derivedSubkey)); | ||
| } |
There was a problem hiding this comment.
Consider adding test cases for boundary conditions around the FIPS minimum key length. For example, test with a KDK of exactly 13 bytes (just below the threshold) and 14 bytes (at the threshold) to ensure the padding logic and threshold check work correctly. While the empty array case is the primary concern for CreateContextHeader, testing these boundaries would increase confidence in the fix.
|
Hi @@copilot. This PR was just approved to be included in the upcoming servicing release. Somebody from the @dotnet/aspnet-build team will get it merged when the branches are open. Until then, please make sure all the CI checks pass and the PR is reviewed. |
Backport FIPS compliance fix for ManagedAuthenticatedEncryptor to release/10.0
Description
Backporting #65186 to release/net10.0.
ASP.NET Core applications that use the Data Protection APIs (e.g. by using the session middleware), fail with cryptographic operation errors on Ubuntu 22.04 if FIPS mode is enabled. The same code works fine with .NET 8.
NET10 Stack trace:
In NET10 we have optimized the paths for
ManagedAuthenticatedEncryptorand started usingHMACSHA512.TryHashDatawhich apparently in the FIPS environment fails with exception when kdk provided is less than 14 bytes.Customer Impact
If DataProtection's
ManagedAuthenticatedEncryptoris used in FIPS environment, it will throw an exception on the initialization.Regression?
Risk
Only FIPS environment impacted; clear message and no flaky behavior; known mitigation of using lower dotnet version.
Verification
Packaging changes reviewed?