2021-12-09 20:33:22 +00:00
|
|
|
======================
|
|
|
|
virt-qemu-sev-validate
|
|
|
|
======================
|
|
|
|
|
|
|
|
--------------------------------------------
|
|
|
|
validate a domain AMD SEV launch measurement
|
|
|
|
--------------------------------------------
|
|
|
|
|
|
|
|
:Manual section: 1
|
|
|
|
:Manual group: Virtualization Support
|
|
|
|
|
|
|
|
.. contents::
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
|
|
``virt-qemu-sev-validate`` [*OPTIONS*]
|
|
|
|
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
===========
|
|
|
|
|
|
|
|
This program validates the reported measurement for a domain launched with AMD
|
|
|
|
SEV. If the program exits with a status of zero, the guest owner can be
|
|
|
|
confident that their guest OS is running under the protection offered by the
|
|
|
|
SEV / SEV-ES platform.
|
|
|
|
|
|
|
|
Note that the level of protection varies depending on the AMD SEV platform
|
|
|
|
generation and describing the differences is outside the scope of this
|
|
|
|
document.
|
|
|
|
|
|
|
|
For the results of this program to be considered trustworthy, it is required to
|
|
|
|
be run on a machine that is already trusted by the guest owner. This could be a
|
|
|
|
machine that the guest owner has direct physical control over, or it could be
|
|
|
|
another virtual machine protected by AMD SEV that has already had its launch
|
|
|
|
measurement validated. Running this program on the virtualization host will not
|
|
|
|
produce an answer that can be trusted.
|
|
|
|
|
2022-10-05 16:39:14 +00:00
|
|
|
If told to connect to libvirt, it will refuse to use a libvirt connection that
|
|
|
|
is local to the machine, since that cannot be trusted. For the sake of testing
|
|
|
|
or demonstration purposes, however, it can be forced to run in this scenario
|
|
|
|
using the ``--insecure`` flag. The result will, of course, still not be
|
|
|
|
trustworthy.
|
|
|
|
|
2021-12-09 20:33:22 +00:00
|
|
|
OPTIONS
|
|
|
|
=======
|
|
|
|
|
|
|
|
Common options
|
|
|
|
--------------
|
|
|
|
|
|
|
|
``-h``, ``--help``
|
|
|
|
|
|
|
|
Display command line help usage then exit.
|
|
|
|
|
|
|
|
``-d``, ``--debug``
|
|
|
|
|
|
|
|
Show debug information while running
|
|
|
|
|
|
|
|
``-q``, ``--quiet``
|
|
|
|
|
|
|
|
Don't print information about the attestation result.
|
|
|
|
|
|
|
|
Guest state options
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
These options provide information about the state of the guest that needs its
|
|
|
|
boot attested.
|
|
|
|
|
|
|
|
``--measurement BASE64-STRING``
|
|
|
|
|
|
|
|
The launch measurement reported by the hypervisor of the domain to be validated.
|
|
|
|
The measurement must be 48 bytes of binary data encoded as a base64 string.
|
|
|
|
|
|
|
|
``--api-major VERSION``
|
|
|
|
|
|
|
|
The SEV API major version of the hypervisor the domain is running on.
|
|
|
|
|
|
|
|
``--api-minor VERSION``
|
|
|
|
|
|
|
|
The SEV API major version of the hypervisor the domain is running on.
|
|
|
|
|
|
|
|
``--build-id ID``
|
|
|
|
|
|
|
|
The SEV build ID of the hypervisor the domain is running on.
|
|
|
|
|
|
|
|
``--policy POLiCY``
|
|
|
|
|
|
|
|
The policy bitmask associated with the session launch data of the domain to be
|
|
|
|
validated.
|
|
|
|
|
|
|
|
Guest config options
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
These options provide items needed to calculate the expected domain launch
|
|
|
|
measurement. This will then be compared to the reported launch measurement.
|
|
|
|
|
|
|
|
``-f PATH``, ``--firmware=PATH``
|
|
|
|
|
|
|
|
Path to the firmware loader binary. This is the EDK2 build that knows how to
|
|
|
|
initialize AMD SEV. For the validation to be trustworthy it important that the
|
|
|
|
firmware build used has no support for loading non-volatile variables from
|
|
|
|
NVRAM, even if NVRAM is expose to the guest.
|
|
|
|
|
2022-01-07 16:15:23 +00:00
|
|
|
``-k PATH``, ``--kernel=PATH``
|
|
|
|
|
|
|
|
Path to the kernel binary if doing direct kernel boot.
|
|
|
|
|
|
|
|
``-r PATH``, ``--initrd=PATH``
|
|
|
|
|
|
|
|
Path to the initrd binary if doing direct kernel boot. Defaults to zero length
|
|
|
|
content if omitted.
|
|
|
|
|
|
|
|
``-e STRING``, ``--cmdline=STRING``
|
|
|
|
|
|
|
|
String containing any kernel command line parameters used during boot of the
|
|
|
|
domain. Defaults to the empty string if omitted.
|
|
|
|
|
2022-01-07 17:25:23 +00:00
|
|
|
``-n COUNT``, ``--num-cpus=COUNT``
|
|
|
|
|
|
|
|
The number of virtual CPUs for the domain. This is required when the
|
|
|
|
domain policy is set to require SEV-ES.
|
|
|
|
|
|
|
|
``-0 PATH``, ``--vmsa-cpu0=PATH``
|
|
|
|
|
|
|
|
Path to the VMSA initial state for the boot CPU. This is required when
|
|
|
|
the domain policy is set to require SEV-ES. The file contents must be
|
|
|
|
exactly 4096 bytes in length.
|
|
|
|
|
|
|
|
``-1 PATH``, ``--vmsa-cpu1=PATH``
|
|
|
|
|
|
|
|
Path to the VMSA initial state for the non-boot CPU. This is required when
|
|
|
|
the domain policy is set to require SEV-ES and the domain has more than one
|
|
|
|
CPU present. The file contents must be exactly 4096 bytes in length.
|
|
|
|
|
2021-12-09 20:33:22 +00:00
|
|
|
``--tik PATH``
|
|
|
|
|
|
|
|
TIK file for domain. This file must be exactly 16 bytes in size and contains the
|
|
|
|
unique transport integrity key associated with the domain session launch data.
|
|
|
|
This is mutually exclusive with the ``--tk`` argument.
|
|
|
|
|
|
|
|
``--tek PATH``
|
|
|
|
|
|
|
|
TEK file for domain. This file must be exactly 16 bytes in size and contains the
|
|
|
|
unique transport encryption key associated with the domain session launch data.
|
|
|
|
This is mutually exclusive with the ``--tk`` argument.
|
|
|
|
|
|
|
|
``--tk PATH``
|
|
|
|
|
|
|
|
TEK/TIK combined file for the domain. This file must be exactly 32 bytes in
|
|
|
|
size, with the first 16 bytes containing the TEK and the last 16 bytes
|
|
|
|
containing the TIK. This is mutually exclusive with the ``--tik`` and ``--tek``
|
|
|
|
arguments.
|
|
|
|
|
2022-10-05 16:39:14 +00:00
|
|
|
Libvirt options
|
|
|
|
---------------
|
|
|
|
|
|
|
|
These options are used when connecting to libvirt to automatically obtain
|
|
|
|
state and configuration information about the domain to be attested.
|
|
|
|
|
|
|
|
``-c``, ``--connect URI``
|
|
|
|
|
|
|
|
Libvirt connection URI. For the validation to be trustworthy this must be a URI
|
|
|
|
resolving to a remote virtualization host. This requirement can be overridden
|
|
|
|
using the ``--insecure`` argument.
|
|
|
|
|
|
|
|
``-o``, ``--domain ID|NAME|UUID``
|
|
|
|
|
|
|
|
Domain ID, or domain name or domain UUID. Used to identify which libvirt domain
|
|
|
|
is to have its launch measured. The domain must be running, and would usually
|
|
|
|
have been started in a paused state, to allow validation to be performed before
|
|
|
|
guest CPUs begin execution.
|
|
|
|
|
|
|
|
``-i``, ``--insecure``
|
|
|
|
|
|
|
|
Proceed even if usage scenario is known to be insecure. This allows the program
|
|
|
|
to connect to a local libvirt hypervisor and rely on file content from the
|
|
|
|
virtualization host. It also allows the validation to proceed even if the
|
|
|
|
virtual machine CPUs are not in the initial paused state. The result of the
|
|
|
|
validation must not be trusted.
|
|
|
|
|
|
|
|
``-g``, ``--ignore-config``
|
|
|
|
|
|
|
|
Do not attempt to sanity check the domain config. The default behaviour is to
|
|
|
|
print out errors if identifying configuration elements in the guest XML that
|
|
|
|
would invalidate the launch measurement. This can help the guest owner to
|
|
|
|
understand any configuration mistakes that have been made. If the
|
|
|
|
``--ignore-config`` argument is given, this sanity checking of configuration
|
|
|
|
will be skipped. The result is that the validation will likely be reported as
|
|
|
|
failed.
|
|
|
|
|
2022-01-07 11:45:27 +00:00
|
|
|
Secret injection options
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
These options provide a way to inject a secret if validation of the
|
|
|
|
launch measurement passes.
|
|
|
|
|
|
|
|
``--inject-secret ALIAS-OR-GUID:PATH``
|
|
|
|
|
|
|
|
Path to a file containing a secret to inject into the guest OS. Typical
|
|
|
|
usage would be to supply a password for unlocking the root filesystem
|
|
|
|
full disk encryption. ``ALIAS`` can be one of the well known secrets:
|
|
|
|
|
|
|
|
* ``luks-key`` - bytes to use as a key for unlocking a LUKS key slot.
|
|
|
|
GUID of ``736869e5-84f0-4973-92ec-06879ce3da0b``.
|
|
|
|
|
|
|
|
Alternatively ``GUID`` refers to an arbitrary UUID of the callers
|
|
|
|
choosing. The contents of ``PATH`` are defined by the requirements
|
|
|
|
of the associated GUID, and will used as-is without modification.
|
|
|
|
In particular be aware:
|
|
|
|
|
|
|
|
* Avoid unwanted trailing newline characters in ``PATH`` unless
|
|
|
|
mandated by the ``GUID``.
|
|
|
|
* Any trailing ``NUL`` byte must be explicitly included in ``PATH``
|
|
|
|
if mandated by the ``GUID``.
|
|
|
|
|
|
|
|
This argument can be repeated multiple times, provided a different
|
|
|
|
``GUID`` is given for each instance.
|
|
|
|
|
|
|
|
``--secret-header PATH``
|
|
|
|
|
|
|
|
Path to a file in which the injected secret header will be written in base64
|
|
|
|
format and later injected into the domain. This is required if there is no
|
|
|
|
connection to libvirt, otherwise the secret will be directly injected.
|
|
|
|
|
|
|
|
``--secret-payload PATH``
|
|
|
|
|
|
|
|
Path to a file in which the injected secret payload will be written in base64
|
|
|
|
format and later injected into the domain. This is required if there is no
|
|
|
|
connection to libvirt, otherwise the secret will be directly injected.
|
|
|
|
|
2021-12-09 20:33:22 +00:00
|
|
|
EXAMPLES
|
|
|
|
========
|
|
|
|
|
|
|
|
Fully offline execution
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
This scenario allows a measurement to be securely validated in a completely
|
|
|
|
offline state without any connection to the hypervisor host. All required
|
|
|
|
data items must be provided as command line parameters. This usage model is
|
|
|
|
considered secure, because all input data is provided by the user.
|
|
|
|
|
|
|
|
Validate the measurement of a SEV guest booting from disk:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
# virt-qemu-sev-validate \
|
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
|
|
|
|
--api-major 0 \
|
|
|
|
--api-minor 24 \
|
|
|
|
--build-id 13 \
|
|
|
|
--policy 3
|
|
|
|
|
2022-01-07 16:15:23 +00:00
|
|
|
Validate the measurement of a SEV guest with direct kernel boot:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 16:15:23 +00:00
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--kernel vmlinuz-5.11.12 \
|
|
|
|
--initrd initramfs-5.11.12 \
|
|
|
|
--cmdline "root=/dev/vda1" \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
|
|
|
|
--api-major 0 \
|
|
|
|
--api-minor 24 \
|
|
|
|
--build-id 13 \
|
|
|
|
--policy 3
|
|
|
|
|
2022-01-07 17:25:23 +00:00
|
|
|
Validate the measurement of a SEV-ES SMP guest booting from disk:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 17:25:23 +00:00
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--num-cpus 2 \
|
|
|
|
--vmsa-cpu0 vmsa0.bin \
|
|
|
|
--vmsa-cpu1 vmsa1.bin \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
|
|
|
|
--api-major 0 \
|
|
|
|
--api-minor 24 \
|
|
|
|
--build-id 13 \
|
|
|
|
--policy 7
|
|
|
|
|
2022-10-05 12:08:17 +00:00
|
|
|
Validate the measurement of a SEV-ES SMP guest booting from disk, with
|
|
|
|
automatically constructed VMSA:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-10-05 12:08:17 +00:00
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--num-cpus 2 \
|
|
|
|
--cpu-family 23 \
|
|
|
|
--cpu-model 49 \
|
|
|
|
--cpu-stepping 0 \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
|
|
|
|
--api-major 0 \
|
|
|
|
--api-minor 24 \
|
|
|
|
--build-id 13 \
|
|
|
|
--policy 7
|
|
|
|
|
2022-01-07 11:45:27 +00:00
|
|
|
Validate the measurement of a SEV guest booting from disk and
|
|
|
|
inject a disk password on success:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2023-02-16 14:55:11 +00:00
|
|
|
--firmware OVMF.sev.fd \
|
2022-01-07 11:45:27 +00:00
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
|
|
|
|
--api-major 0 \
|
|
|
|
--api-minor 24 \
|
|
|
|
--build-id 13 \
|
|
|
|
--policy 3 \
|
2023-03-16 08:57:34 +00:00
|
|
|
--inject-secret 736869e5-84f0-4973-92ec-06879ce3da0b:passwd.txt \
|
2022-01-07 11:45:27 +00:00
|
|
|
--secret-header secret-header.b64 \
|
|
|
|
--secret-payload secret-payload.b64
|
|
|
|
|
|
|
|
The ``secret-header.b64`` and ``secret-payload.b64`` files can now be sent to
|
|
|
|
the virtualization host for injection.
|
|
|
|
|
2022-10-05 16:39:14 +00:00
|
|
|
Fetch from remote libvirt
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
This scenario allows fetching certain data from a remote hypervisor via a
|
|
|
|
connection to libvirt. It will aid in debugging by analysing the guest
|
|
|
|
configuration and reporting anything that could invalidate the measurement
|
|
|
|
of the guest. This usage model is considered secure, because the limited
|
|
|
|
information obtained from the untrusted hypervisor cannot be used to change
|
|
|
|
the result.
|
|
|
|
|
|
|
|
Validate the measurement of a SEV guest booting from disk:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
# virt-qemu-sev-validate \
|
|
|
|
--connect qemu+ssh://root@some.remote.host/system \
|
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-01-07 16:15:23 +00:00
|
|
|
Validate the measurement of a SEV guest with direct kernel boot:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 16:15:23 +00:00
|
|
|
--connect qemu+ssh://root@some.remote.host/system \
|
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--kernel vmlinuz-5.11.12 \
|
|
|
|
--initrd initramfs-5.11.12 \
|
|
|
|
--cmdline "root=/dev/vda1" \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-01-07 17:25:23 +00:00
|
|
|
Validate the measurement of a SEV-ES SMP guest booting from disk:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 17:25:23 +00:00
|
|
|
--connect qemu+ssh://root@some.remote.host/system \
|
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--num-cpus 2 \
|
|
|
|
--vmsa-cpu0 vmsa0.bin \
|
|
|
|
--vmsa-cpu1 vmsa1.bin \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-10-05 12:08:17 +00:00
|
|
|
Validate the measurement of a SEV-ES SMP guest booting from disk, with
|
|
|
|
automatically constructed VMSA:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-10-05 12:08:17 +00:00
|
|
|
--connect qemu+ssh://root@some.remote.host/system \
|
|
|
|
--firmware OVMF.sev.fd \
|
|
|
|
--cpu-family 23 \
|
|
|
|
--cpu-model 49 \
|
|
|
|
--cpu-stepping 0 \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-01-07 11:45:27 +00:00
|
|
|
Validate the measurement of a SEV guest booting from disk and
|
|
|
|
inject a disk password on success:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 11:45:27 +00:00
|
|
|
--connect qemu+ssh://root@some.remote.host/system \
|
2023-02-16 14:55:11 +00:00
|
|
|
--firmware OVMF.sev.fd \
|
2022-01-07 11:45:27 +00:00
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64 \
|
2023-03-16 08:57:34 +00:00
|
|
|
--inject-secret 736869e5-84f0-4973-92ec-06879ce3da0b:passwd.txt
|
2022-01-07 11:45:27 +00:00
|
|
|
|
2022-10-05 16:39:14 +00:00
|
|
|
Fetch from local libvirt
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
This scenario allows fetching all data from the local hypervisor via a
|
|
|
|
connection to libvirt. It is only to be used for the purpose of testing,
|
|
|
|
debugging, or demonstrations, because running on the local hypervisor is not
|
|
|
|
a secure scenario. To enable this usage, the ``--insecure`` flag must be
|
|
|
|
specified. Given a pointer to the libvirt guest to validate, all information
|
|
|
|
needed to perform a validation, except the TIK/TEK pair can be acquired
|
|
|
|
automatically.
|
|
|
|
|
|
|
|
Validate the measurement of a SEV guest booting from disk:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
# virt-qemu-sev-validate \
|
|
|
|
--insecure \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-10-06 11:35:40 +00:00
|
|
|
Validate the measurement of a SEV guest with direct kernel boot:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-10-06 11:35:40 +00:00
|
|
|
--insecure \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-01-07 17:25:23 +00:00
|
|
|
Validate the measurement of a SEV-ES SMP guest booting from disk:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 17:25:23 +00:00
|
|
|
--insecure \
|
|
|
|
--vmsa-cpu0 vmsa0.bin \
|
|
|
|
--vmsa-cpu1 vmsa1.bin \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-10-05 12:08:17 +00:00
|
|
|
Validate the measurement of a SEV-ES SMP guest booting from disk, with
|
|
|
|
automatically constructed VMSA:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-10-05 12:08:17 +00:00
|
|
|
--insecure \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64
|
|
|
|
|
2022-01-07 11:45:27 +00:00
|
|
|
Validate the measurement of a SEV guest booting from disk and
|
|
|
|
inject a disk password on success:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
2023-02-02 18:00:18 +00:00
|
|
|
# virt-qemu-sev-validate \
|
2022-01-07 11:45:27 +00:00
|
|
|
--insecure \
|
|
|
|
--tk this-guest-tk.bin \
|
|
|
|
--domain fedora34x86_64 \
|
2023-03-16 08:57:34 +00:00
|
|
|
--inject-secret 736869e5-84f0-4973-92ec-06879ce3da0b:passwd.txt
|
2022-01-07 11:45:27 +00:00
|
|
|
|
2022-10-07 10:53:35 +00:00
|
|
|
COMMON MISTAKES CHECKLIST
|
|
|
|
=========================
|
|
|
|
|
|
|
|
The complexity of configuring a guest and validating its boot measurement
|
|
|
|
means it is very likely to see the failure::
|
|
|
|
|
|
|
|
ERROR: Measurement does not match, VM is not trustworthy
|
|
|
|
|
|
|
|
This error message assumes the worst, but in most cases will failure will be
|
|
|
|
a result of either mis-configuring the guest, or passing the wrong information
|
|
|
|
when trying to validate it. The following information is a guide for what
|
|
|
|
items to check in order to stand the best chance of diagnosing the problem
|
|
|
|
|
|
|
|
* Check the VM configuration for the DH certificate and session
|
|
|
|
blob in the libvirt guest XML.
|
|
|
|
|
|
|
|
The content for these fields should be in base64 format, which is
|
|
|
|
what ``sevctl session`` generates. Other tools may generate the files
|
|
|
|
in binary format, so ensure it has been correctly converted to base64.
|
|
|
|
|
|
|
|
* Check the VM configuration policy value matches the session blob
|
|
|
|
|
|
|
|
The ``<policy>`` value in libvirt guest XML has to match the value
|
|
|
|
passed to the ``sevctl session`` command. If this is mismatched
|
|
|
|
then the guest will not even start, and QEMU will show an error
|
|
|
|
such as::
|
|
|
|
|
|
|
|
sev_launch_start: LAUNCH_START ret=1 fw_error=11 'Bad measurement'
|
|
|
|
|
|
|
|
* Check the correct TIK/TEK keypair are passed
|
|
|
|
|
|
|
|
The TIK/TEK keypair are uniquely tied to each DH cert and session
|
|
|
|
blob. Make sure that the TIK/TEK keypair passed to this program
|
|
|
|
the ones matched to the DH cert and session blob configured for
|
|
|
|
the libvirt guest XML. This is one of the most common mistakes.
|
|
|
|
Further ensure that the TIK and TEK files are not swapped.
|
|
|
|
|
|
|
|
* Check the firmware binary matches the one used to boot
|
|
|
|
|
|
|
|
The firmware binary content is part of the data covered by the
|
|
|
|
launch measurement. Ensure that the firmware binary passed to
|
|
|
|
this program matches the one used to launch the guest. The
|
|
|
|
hypervisor host will periodically get software updates which
|
|
|
|
introduce a new firmware binary version.
|
|
|
|
|
|
|
|
* Check the kernel, initrd and cmdline match the one used to boot
|
|
|
|
|
|
|
|
If the guest is configured to use direct kernel boot, check that
|
|
|
|
the kernel, initrd and cmdline passed to this program match the
|
|
|
|
ones used to boot the guest. In the kernel cmdline whitespace
|
|
|
|
must be preserved exactly, including any leading or trailing
|
|
|
|
spaces.
|
|
|
|
|
|
|
|
* Check whether the kernel hash measurement is enabled
|
|
|
|
|
|
|
|
The ``kernelHashes`` property in the libvirt guest XML controls
|
|
|
|
whether hashes of the kernel, initrd and cmdline content are
|
|
|
|
covered by the boot measurement. If enabled, then the matching
|
|
|
|
content must be passed to this program. UIf disabled, then
|
|
|
|
the content must **NOT** be passed.
|
|
|
|
|
|
|
|
* Check that the correct measurement hash is passed
|
|
|
|
|
|
|
|
The measurement hash includes a nonce, so it will be different
|
|
|
|
on every boot attempt. Thus when validating the measuremnt it
|
|
|
|
is important ensure the most recent measurement is used.
|
|
|
|
|
|
|
|
* Check the correct VMSA blobs / CPU SKU values for the host are used
|
|
|
|
|
|
|
|
The VMSA blobs provide the initial register state for the
|
|
|
|
boot CPU and any additional CPUs. One of the registers
|
|
|
|
encodes the CPU SKU (family, model, stepping) of the physical
|
|
|
|
host CPU. Make sure that the VMSA blob used for validation
|
|
|
|
is one that matches the SKU of the host the guest is booted
|
|
|
|
on. Passing the CPU SKU values directly to the tool can
|
|
|
|
reduce the likelihood of using the wrong ones.
|
|
|
|
|
|
|
|
* Check the CPU count is correct
|
|
|
|
|
|
|
|
When passing VMSA blobs for SEV-ES guests, the number of CPUs
|
|
|
|
present will influence the measurement result. Ensure that the
|
|
|
|
correct vCPU count is used corresponding to the guest boot
|
|
|
|
attempt.
|
|
|
|
|
|
|
|
|
|
|
|
Best practice is to run this tool in completely offline mode and pass
|
|
|
|
all information as explicit command line parameters. When debugging
|
|
|
|
failures, however, it can be useful to tell it to connect to libvirt
|
|
|
|
and fetch information. If connecting to a remote libvirt instance,
|
|
|
|
it will fetch any information that can be trusted, which is the basic
|
|
|
|
VM launch state data. It will also sanity check the XML configuration
|
|
|
|
to identify some common mistakes. If the ``--insecure`` flag is passed
|
|
|
|
it can extract some configuration information and use that for the
|
|
|
|
attestation process.
|
|
|
|
|
|
|
|
If the mistake still can't be identified, then this tool can be run
|
|
|
|
on the virtualization host. In that scenario the only three command
|
|
|
|
line parameters required are for the TIK, TEK and libvirt domain
|
|
|
|
name. It should be able to automatically determine all the other
|
|
|
|
information required. If it still reports a failure, this points
|
2022-12-08 15:55:32 +00:00
|
|
|
very strongly to the TIK/TEK pair not matching the configured
|
2022-10-07 10:53:35 +00:00
|
|
|
DH certificate and session blob.
|
|
|
|
|
|
|
|
The ``--debug`` flag will display hashes and/or hex dumps for various
|
|
|
|
pieces of information used in the attestation process. Comparing the
|
|
|
|
``--debug`` output from running on the hypervisor host, against that
|
|
|
|
obtained when running in offline mode can give further guidance to
|
|
|
|
which parameter is inconsistent.
|
|
|
|
|
|
|
|
As mentioned earlier in this document, bear in mind that in general
|
|
|
|
any attestation answers obtained from running on the hypervisor host
|
|
|
|
should not be trusted. So if a configuration mistake is identified
|
|
|
|
it is strongly recommended to re-run the attestation in offline mode
|
|
|
|
on a trusted machine.
|
|
|
|
|
|
|
|
|
2021-12-09 20:33:22 +00:00
|
|
|
EXIT STATUS
|
|
|
|
===========
|
|
|
|
|
|
|
|
Upon successful attestation of the launch measurement, an exit status of 0 will
|
|
|
|
be set.
|
|
|
|
|
|
|
|
Upon failure to attest the launch measurement one of the following codes will
|
|
|
|
be set:
|
|
|
|
|
|
|
|
* **1** - *Guest measurement did not validate*
|
|
|
|
|
|
|
|
Assuming the inputs to this program are correct, the virtual machine launch
|
|
|
|
has been compromised and it should not be trusted henceforth.
|
|
|
|
|
|
|
|
* **2** - *Usage scenario cannot be supported*
|
|
|
|
|
|
|
|
The way in which this program has been invoked prevent it from being able to
|
|
|
|
validate the launch measurement.
|
|
|
|
|
2022-10-05 16:39:14 +00:00
|
|
|
* **3** - *Usage scenario is not secure*
|
|
|
|
|
|
|
|
The way in which this program has been invoked means that the result of any
|
|
|
|
launch measurement validation will not be secure.
|
|
|
|
|
|
|
|
The program can be reinvoked with ``--insecure`` argument to force a
|
|
|
|
validation, however, the results of this should not be trusted. This should
|
|
|
|
only be used for testing, debugging or demonstration purposes, never in a
|
|
|
|
production deployment.
|
|
|
|
|
|
|
|
* **4** - *Domain has incorrect configuration to be measured*
|
|
|
|
|
|
|
|
The way in which the guest has been configured prevent this program from being
|
|
|
|
able to validate the launch measurement. Note that in general the guest
|
|
|
|
configuration reported by the hypervisor is not trustworthy, so it is
|
|
|
|
possible this error could be a false positive designed to cause a denial of
|
|
|
|
service.
|
|
|
|
|
|
|
|
This program can be reinvoked with the ``--ignore-config`` argument to skip
|
|
|
|
the sanity checks on the domain XML. This will likely result in it failing
|
|
|
|
with an exit code of **1** indicating the measurement is invalid
|
|
|
|
|
|
|
|
* **5** - *Domain is in incorrect state to be measured*
|
|
|
|
|
|
|
|
The domain has to be running in order to validate a launch measurement.
|
|
|
|
|
|
|
|
* **6** - *unexpected error occurred in the code*
|
2021-12-09 20:33:22 +00:00
|
|
|
|
|
|
|
A logic flaw in this program means it is unable to complete the validation of
|
|
|
|
the measurement. This is a bug which should be reported to the maintainers.
|
|
|
|
|
|
|
|
AUTHOR
|
|
|
|
======
|
|
|
|
|
|
|
|
Daniel P. Berrangé
|
|
|
|
|
|
|
|
|
|
|
|
BUGS
|
|
|
|
====
|
|
|
|
|
|
|
|
Please report all bugs you discover. This should be done via either:
|
|
|
|
|
|
|
|
#. the mailing list
|
|
|
|
|
|
|
|
`https://libvirt.org/contact.html <https://libvirt.org/contact.html>`_
|
|
|
|
|
|
|
|
#. the bug tracker
|
|
|
|
|
|
|
|
`https://libvirt.org/bugs.html <https://libvirt.org/bugs.html>`_
|
|
|
|
|
|
|
|
Alternatively, you may report bugs to your software distributor / vendor.
|
|
|
|
|
|
|
|
|
|
|
|
COPYRIGHT
|
|
|
|
=========
|
|
|
|
|
|
|
|
Copyright (C) 2022 by Red Hat, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
LICENSE
|
|
|
|
=======
|
|
|
|
|
|
|
|
``virt-qemu-sev-validate`` is distributed under the terms of the GNU LGPL v2.1+.
|
|
|
|
This is free software; see the source for copying conditions. There
|
|
|
|
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
PURPOSE
|
|
|
|
|
|
|
|
|
|
|
|
SEE ALSO
|
|
|
|
========
|
|
|
|
|
|
|
|
virsh(1), `SEV launch security usage <https://libvirt.org/kbase/launch_security_sev.html>`_,
|
|
|
|
`https://www.libvirt.org/ <https://www.libvirt.org/>`_
|