Enhance VSM/HGS enclave session key binding validation - #4532
Conversation
There was a problem hiding this comment.
Pull request overview
Strengthens the Always Encrypted VSM/HGS enclave attestation flow by adding an explicit binding check between the signed enclave report (EnclaveData) and the enclave public key used during session establishment, ensuring the session cannot be established with a substituted key.
Changes:
- Adds SHA-256(public key) binding validation against the first 32 bytes of
Report.EnclaveDatain the VSM/HGS attestation path (with fixed-time comparison). - Introduces a .NET Framework-compatible fixed-time comparison helper for the key-binding check.
- Adds a new localized failure message and unit tests covering match/mismatch scenarios.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderTest.cs | Adds unit tests validating the new key-binding behavior via reflection. |
| src/Microsoft.Data.SqlClient/src/Resources/Strings.resx | Adds a dedicated localized error message for key-binding failures. |
| src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs | Adds the generated strongly-typed accessor for the new resource string. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs | Implements the binding check before shared secret derivation and adds a .NET Framework fixed-time compare helper. |
Files not reviewed (1)
- src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
🤖 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Generated file
Suppressed comments (4)
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs:349
- The XML doc says this validates the enclave’s Diffie-Hellman public key, but the value being hashed/validated here is the enclave identity public key (the same EnclavePublicKey used in GetSharedSecret/VerifyEnclaveDHInfo). This is misleading for future maintenance/debugging of the attestation flow.
/// <summary>
/// Verifies that the enclave's Diffie-Hellman public key is the one committed to by the signed
/// attestation report. A genuine VBS enclave writes SHA-256(public key) into the first 32 bytes of the
/// report's EnclaveData, and that EnclaveData is covered by the report signature that
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs:352
- The XML doc claims this binding ensures the key used to derive the session secret is committed by the attested enclave. In this path the identity public key is used to validate the enclave’s key-exchange (DH) data/signature rather than being the DH key itself, so the wording should reflect that.
/// <see cref="VerifyAttestationInfo"/> has already validated. Confirming this binding ensures the key used
/// to derive the session secret is the exact key the attested enclave committed to. This mirrors the
/// aas-ehd key binding performed on the AAS attestation path.
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderTest.cs:22
- The test hard-codes the EnclaveReportPackageHeader and EnclaveReport sizes (including a literal 152 for EnclaveIdentity). This is brittle if the production payload layout changes; since the test assembly has IVT access, prefer using the production SizeInPayload constants.
private const int EnclaveReportPackageHeaderSize = 6 * sizeof(uint); // 24
private const int EnclaveReportSize = (sizeof(uint) * 2) + 64 + 152; // ReportSize + ReportVersion + EnclaveData + EnclaveIdentity = 224
src/Microsoft.Data.SqlClient/src/Resources/Strings.resx:1973
- The new resource string uses plain spaces around “- see” / “for more details”, but nearby attestation strings consistently use the non-breaking spacing form (e.g., Strings.resx:1969). Aligning this avoids inconsistent rendering/wrapping in localized error text.
<data name="VerifyEnclaveKeyBindingFailed" xml:space="preserve">
<value>Enclave attestation failed because the signed enclave report did not bind to the enclave public key used to establish the session. The enclave public key must match the value committed to by the signed report - see https://go.microsoft.com/fwlink/?linkid=2160553 for more details. If correct, contact Customer Support Services.</value>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4532 +/- ##
==========================================
- Coverage 64.78% 62.92% -1.86%
==========================================
Files 288 283 -5
Lines 44418 67425 +23007
==========================================
+ Hits 28774 42428 +13654
- Misses 15644 24997 +9353
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
cheenamalhotra
left a comment
There was a problem hiding this comment.
Just noting, we need localized messages for this one, and also backporting them to respective release branches.
mdaigle
left a comment
There was a problem hiding this comment.
optional comment to remove reflection
| /// Thrown when the report's EnclaveData does not match SHA-256 of <paramref name="enclavePublicKey"/>, or | ||
| /// when the required report or key data is missing. In either case attestation is rejected. | ||
| /// </exception> | ||
| private void VerifyEnclavePublicKeyBinding(EnclaveReportPackage enclaveReportPackage, EnclavePublicKey enclavePublicKey) |
There was a problem hiding this comment.
Any harm in marking this as internal? then we can avoid reflection in the unit tests.
There was a problem hiding this comment.
Nope, no harm as far as I can tell - also no reason to not make it static, too.
Description
This change strengthens the Always Encrypted VSM/HGS enclave attestation flow by validating that the enclave public key used to establish the session is the same key committed to by the signed enclave report.
During enclave session setup, the provider now verifies that SHA-256(enclave public key) matches the value in the first 32 bytes of the report’s EnclaveData after attestation report verification and before deriving the shared secret. If the report data is missing, malformed, or does not match the session key, attestation is rejected with a dedicated error message.
Changes
Testing