Igvmfilegen: Support CoRIM generation and patch command#3088
Igvmfilegen: Support CoRIM generation and patch command#3088mingweishih wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds CoRIM (Concise Reference Integrity Manifest) patching/extraction capabilities to igvmfilegen, enabling post-build injection of CoRIM document/signature data into an existing IGVM file (including support for splitting bundled COSE_Sign1 inputs).
Changes:
- Add new
DumpCorimandPatchCorimCLI subcommands to inspect and patch CoRIM headers in IGVM files. - Introduce a new
corimmodule implementing IGVM directive patching plus minimal COSE_Sign1 split/validation utilities (with unit tests). - Switch
igvm/igvm_defsworkspace deps to a git fork/branch that includes the required CoRIM header support.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| vm/loader/igvmfilegen/src/main.rs | Adds new CLI commands and implements CoRIM header dumping/patching entrypoints. |
| vm/loader/igvmfilegen/src/corim/mod.rs | Adds IGVM-level CoRIM patching logic and compatibility-mask helpers. |
| vm/loader/igvmfilegen/src/corim/cose.rs | Adds COSE_Sign1 parsing/splitting/validation helpers plus unit tests. |
| vm/loader/igvmfilegen/Cargo.toml | Adds open_enum dependency for the new COSE/CBOR helpers. |
| Cargo.toml | Switches igvm and igvm_defs from crates.io to a git fork/branch. |
| Cargo.lock | Updates lock entries for the new git-based igvm crates and incidental dependency resolution changes. |
568d310 to
6c10547
Compare
6c10547 to
6e2ff44
Compare
| igvm = { git = "https://github.com/mingweishih/igvm", rev = "c389b9f", features = ["corim"] } | ||
| igvm_defs = { git = "https://github.com/mingweishih/igvm", rev = "c389b9f", default-features = false } |
f77bbff to
9d34a96
Compare
9d34a96 to
2948e70
Compare
2948e70 to
992252b
Compare
mebersol
left a comment
There was a problem hiding this comment.
[Copilot] Review feedback on PR #3088
Overall this is a substantial and well-tested change — the documentation in the new modules is excellent, the pre-mutation verification + atomic rename in patch_corim_signature is the right shape, and the test suite (especially the multi-platform and end-to-end paths) covers a lot of meaningful failure modes. A few things I'd push back on or want clarified before merge:
High-impact
-
igvm/igvm_defsswitched from crates.io to a git pin (rev = "e6c3ff1"). This is a release-blocker concern for downstream consumers — pinning to a specific commit ofmicrosoft/igvmmeans anyone building openvmm now needs network access to that exact git rev, and anycargo updatelottery can regress. The PR description doesn't mention a plan for re-publishing 0.5.0 to crates.io. Could you either (a) cut anigvm 0.5.0release first and depend on that, or (b) explicitly call out in the PR body that this is a temporary pin and link the tracking issue? -
SNP
SevVmsasize handling silently loosened infile_loader.rs. The old check required exact equality; the new check allows anydata.len() <= size_of::<SevVmsa>()and zero-pads to the new (page-aligned, 4K) size. The comment explains the size mismatch but doesn't address the measurement implication: SEV-SNP measures the VMSA page contents, and PSP-spec measurement is over the architectural 1648-byte form. If the padding bytes end up in the measured digest because the newSevVmsadefinition is page-sized, you've silently changed measurements (and they'll only diverge at attestation time on real hardware). Please confirm:- The
test_snp_measurementreference digest was regenerated against real hardware-validated output, not just updated to match whatever the new code produces. - The padded VMSA bytes are not included in the hashed region for the launch digest, OR the spec-mandated bytes are byte-identical pre/post.
- The
-
Possibly incorrect
libssl-devdependency inbuild_igvmfilegen.rs. The comment sayslibssl-dev + pkg-configare required, butcryptois enabled withfeatures = ["native", "vendored"]. Persupport/crypto/Cargo.toml,vendoredtranslates toopenssl?/vendoredwhich builds OpenSSL from source — systemlibssl-devshould not be needed in that configuration.pkg-configmay still be needed by openssl-sys's build script, butlibssl-devlikely isn't. Worth verifying — if the build works withoutlibssl-dev, drop it; if it doesn't, thevendoredfeature is being defeated somewhere and that needs fixing instead.
Behavior nuances worth surfacing
-
PatchCorimSignature --corim-bundlesilently discards the bundle's payload. Only the detached signature is taken from a bundled input; the embedded CoRIM document is dropped on the floor and the IGVM-embedded document is what gets signed against. The CLI help mentions it, but in practice if a user supplies a bundle whose embedded payload differs from the IGVM-embedded document, they'll get acryptographic verification failederror with no hint about why (the document mismatch). Consider either: (a) compare the two documents and emit a targeted error ("bundled document does not match IGVM-embedded document"), or (b) log the discard at info level so it's visible in build logs. -
CoRIM signature header is reordered relative to other initialization headers. In
corim_signature::mod::patch, when an existingCorimDocumentis matched it's dropped from the iteration and re-pushed at the end, then the new signature is appended. This moves the document past any subsequent non-CoRIM init headers (e.g.GuestPolicy,RelocatableRegion). The igvm crate may or may not care about absolute init-header ordering — please confirm with the upstream maintainer that only the relative (doc-before-sig) ordering matters, and that re-anchoring at the tail doesn't change semantics. If you can preserve the document at its original position and only move/insert the signature adjacent to it, that's strictly safer. -
Inconsistency: VBS legacy signing-algo says
ECDSA_P384, CoRIM signing-algo restricted toPS384. Inmeasurement_diag::log_vbsyou hard-codesigning_algo: VbsSigningAlgorithm::ECDSA_P384.0, but the CoRIM verify path inenvelope::verify_corim_signatureonly acceptsCoseAlgorithm::Ps384(RSA-PSS). Two different signing paths, two different algorithms is fine, but a sentence in the PR description explaining "legacy VBS endorsement is ECDSA P-384 over the boot-measurement struct; CoRIM endorsement is PS384 over the CoRIM document, by separate keys" would prevent future readers from staring at this and assuming a bug. -
Crypto backend mismatch between test and prod.
crypto::ensure_single_backend!()is gated#[cfg(not(test))]. If tests run under a different backend than the binary, the cryptographic verify path being exercised byverify_ps384_round_tripis not the one shipping. Please confirm the test backend (RustCrypto?) and the prod backend (OpenSSL via native+vendored) both round-trip PS384 identically.
Minor
-
build_endorsement_jsonusesunreachable!for non-measurable platforms. Invariant is enforced at the call site, not the type system. Consider taking a small enum likeenum MeasurablePlatform { Snp, Tdx, Vbs }from the call site so the function signature itself can't be misused — would eliminate the.expect()digests too. -
PlatformCLI enum duplicatesIgvmPlatformTypefor clap. Cosmetic. Could be a single newtype with avalue_parser, but the current approach is also fine. -
CoRIM crate at
0.1.3(0.y.z). Pre-1.0 SemVer means any 0.x bump can break — given how central this is to the patch path, consider pinning to=0.1.3until upstream stabilizes, to avoid silent breakage oncargo update. -
SNP_FAMILY_ID = *b"msft\0..."andSNP_IMAGE_ID = *b"underhill\0..."are now duplicated inmeasurement_diag.rshaving moved fromsigned_measurement/snp.rs. Worth confirming the bytes are byte-identical to the original (looks correct in the diff, but a one-line test asserting these constants would catch a future typo since the values are baked into externally-issued SNP ID blocks).
Test coverage
The test suite is thorough — particularly test_e2e_real_corim_build_and_patch exercising the full add_corim → sign → patch flow. Two additions that would tighten it:
- A negative test where the bundle's embedded payload differs from the IGVM-embedded document (covers the failure mode in point 4 above).
- A test that asserts the patched IGVM file's
IGVM_FIXED_HEADER.checksum(CRC32) actually validates —test_patch_corim_output_is_valid_igvm_headerchecks magic/version/size but not the checksum.
Petri test failures
The bot reports 27 (5 unstable) Petri failures on the latest push, 38 (15 unstable) on the one before. Worth checking whether any of those are CoRIM/measurement-related vs pre-existing flakiness, and calling that out in the PR.
992252b to
3a7b319
Compare
3a7b319 to
eaf8b8f
Compare
Review responsesHigh-Impact issues:
Behavior nuances worth surfacing
Minor
Test Coverage
Petri failuresfailures are unrelated to this PR. |
eaf8b8f to
fd8b2ed
Compare
fd8b2ed to
224346f
Compare
Bump the workspace igvm/igvm_defs dependencies to microsoft/igvm rev e6c3ff1 (current main tip). This pulls in: - PR microsoft#109 which pads `SevVmsa` out to a full 4 KiB page, whereas `x86defs::snp::SevVmsa` produced by the VP context builder is the architectural 1648-byte structure. - PR microsoft#122 which adds CoRIM launch-measurement APIs. - New `AArch64Register` variants (X2-X7) and a new `IgvmDirectiveHeader::AArch64CcaVpContext` variant. Adapt local callers: - igvmfilegen's `import_pages` SNP branch zero-pads the incoming VMSA up to the igvm crate's expected size before calling `SevVmsa::read_from_bytes`, and the strict size check is relaxed to allow any input no larger than the padded size. - `vm/loader` and `vmm_core/vm_loader` mirror the new `AArch64Register` X2-X7 variants. - `openvmm_core`'s IGVM directive matcher adds `AArch64CcaVpContext` arms (todo-stubbed; no callers exercise CCA yet). This is a no-op for current functionality and is a prerequisite for the upcoming CoRIM endorsement support. Signed-off-by: Ming-Wei Shih <mishih@microsoft.com>
Signed-off-by: Ming-Wei Shih <mishih@microsoft.com>
224346f to
bf3969b
Compare
This PR adds the support of writing CoRIM to an existing IGVM file, allowing for injecting the CoRIM files post build in the pipeline.
By IGVM design, a signed CoRIM is expected to be broken into payload and signed envelope with payload detached and written into
CORIM_DOCUMENTandCORIM_SIGNATUREentries correspondingly. The idea is decoupling the payload generation and the signing process. However, given that the CoRIM detached signing might not always be supported by the signing infrastructure, the tool additionally supports taking a signed CoRIM as input and handles the decoupling before writing to the IGVM file.Notes to the PR
igvm 0.5.0ships.SevVmsasize loosening: igvm crate'sSevVmsais padded out to a full 4K page.AArch64Registervariants (X2-X7) and a newIgvmDirectiveHeader::AArch64CcaVpContextvariant.