feat(migtd): support tdinfo_init in MigtdMigrationInformation#825
Merged
Conversation
Contributor
|
LGTM, thanks |
adcbeb6 to
5b3dcba
Compare
Per GHCI 1.5, the VMM must put migpolicy.policy_key and migpolicy.policy_svn in TDINFO.MROWNER and TDINFO.MROWNERCONFIG respectively, and may provide initMigtdData in the StartMigration request for subsequent migrations. This change implements: a) Allow VMM to pass initMigtdData via the StartMigration request. MigtdMigrationInformation now has has_init_data field at offset 9 and the parser accepts variable-length payload with init data. b) MigTD startup self-check: verify that own TDINFO.MROWNER equals SHA384(policy signing public key) and TDINFO.MROWNERCONFIG equals own policy_svn. Reject with InvalidPolicyError on mismatch. c) Migration flow verification: when VMM provides initMigtdData, verify that initMigtdData.MROWNER matches own policy signer key hash and initMigtdData.MROWNERCONFIG <= own policy_svn before proceeding with key exchange. d) SPDM requester for migration uses VMM-provided initMigtdData (when available) instead of always generating local TDINFO, enabling correct attestation for non-initial migrations. Closes: intel#822 Signed-off-by: Michal Tarnacki <michal.tarnacki@intel.com> Co-authored-by: GitHub Copilot <noreply@github.com>
sgrams
approved these changes
May 14, 2026
sgrams
reviewed
May 14, 2026
| @@ -0,0 +1,120 @@ | |||
| // Copyright (c) 2025 Intel Corporation | |||
sgrams
approved these changes
May 14, 2026
haitaohuang
added a commit
to haitaohuang/MigTD
that referenced
this pull request
May 16, 2026
The cherry-picked Intel PR intel#825 doesn't compile on the Microsoft fork due to two differences in the fork's module layout: 1. main.rs uses 'panic_with_guest_crash_reg_report' but the Microsoft fork does not import it at the file scope (unlike intel/main which has 'use migtd::driver::vmcall_raw::panic_with_guest_crash_reg_report' at the top). Add the import inside the new cfg block where it is referenced. 2. mig_policy::verify_init_migtd_data_policy_binding references crate::migration::rebinding::InitData, but on this fork the 'rebinding' module is gated on all(feature = "main", feature = "policy_v2", feature = "vmcall-raw"). Gate the function on all(feature = "main", feature = "vmcall-raw") (policy_v2 is implied by the surrounding 'mod v2' block) so the lib still compiles in spdm_attestation + virtio-vsock + policy_v2 builds where rebinding is absent. Verified with cargo check on x86_64-unknown-none for feature combos: - main,stack-guard,vmcall-raw,policy_v2 - main,stack-guard,vmcall-raw - main,stack-guard,virtio-vsock - main,stack-guard,spdm_attestation,virtio-vsock,policy_v2 - main,stack-guard,spdm_attestation,vmcall-raw,policy_v2 - main,stack-guard,test_disable_ra_and_accept_all,vmcall-raw,policy_v2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Haitao Huang <haitaohuang@microsoft.com>
haitaohuang
added a commit
to haitaohuang/MigTD
that referenced
this pull request
May 16, 2026
Intel PR intel#825 added `mig_policy::verify_own_tdinfo()` (GHCI 1.5) which checks at startup that the running MigTD's TDINFO matches its policy: td_info.mrowner == SHA384(policy signer public key) td_info.mrownerconfig == policy_svn as u32 LE || [0u8; 44] These fields are normally provisioned by the host VMM. AzCVMEmu uses a hardcoded mock TDREPORT whose MROWNER/MROWNERCONFIG are zero, so the check would always fail under emulation and block all policy_v2 + mock-report tests. Skip the call site in main.rs when the `AzCVMEmu` feature is active: #[cfg(all(feature = "vmcall-raw", not(feature = "AzCVMEmu")))] `verify_own_tdinfo()` itself remains compiled under `vmcall-raw`, so real (non-emulator) builds still enforce the GHCI 1.5 binding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
haitaohuang
added a commit
to haitaohuang/MigTD
that referenced
this pull request
May 22, 2026
Intel PR intel#825 added `mig_policy::verify_own_tdinfo()` (GHCI 1.5) which checks at startup that the running MigTD's TDINFO matches its policy: td_info.mrowner == SHA384(policy signer public key) td_info.mrownerconfig == policy_svn as u32 LE || [0u8; 44] These fields are normally provisioned by the host VMM. AzCVMEmu uses a hardcoded mock TDREPORT whose MROWNER/MROWNERCONFIG are zero, so the check would always fail under emulation and block all policy_v2 + mock-report tests. Skip the call site in main.rs when the `AzCVMEmu` feature is active: #[cfg(all(feature = "vmcall-raw", not(feature = "AzCVMEmu")))] `verify_own_tdinfo()` itself remains compiled under `vmcall-raw`, so real (non-emulator) builds still enforce the GHCI 1.5 binding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
haitaohuang
added a commit
to haitaohuang/MigTD
that referenced
this pull request
May 23, 2026
Intel PR intel#825 added `mig_policy::verify_own_tdinfo()` (GHCI 1.5) which checks at startup that the running MigTD's TDINFO matches its policy: td_info.mrowner == SHA384(policy signer public key) td_info.mrownerconfig == policy_svn as u32 LE || [0u8; 44] These fields are normally provisioned by the host VMM. AzCVMEmu uses a hardcoded mock TDREPORT whose MROWNER/MROWNERCONFIG are zero, so the check would always fail under emulation and block all policy_v2 + mock-report tests. Skip the call site in main.rs when the `AzCVMEmu` feature is active: #[cfg(all(feature = "vmcall-raw", not(feature = "AzCVMEmu")))] `verify_own_tdinfo()` itself remains compiled under `vmcall-raw`, so real (non-emulator) builds still enforce the GHCI 1.5 binding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
haitaohuang
added a commit
to haitaohuang/MigTD
that referenced
this pull request
May 23, 2026
Intel PR intel#825 added `mig_policy::verify_own_tdinfo()` (GHCI 1.5) which checks at startup that the running MigTD's TDINFO matches its policy: td_info.mrowner == SHA384(policy signer public key) td_info.mrownerconfig == policy_svn as u32 LE || [0u8; 44] These fields are normally provisioned by the host VMM. AzCVMEmu uses a hardcoded mock TDREPORT whose MROWNER/MROWNERCONFIG are zero, so the check would always fail under emulation and block all policy_v2 + mock-report tests. Skip the call site in main.rs when the `AzCVMEmu` feature is active: #[cfg(all(feature = "vmcall-raw", not(feature = "AzCVMEmu")))] `verify_own_tdinfo()` itself remains compiled under `vmcall-raw`, so real (non-emulator) builds still enforce the GHCI 1.5 binding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Per GHCI 1.5, the VMM must put migpolicy.policy_key and migpolicy.policy_svn in TDINFO.MROWNER and TDINFO.MROWNERCONFIG respectively, and may provide initMigtdData in the StartMigration request for subsequent migrations.
This change implements:
a) Allow VMM to pass initMigtdData via the StartMigration request.
MigtdMigrationInformation now has has_init_data field at offset 9
and the parser accepts variable-length payload with init data.
b) MigTD startup self-check: verify that own TDINFO.MROWNER equals
SHA384(policy signing public key) and TDINFO.MROWNERCONFIG equals
own policy_svn. Reject with InvalidPolicyError on mismatch.
c) Migration flow verification: when VMM provides initMigtdData,
verify that initMigtdData.MROWNER matches own policy signer key
hash and initMigtdData.MROWNERCONFIG <= own policy_svn before
proceeding with key exchange.
d) SPDM requester for migration uses VMM-provided initMigtdData
(when available) instead of always generating local TDINFO,
enabling correct attestation for non-initial migrations.
Closes: #822 #823