Skip to content

Updating Library to Match Version 1.58 of the SNP Spec#312

Merged
tylerfanelli merged 3 commits into
virtee:mainfrom
DGonzalezVillal:firmware-uptdate
Jul 11, 2025
Merged

Updating Library to Match Version 1.58 of the SNP Spec#312
tylerfanelli merged 3 commits into
virtee:mainfrom
DGonzalezVillal:firmware-uptdate

Conversation

@DGonzalezVillal

Copy link
Copy Markdown
Member

The new 1.58 firmware specification has been released, introducing changes to both the attestation report and key derivation features.

Attestation Report Changes:
Two new fields have been added: launch_mit_vector and current_mit_vector. These vectors reflect mitigations that may or may not be present on the system. Additionally, a new enablement bit for SEV-TIO has been added to the PlatformInfo structure. The attestation report version is now bumped to version 5. (Note: Version 4 remains under AMD embargo, so specifics cannot be disclosed.)

Key Derivation Changes:
A new field, launch_mit_vector, has been added to the key derivation request structure. This allows a mitigation vector to be mixed into the derived key. As a result, the message key request has been bumped to version 2. Version 2 requests require a mit_vector value; if a version 1 request is used, the mit_vector defaults to zero.

Parsing Improvements:
The attestation report byte parsing logic has been updated. Previously, there were separate variants for each version (pre-Turin and Turin). Now, the write_tcb and parse_tcb functions are used more effectively. Once the processor generation is determined, the appropriate TCB layout can be applied. Since TCB layout is the main difference between pre-Turin and Turin+ attestation reports, this change allows us to maintain a single report variant per version.

@DGonzalezVillal

DGonzalezVillal commented Jun 19, 2025

Copy link
Copy Markdown
Member Author

@DGonzalezVillal

Copy link
Copy Markdown
Member Author

Will fix failures now

larrydewey
larrydewey previously approved these changes Jun 20, 2025

@larrydewey larrydewey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One nit which isn't a requirement to be changed. Just a thought.

Comment thread src/firmware/guest/types/snp.rs Outdated

@tylerfanelli tylerfanelli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you break this change up into multiple commits? Each commit should include one logical change rather than one sweeping commit listing multiple changes in the description.

@DGonzalezVillal

Copy link
Copy Markdown
Member Author

@tylerfanelli split into smaller commits. Let me know if you have any other comments

…errors

We have variants for each attestation report version (pre-turin and post-turin). As we add new versions the amount of variants we will need for each report will grow quickly and will make logic to handle the variants annoying and redundant. With this change we can make use of the already established GENERATION enum and it's logic to tell the proc generation atparsing time. Then we can make better use of the write_tcb and parse_tcb functions to parse according to the proc generation instead of a boolean. The only difference (so far) between version variants is the TCB format according to it's proc generation. This change will allow us to maintain a single variant per report version.

Also some lint errors were addressed to remove redundant calls of
io::Error::new.

Signed-off-by: DGonzalezVillal <Diego.GonzalezVillalobos@amd.com>
…ds for SNP SPEC 1.58

Two new fields have been added to the attestation report:
launch_mit_vector and current_mit_vector. These mitigation vectors were introduced in version 1.58.

Additionally, the PlatformPolicy, GuestPolicy, and PlatformInfo structures have had new fields added, which are now supported. Some of these structures previously had incomplete display implementations, so we've updated those as well to include the newly added fields.

Signed-off-by: DGonzalezVillal <Diego.GonzalezVillalobos@amd.com>
A new field, launch_mit_vector, has been added to the key derivation request structure. This allows a mitigation vector to be mixed into the derived key. As a result, the message key request has been bumped to version 2. Version 2 requests require a mit_vector value; if a version 1 request is used, the mit_vector defaults to zero.

Tests have been updated to reflect the new structure.

Signed-off-by: DGonzalezVillal <Diego.GonzalezVillalobos@amd.com>
@DGonzalezVillal

Copy link
Copy Markdown
Member Author

@tylerfanelli Please take a look now

@cschramm

cschramm commented Sep 1, 2025

Copy link
Copy Markdown

Not sure how relevant this is, but I'd like to mention that we have Genoa attestation reports sitting in some test fixtures that have version 3 but the CPUID bits all zero. Obviously, that case fails to parse as Generation::identify_cpu expects proper values. We are not able to replicate this in any way now, but we are also not on the TCB version anymore (specifically SNP 22 -> 23).

0300000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000090000000000164821000000000000000000000000000000bb851e203747c3685d79a29910e76c53957896dbf6e68835b64ea2c2b2be7db600000000000000000000000000000000000000000000000000000000000000000a30b90d73f101fcfa29d1c7b7cd0b6918dc89ff3e84fb06bcce85c86d22d43ddea2cbf2d736697d54c7ea5cf33ca77000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a369c0fa8f2a7a8e378d62567c37007fe56fc5071baa7f18d9f97117301f7bfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff09000000000016480000000000000000000000000000000000000000000000009dc99962c063029e430b6f7b734075ec542f4f3ec639e657e14585d3fe559b38532bc42d037d618317694ad6634d2507964e276c8eedeac4978c7006bf89f8e1090000000000164826370100263701000900000000001648000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8ea2e525e2513fe8d89fb83160fcd295728da2ab6dfd762b81991069be542c70a04be850503b2ee12ba71eb957aa4fd0000000000000000000000000000000000000000000000008a6c68f5ecd2f39d35e2e162cc2a45472a83c1020e13620ba1d94afb6e357254adc7c9fd3ec0210689b745b33f691a690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

@DGonzalezVillal

Copy link
Copy Markdown
Member Author

Not sure how relevant this is, but I'd like to mention that we have Genoa attestation reports sitting in some test fixtures that have version 3 but the CPUID bits all zero. Obviously, that case fails to parse as Generation::identify_cpu expects proper values. We are not able to replicate this in any way now, but we are also not on the TCB version anymore (specifically SNP 22 -> 23).

0300000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000090000000000164821000000000000000000000000000000bb851e203747c3685d79a29910e76c53957896dbf6e68835b64ea2c2b2be7db600000000000000000000000000000000000000000000000000000000000000000a30b90d73f101fcfa29d1c7b7cd0b6918dc89ff3e84fb06bcce85c86d22d43ddea2cbf2d736697d54c7ea5cf33ca77000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a369c0fa8f2a7a8e378d62567c37007fe56fc5071baa7f18d9f97117301f7bfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff09000000000016480000000000000000000000000000000000000000000000009dc99962c063029e430b6f7b734075ec542f4f3ec639e657e14585d3fe559b38532bc42d037d618317694ad6634d2507964e276c8eedeac4978c7006bf89f8e1090000000000164826370100263701000900000000001648000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8ea2e525e2513fe8d89fb83160fcd295728da2ab6dfd762b81991069be542c70a04be850503b2ee12ba71eb957aa4fd0000000000000000000000000000000000000000000000008a6c68f5ecd2f39d35e2e162cc2a45472a83c1020e13620ba1d94afb6e357254adc7c9fd3ec0210689b745b33f691a690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

We need to know the generation of the host CPU in order to parse the TCB correctly. In version 2 of the reports the new cpu family, model and stepping fields were not available, so we we could use a little trick of checking the length of the cpuid field to tell the generations apart. But as you mention, if mask chip id is enabled, then the chip id will be set to 0, so if that's the case we can't parse the report and it will fail. But that will only happen in the rare case you have a version 2 report and mask chip id enabled. In version 3 and forward we can get that information from the family, model and stepping.

If you bring this up because of the skip bytes error that was mentioned in trustee. This won't be a problem in fields that have expected values. Skip bytes was made to skip reserved fields, and raise and error if these fields are not 0 as they are expected to be.

@cschramm

cschramm commented Sep 3, 2025

Copy link
Copy Markdown

In the report that I provided in hex, you can see that the version byte (offset 0) indicates 3, and family (offset 0x188) and model (offset 0x189) are both 0. AttestationReport::from_bytes passes those values to Generation::identify_cpu which fails with the processor is not of know SEV-SNP generation. error.

I have no idea how that report came to be as it does not match the specification, but we have multiple such reports in our fixtures. They are valid and should have come from an EPYC 9454P in January. The machine received a firmware update in the meantime and we are not able to replicate such reports.

@DGonzalezVillal

Copy link
Copy Markdown
Member Author

There is a chance those reports were either parsed incorrectly by old tooling or some firmware error?

Version 3 of the report should have a valid family ,model and stepping.

@cschramm

cschramm commented Sep 3, 2025

Copy link
Copy Markdown

We can rule out incorrect parsing as a source, as the reports have a signature that verifies fine with their corresponding VCEK certificate (https://kdsintf.amd.com/vcek/v1/Genoa/9dc99962c063029e430b6f7b734075ec542f4f3ec639e657e14585d3fe559b38532bc42d037d618317694ad6634d2507964e276c8eedeac4978c7006bf89f8e1?blSPL=9&teeSPL=0&snpSPL=22&ucodeSPL=72), e.g. using sev 6.2's parser and verification. As the signature covers both the version 3 byte and the 0 family, model, and stepping bytes, the report must have been issued exactly like that.

Anyway, if this weird phenomenon is something completely new to you, it's probably not worth handling. We do not have a use case either, just noticed it in our fixtures, which we can simply replace to make them work with sev 6.3 and 7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants