Git Product home page Git Product logo

sev-snp-measure's Introduction

sev-snp-measure

Scope

Command-line tool and Python library to calculate expected measurement of an AMD SEV/SEV-ES/SEV-SNP guest VM for confidential computing.

Installation

From pip

Install from pip:

pip install sev-snp-measure

This installs the sevsnpmeasure package and the sev-snp-measure command-line script.

From Github

Clone the Github repo and run the script directly from the local directory:

git clone https://github.com/virtee/sev-snp-measure.git
cd sev-snp-measure
./sev-snp-measure.py --help

Command-line usage

sev-snp-measure

$ sev-snp-measure --help
usage: sev-snp-measure [-h] [--version] [-v] --mode {sev,seves,snp,snp:ovmf-hash,snp:svsm}
                       [--vcpus N] [--vcpu-type CPUTYPE] [--vcpu-sig VALUE] [--vcpu-family FAMILY]
                       [--vcpu-model MODEL] [--vcpu-stepping STEPPING] [--vmm-type VMMTYPE] --ovmf
                       PATH [--kernel PATH] [--initrd PATH] [--append CMDLINE]
                       [--guest-features VALUE] [--output-format {hex,base64}]
                       [--snp-ovmf-hash HASH] [--dump-vmsa] [--svsm PATH]
                       [--vars-size SIZE | --vars-file PATH]

Calculate AMD SEV/SEV-ES/SEV-SNP guest launch measurement

options:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -v, --verbose
  --mode {sev,seves,snp,snp:ovmf-hash,snp:svsm}
                        Guest mode
  --vcpus N             Number of guest vcpus
  --vcpu-type CPUTYPE   Type of guest vcpu (EPYC, EPYC-v1, EPYC-v2, EPYC-IBPB, EPYC-v3, EPYC-v4,
                        EPYC-Rome, EPYC-Rome-v1, EPYC-Rome-v2, EPYC-Rome-v3, EPYC-Milan, EPYC-
                        Milan-v1, EPYC-Milan-v2, EPYC-Genoa, EPYC-Genoa-v1)
  --vcpu-sig VALUE      Guest vcpu signature value
  --vcpu-family FAMILY  Guest vcpu family
  --vcpu-model MODEL    Guest vcpu model
  --vcpu-stepping STEPPING
                        Guest vcpu stepping
  --vmm-type VMMTYPE    Type of guest vmm (QEMU, ec2)
  --ovmf PATH           OVMF file to calculate hash from
  --kernel PATH         Kernel file to calculate hash from
  --initrd PATH         Initrd file to calculate hash from (use with --kernel)
  --append CMDLINE      Kernel command line to calculate hash from (use with --kernel)
  --guest-features VALUE
                        Hex representation of the guest kernel features expected to be included
                        (defaults to 0x1); see README.md for possible values
  --output-format {hex,base64}
                        Measurement output format
  --snp-ovmf-hash HASH  Precalculated hash of the OVMF binary (hex string)
  --dump-vmsa           Write measured VMSAs to vmsa<N>.bin (seves, snp, and snp:svsm modes only)

snp:svsm Mode:
  AMD SEV-SNP with Coconut-SVSM. This mode additionally requires --svsm and either --vars-file
  or --vars-size to be set.

  --svsm PATH           SVSM binary
  --vars-size SIZE      Size of the OVMF_VARS file in bytes (conflicts with --vars-file)
  --vars-file PATH      OVMF_VARS file (conflicts with --vars-size)

Example: SNP mode

$ sev-snp-measure --mode snp --vcpus=1 --vcpu-type=EPYC-v4 --ovmf=OVMF.fd --kernel=vmlinuz --initrd=initrd.img --append="console=ttyS0 loglevel=7"
1c8bf2f320add50cb22ca824c17f3fa51a7a4296a4a3113698c2e31b50c2dcfa7e36dea3ebc3a9411061c30acffc6d5a

Example: SNP:SVSM mode

$ sev-snp-measure \
    --mode snp:svsm \
    --vmm-type=QEMU \
    --vcpus=4 \
    --vcpu-type=EPYC-v4 \
    --ovmf=OVMF_CODE.fd \
    --svsm=svsm.bin --vars-file=OVMF_VARS.fd
3447e476b226e317890a350003b56ee17becb48d1dc25dd6b5819a1192df3238f50cda0f0216bd5ae2a992ad7ab961c4

snp-create-id-block

$ snp-create-id-block --help
usage: snp-create-id-block [-h] [--measurement VALUE] [--idkey PATH] [--authorkey PATH]

Calculate AMD SEV-SNP guest id block

optional arguments:
  -h, --help           show this help message and exit
  --measurement VALUE  Guest launch measurement in Base64 encoding
  --idkey PATH         id private key file
  --authorkey PATH     author private key file

Programmatic usage

After installing the sev-snp-measure package with pip, you can call it from another Python application:

from sevsnpmeasure import guest,id_block
from sevsnpmeasure import vcpu_types
from sevsnpmeasure.sev_mode import SevMode

ld = guest.calc_launch_digest(SevMode.SEV_SNP, vcpus_num, vcpu_types.CPU_SIGS["EPYC-v4"],
                              ovmf_path, kernel_path, initrd_path, cmdline_str, guest_features)
print("Calculated measurement:", ld.hex())

block = id_block.snp_calc_id_block(ld,"id_key_file","author_key_file")
print("Calculated id block in base64", block)

Choosing guest CPU type

For SEV-ES and SEV-SNP, the initial CPU state (VMSA) includes the guest CPU signature in the edx register when you use the QEMU vmm. Therefore, starting the VM with a different type of guest CPU will modify the content of the VMSA, and therefore modify the calculated measurement.

You can choose the guest CPU type using --vcpu-type, or --vcpu-sig, or a combination of --vcpu-family, --vcpu-model, and --vcpu-stepping. For example, the following 3 invocations are identical:

  1. sev-snp-measure --vcpu-type=EPYC-v4 ...
  2. sev-snp-measure --vcpu-sig=0x800f12 ...
  3. sev-snp-measure --vcpu-family=23 --vcpu-model=1 --vcpu-stepping=2 ...

SEV-SNP Guest Feature Field Values

Prior to Linux Kernel version 6.6, the default value was always calculated to 0x1, as the kernel only supported SNPActive. After the release of Linux Kernel 6.6, additional features were made available some of them enabled by default. Because of this, the new default value is 0x21 which is SNPActive + DebugSwap. Other possible combinations my be derived by generating a 64-bit hex value from the following chart:

BIT FIELD Description
0 SNPActive
1 vTOM
2 ReflectVC
3 RestrictedInjection
4 AlternateInjection
5 DebugSwap
6 PreventHostIBS
7 BTBIsolation
8 VmplSSS
9 SecureTSC
10 VmgexitParameter
11 Reserved, SBZ
12 IbsVirtualization
13 Reserved, SBZ
14 VmsaRegProt
15 SmtProtection
63:16 Reserved, SBZ

Precalculated OVMF hashes

The SEV-SNP digest gets generated in multiple steps that each have a digest as output. With that digest output, you can stop at any of these steps and continue generation of the full digest later. These are the steps:

  1. OVMF
  2. (optional) -kernel, -initrd, -append arguments
  3. Initial state of all vCPUs

In situations where only minor OVMF changes happen, you may not want to copy the full OVMF binary to the validation system. In these situations, you can cut digest calculation after the OVMF step and use its hash instead of the full binary.

To generate a hash, use the --mode snp:ovmf-hash parameter:

$ sev-snp-measure --mode snp:ovmf-hash --ovmf OVMF.fd
cab7e085874b3acfdbe2d96dcaa3125111f00c35c6fc9708464c2ae74bfdb048a198cb9a9ccae0b3e5e1a33f5f249819

On a different machine that only has access to an older but compatible OVMF binary, you can then ingest the hash again to generate a full measurement:

$ sev-snp-measure --mode snp --vcpus=1 --vcpu-type=EPYC-v4 --ovmf=OVMF.fd.old --ovmf-hash cab7e[...]
d52697c3e056fb8d698d19cc29adfbed5a8ec9170cb9eb63c2ac957d22b4eb647e25780162036d063a0cf418b8830acc

Related projects

Development

Run all unit tests:

pip install -r requirements.txt
make test

Check unit tests coverage:

pip install coverage
make coverage
# See HTML coverage report in htmlcov/

Check Python type hints:

pip install mypy
make typecheck

Check Python coding style:

pip install flake8
make lint

Notes

If you have any questions or issues you can create a new issue here

Pull requests are welcome!

License

Apache 2.0 license.

sev-snp-measure's People

Contributors

dependabot[bot] avatar dubek avatar larrydewey avatar msanft avatar osteffenrh avatar shuk777 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

sev-snp-measure's Issues

Random error 'Bad signature' when launching with id block and id auth

It is really wired that the error occurs randomly, re-calculating id-block and id-auth may solve the problem.

I tried to locally validate the signatures in id-auth and it seems valid, so I'm not sure if it is because of my environment or the SNP firmware. If anyone have similar problem plz let me know.

Need a function to calculate snp id block

One of the main features of SNP is starting vm based on id block, which requires id-block and id-auth for guest owner, id-key-digest and author-key-digest for verifier.

The main program should add two addtional inputs: idkey and authorkey to take id private key and author private key files, and a new option output-format=idblock

Transferring sev-snp-measure repo to VirTEE org

After a short conversations with the teams in IBM, AMD, and @tylerfanelli , we decided it is a good idea to transfer this repo from the IBM github org to the virtee github org.

Expected effects for end-users:

  1. When installing with pip install sev-snp-measure: no change.
  2. When cloning the repo: github should redirect all accesses (https and git/ssh) over to the new repo.

Here's the list of tasks; please comment if you see any issue.

  • @tylerfanelli : Allow @dubek to create new repos in @virtee org.
    • According to the docs, this is needed in order to transfer the repo.
  • @dubek : Transfer the repo to virtee. Accesses to the old repo will be redirected by github.
  • @dubek : Create a PR modifying README.md, CONTRIBUTING.md, setup.cfg - fixing the repo links to the new URL.
  • @dubek : Cut a new version 0.0.7 with this change and publish to PyPI. This will cause the PyPI project page to be updated with the new URLs.

FYI @fitzthum @dbuono @larrydewey

Provide Warning when OVMF is missing functionality for desired measurements.

When passing command line parameters for sev-snp-measure, if OVMF is missing functionality for the fields specified, it would be nice to provide a warning about them not being included in the produced measurement. For example, if a user requests the cmdline to be included, but OVMF doesn't have support to include that in the measurement.

[Question] Why measurement not need rootfs hash?

I'm a freshman about AMD sev-snp, I want to know why measurement not need include rootfs hash?
If there are some security hole when not include rootfs hash?

Can someone can help to explain it, thank U!

SEV-ES support

Hi there,

The tool looks very promising. I learnt a lot details about qemu and sev. Thank you very much! Currently I only have SEV-ES platform, and hope I could use this tool to measure SEV-ES vm. Occassionally I ran into this thread and I guess that this tool is the closest tool for SEV-ES measurement. How do you think? Thanks!

How to compute the correct launch digest of a QEMU SEV-SNP guest

Hi,

Apologies for the noob question. I'm experimenting with SEV-SNP using the official scripts and tools from the AMDESE/AMDSEV repo (snp-latest branch). I'm at the point that I can correctly launch a SNP-enabled guest VM, and now I want to attest my VM and verify the launch digest.

However, the launch digest in the attestation report does not match my reference value computed using sev-snp-measure. I am not even sure which exact parameters are needed to compute the correct measurement.

The command I used to compute the launch digest is the following:

sev-snp-measure --mode snp --vcpus=4 --vcpu-type=EPYC-v4 --ovmf=AMDSEV/snp-release-2023-10-13/usr/local/share/qemu/OVMF_CODE.fd

Instead, this is the full QEMU command that is used to boot the guest VM (from launch-qemu.sh):

/home/ecaiogs/sev/AMDSEV/snp-release-2023-10-13/usr/local/bin/qemu-system-x86_64 -enable-kvm -cpu EPYC-v4 -machine q35 -smp 4,maxcpus=255 -m 2048M,slots=5,maxmem=10240M -no-reboot -drive if=pflash,format=raw,unit=0,file=/home/ecaiogs/sev/AMDSEV/snp-release-2023-10-13/usr/local/share/qemu/OVMF_CODE.fd,readonly -drive if=pflash,format=raw,unit=1,file=/home/ecaiogs/sev/AMDSEV/snp-release-2023-10-13/sevsnp.fd -drive file=/home/ecaiogs/sev/sevsnp.qcow2,if=none,id=disk0,format=qcow2 -device virtio-scsi-pci,id=scsi0,disable-legacy=on,iommu_platform=true -device scsi-hd,drive=disk0 -machine memory-encryption=sev0,vmport=off -object memory-backend-memfd-private,id=ram1,size=2048M,share=true -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,discard=none -machine memory-backend=ram1,kvm-type=protected -nographic -monitor pty -monitor unix:monitor,server,nowait

Now, here I assumed that the kernel, initrd and append parameters do not play a role in the launch digest since when I pass the kernel to sev-snp-measure it complains that OVMF does not include SNP_KERNEL_HASHES (I checked #26 and I will to verify the kernel and initrd as well).

Does anybody know what I am missing here?

Thanks!

Error: Can't find SEV_ES_RESET_BLOCK_GUID entry in OVMF table

I am trying to run the sev-snp-measure tool in SNP mode using the example in the readme:
sev-snp-measure --mode snp --vcpus=1 --vcpu-type=EPYC-v4 --ovmf=OVMF.fd --kernel=vmlinuz --initrd=initrd.img --append="console=ttyS0 loglevel=7"

but i get the following error:
Error: Can't find SEV_ES_RESET_BLOCK_GUID entry in OVMF table

the type of the OVMF.fd file is the following:
file OVMF.fd
OVMF.fd: Matlab v4 mat-file (little endian) \226v\213L\251\205'G\007[OP, numeric, rows 0, columns 0

i tried with different images but the problem always seems to be the OVMF.fd file.
what could be the cause of the error? is there a specific format that i have to use ?

[Feature Request] Add support for (Coconut) SVSM

It would be nice to be able to calculate measurement values
when running the Coconut SVSM in an Qemu SNP VM.

This requires measuring the additional svsm binary.
The configuration of the other pages (CPUID, Secrets, ZeroPage, VMSA) seems to be different too.

I am putting this here as a "would be nice to have" feature request, and I am intending to spend time on this myself.

Please share if you have any hints on how to implement this.

ID Block: keys forced to use the P-384 curve

Hi,

I had quite some issues with verifying the ID Block since I was always getting the Bad signature error when launching QEMU and could not understand why.

I then found out that the problem is that snp-create-id-block computes the author and id public keys using always the P-384 curve, regardless of what is passed as input, as shown in the line below:

curve=CurveP384,

This of course creates some problems when the keys passed as input to snp-create-id-block use a different curve. So, my suggestion would be to simply use the public_key() method of EllipticCurvePrivateKey to derive the correct public keys, instead of using marshal_ec_public_key().

No module named 'sevsnpmeasure.cli'

Hi,

I tried to run sev-snp-measure both from source code and from pip but in both I get this error "ModuleNotFoundError: No module named 'sevsnpmeasure.cli'", what is missing?

Thanks in advance.
Pegah

Confusion from project name and readme

Because of the way the SEV API specification is written, users of this tool might be confused to learn this tool does not generate the expected launch measurement, but calculates an expected launch digest

Launch Measurement:

# Legacy SEV (non-SNP)
HMAC(0x04 || API_MAJOR || API_MINOR || BUILD || GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)

Launch Digest:

# Naples - UEFI Possibly additional measurements.
SHA256SUM(OVFM||Linux Kernel||initrd||Command Line Parameters)

# >= Rome - UEFI, Kernel, Initrd, CLI-params, VMSA, Pages (Milan+)
SHA384SUM(OVFM||Linux Kernel||initrd||Command Line Parameters||VMSA)

Perhaps some re-naming would be beneficial?

OVMF metadata doesn't include SNP_KERNEL_HASHES section

Hi,

Is there anyone know why this occurs?

Error: Kernel specified but OVMF metadata doesn't include SNP_KERNEL_HASHES section

To generate an OVMF.fd with SEV-SNP enabled, I followed the instruction of this AMDSEV repo.
However, the above problem occurs when I use the following command.

$ sev-snp-measure --mode snp --vcpus=1 --vcpu-type=EPYC-v4 --ovmf=OVMF.fd --kernel=vmlinuz --initrd=initrd.img --append="console=ttyS0 loglevel=7"

Am I missing some parts?

Jingyao

Issue with Recalculating Measurement from Attestation Report in Guest Machine on the Host Machine

I am encountering an issue while attempting to recalculate the measurement from the attestation report within the guest machine. Below are the details of the problem:

I have installed the guest machine, a virtual machine, using the AMDSEV project from the GitHub user AMDESE. After successfully installing the guest machine, I executed it using the command:

sudo ./launch-qemu.sh -hda sev-guest.qcow2 -sev-snp

Following the execution of the guest machine, I utilized the 'snpguest' tool to generate the attestation report. The report contains the measurement, represented by the hash:

d7b9f49e254f5d3eeda91e2966ad68504c2b54710ff6a21d05bc1279bfd77aba8de2e582a00eaebb37c004be12c37830.

Subsequently, I attempted to recalculate this hash (measurement) from the host machine using the 'sev-snp-measurement' tool with the following command:

./sev-snp-measure.py --mode snp --vcpus=1 --vcpu-type=EPYC-v4 --vmm-type=QEMU --ovmf=/home/user/AMDSEV/usr/local/share/qemu/OVMF_CODE.fd --kernel=/home/user/AMDSEV/sev-guest.fd --initrd=/home/user/AMDSEV/sev-guest.qcow2 --append="console=ttyS0 loglevel=7" --snp-ovmf-hash=711dd640bc679fcdefa729f47ff56700c95b1c590a779391ab178d511d6237677bea447327923972c4eee313fc2f915d

However, I encountered the following error:

"Error: Kernel specified but OVMF metadata doesn't include SNP_KERNEL_HASHES section."

This has led me to question the correctness of the kernel path, initrd value, and other parameters.

  1. Where can I find the correct values to use for the parameters( kernel path, initrd path, append,..) mentioned above please ?

Additionally, when using the 'sev-snp-measure.py' tool with the command:

./sev-snp-measure.py --mode snp --vcpus=1 --vcpu-type=EPYC-v4 --vmm-type=QEMU --ovmf=/home/user/AMDSEV/usr/local/share/qemu/OVMF_CODE.fd --snp-ovmf-hash=711dd640bc679fcdefa729f47ff56700c95b1c590a779391ab178d511d6237677bea447327923972c4eee313fc2f915d

I get a value that does not match the measurement in the attestation report within the guest machine.

  1. How can I accurately recalculate the value of this measurement?

Any guidance or assistance on resolving this issue and accurately recalculating the measurement would be highly appreciated.

What influences metadata in OVMF images?

Hey everyone,
thanks for writing this tool, it has been very helpful in precalculating launch measurements!

I am currently working on a component that should precalculate launch measurements depending on the number of vCPUs.
The component only supports a specific VMM and CPU type.
The component does not have access to the OVMF binary, but can fetch arbitrary metadata from an API.

Right now, the API serves the data that is parsed from the OVMF binary as json. But I am wondering if that data could be hardcoded into the component.
So my question is: when and how can the metadata of an OVMF image change? On what does it depend?

I compared the metadata from the two releases of aws/uefi and they stayed the same. But thats a very small sample size..
It seems to me like the addresses that are parsed relate to the GCTX's layout. And I would imagine that there is not much room for change here within one processor generation. But I am not very familiar with UEFI, OVMF, etc.

Thanks!
Otto

Latest SNP OVMF binary causes measurement failure

The OVMF binary that's built using the AMDSEV repository now contains a SVSM Calling Area Address (CAA) section type.
Defined here as:

%define OVMF_SECTION_TYPE_SVSM_CAA        0x4

This causes the measurement to fail with

ValueError: 4 is not a valid SectionType

Could you give me some guidance on how I could fix the measurement calculation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.