You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a permanent ~5-8% regression likely caused by dotnet/runtime#120769 (there was some noise here too but consistently getting 5% or 8% depending on which scenario you test). @vcsjones in case you have ideas for how to fix the regression, or if this is something we expected and have to live with.
It's a bit hard to narrow the commit range here because there was ~1 week of no builds from the VMR at this time, but dotnet/runtime#120769 is the most likely candidate since it affects hashing.
It's possible that PR introduced a regression in HMAC depending on how you are using it. Unfortunately I don't know that there is much we can do about it - this PR was an effort to move us off of deprecated OpenSSL APIs onto supported ones, and the deprecated ones are not FIPS compliant, which was the motivating factor to get off of the old ones.
If you are using instance based HMAC, either by creating instances HMACSHA123 or IncrementalHash, you are using the new OpenSSL APIs.
If you are using one-shots, like HMACSHA512.HashData then you are not using new OpenSSL APIs as the one-shots moved years ago.
Some questions
Where is the actual source for the benchmark?
What OS and Target Framework are the benchmarks for?
What version of OpenSSL is on the box?
Some ways to win some back perf
Use the SP800108HmacCounterKdf that is built in to the runtime (and consider using Microsoft.Bcl.Cryptography for downlevel support as well) inside of DataProtection, if that is in the anti-forgery path.
Test against OpenSSL 3.5, if possible. If the benchmarks are being done against OpenSSL 3.0, it's possible it got better in 3.3 or later.
Use IncrementalHash instead of new HMACSHA256() or new HMACSHA512(). The latter two do a little extra bookkeeping that IncrementalHash does not need to.
What OS and Target Framework are the benchmarks for?
Linux, 11.0.
What version of OpenSSL is on the box?
I'll need to check on that.
Use the SP800108HmacCounterKdf that is built in to the runtime (and consider using Microsoft.Bcl.Cryptography for downlevel support as well) inside of DataProtection, if that is in the anti-forgery path.
Looks like you made that comment before and it was claimed to be slow. #59424 (review)
AI summary from looking at traces of before and after (I can also provide the traces offline if interested):
Module-Level CPU Shift
Module
Baseline
Experiment
Δ
System.Security.Cryptography
5.3%
13.8%
+8.5% ❌
Interop+Crypto (P/Invoke wrappers)
0.5%
7.6%
+7.1% ❌
[Native/Unknown] (unresolved native)
6.6%
0%
−6.6% ✅ (now attributed)
Microsoft.AspNetCore.DataProtection
4.4%
4.6%
same
The [Native/Unknown] category in baseline = the old lean HMAC_* native calls that the profiler couldn't attribute to
managed frames. In the experiment, those native calls now route through more managed wrapper code in Interop+Crypto,
making them visible but slower.
The old HMAC_* path was a single lean native call (6.6% total, unresolvable). The new EVP_MAC path decomposes into:
More managed-native transitions — HmacOneShot wraps EVP_MAC_CTX_new + EVP_MAC_init + EVP_MAC_update +
EVP_MAC_final + EVP_MAC_CTX_free into one call, but with more marshalling
Activity
sebastienros commentedon Apr 30, 2026
@DeagleGross
BrennanConroy commentedon May 13, 2026
There is a permanent ~5-8% regression likely caused by dotnet/runtime#120769 (there was some noise here too but consistently getting 5% or 8% depending on which scenario you test). @vcsjones in case you have ideas for how to fix the regression, or if this is something we expected and have to live with.
It's a bit hard to narrow the commit range here because there was ~1 week of no builds from the VMR at this time, but dotnet/runtime#120769 is the most likely candidate since it affects hashing.
vcsjones commentedon May 13, 2026
It's possible that PR introduced a regression in HMAC depending on how you are using it. Unfortunately I don't know that there is much we can do about it - this PR was an effort to move us off of deprecated OpenSSL APIs onto supported ones, and the deprecated ones are not FIPS compliant, which was the motivating factor to get off of the old ones.
IncrementalHash, you are using the new OpenSSL APIs.HMACSHA512.HashDatathen you are not using new OpenSSL APIs as the one-shots moved years ago.Some questions
Some ways to win some back perf
SP800108HmacCounterKdfthat is built in to the runtime (and consider using Microsoft.Bcl.Cryptography for downlevel support as well) inside of DataProtection, if that is in the anti-forgery path.IncrementalHashinstead ofnew HMACSHA256()ornew HMACSHA512(). The latter two do a little extra bookkeeping thatIncrementalHashdoes not need to.BrennanConroy commentedon May 13, 2026
The actual source for the benchmark is at https://github.com/aspnet/Benchmarks/blob/main/src/BenchmarksApps/Antiforgery/Program.cs although that's not particularly interesting.
https://github.com/dotnet/aspnetcore/blob/main/src/DataProtection/DataProtection/src/SP800_108/ManagedSP800_108_CTR_HMACSHA512.cs#L69 is probably more interesting as that's the callsite for hmac.
Linux, 11.0.
I'll need to check on that.
Looks like you made that comment before and it was claimed to be slow. #59424 (review)
AI summary from looking at traces of before and after (I can also provide the traces offline if interested):
Module-Level CPU Shift
The [Native/Unknown] category in baseline = the old lean HMAC_* native calls that the profiler couldn't attribute to
managed frames. In the experiment, those native calls now route through more managed wrapper code in Interop+Crypto,
making them visible but slower.
ManagedAuthenticatedEncryptor.Encrypt — Caller-Callee Comparison
Inclusive time: 15.6% → 17.8% (+2.2 percentage points = +8.8% relative)
Root Cause Breakdown
The old HMAC_* path was a single lean native call (6.6% total, unresolvable). The new EVP_MAC path decomposes into:
EVP_MAC_final + EVP_MAC_CTX_free into one call, but with more marshalling
string-based algorithm resolution)
vcsjones commentedon May 13, 2026
It's possible it's faster than what EVP_MAC provides now. It's also FIPS compliant. Hand-rolling SP800-108 / KBKDF is not FIPS compliant.
I don't understand this. The one shots have not changed from that
dotnet/runtimePR.