1VIRT-QEMU-SEV-VALIDATE(1)   Virtualization Support   VIRT-QEMU-SEV-VALIDATE(1)
2
3
4

NAME

6       virt-qemu-sev-validate - validate a domain AMD SEV launch measurement
7

SYNOPSIS

9       virt-qemu-sev-validate [OPTIONS]
10

DESCRIPTION

12       This  program  validates the reported measurement for a domain launched
13       with AMD SEV. If the program exits with a status  of  zero,  the  guest
14       owner can be confident that their guest OS is running under the protec‐
15       tion offered by the SEV / SEV-ES platform.
16
17       Note that the level of protection varies depending on the AMD SEV plat‐
18       form  generation and describing the differences is outside the scope of
19       this document.
20
21       For the results of this program to be considered trustworthy, it is re‐
22       quired  to  be  run  on  a machine that is already trusted by the guest
23       owner. This could be a machine that the guest owner has direct physical
24       control  over,  or it could be another virtual machine protected by AMD
25       SEV that has already had its launch measurement validated. Running this
26       program  on the virtualization host will not produce an answer that can
27       be trusted.
28
29       If told to connect to libvirt, it will refuse to use a libvirt  connec‐
30       tion  that  is  local to the machine, since that cannot be trusted. For
31       the sake of testing or  demonstration  purposes,  however,  it  can  be
32       forced  to  run  in this scenario using the --insecure flag. The result
33       will, of course, still not be trustworthy.
34

OPTIONS

36   Common options
37       -h, --help
38
39       Display command line help usage then exit.
40
41       -d, --debug
42
43       Show debug information while running
44
45       -q, --quiet
46
47       Don't print information about the attestation result.
48
49   Guest state options
50       These options provide information about the state  of  the  guest  that
51       needs its boot attested.
52
53       --measurement BASE64-STRING
54
55       The  launch  measurement reported by the hypervisor of the domain to be
56       validated.  The measurement must be 48 bytes of binary data encoded  as
57       a base64 string.
58
59       --api-major VERSION
60
61       The SEV API major version of the hypervisor the domain is running on.
62
63       --api-minor VERSION
64
65       The SEV API major version of the hypervisor the domain is running on.
66
67       --build-id ID
68
69       The SEV build ID of the hypervisor the domain is running on.
70
71       --policy POLiCY
72
73       The  policy  bitmask associated with the session launch data of the do‐
74       main to be validated.
75
76   Guest config options
77       These options provide items needed to  calculate  the  expected  domain
78       launch  measurement.  This will then be compared to the reported launch
79       measurement.
80
81       -f PATH, --firmware=PATH
82
83       Path to the firmware loader binary. This is the EDK2 build  that  knows
84       how  to initialize AMD SEV. For the validation to be trustworthy it im‐
85       portant that the  firmware  build  used  has  no  support  for  loading
86       non-volatile  variables  from  NVRAM,  even  if  NVRAM is expose to the
87       guest.
88
89       -k PATH, --kernel=PATH
90
91       Path to the kernel binary if doing direct kernel boot.
92
93       -r PATH, --initrd=PATH
94
95       Path to the initrd binary if doing direct kernel boot. Defaults to zero
96       length content if omitted.
97
98       -e STRING, --cmdline=STRING
99
100       String  containing  any kernel command line parameters used during boot
101       of the domain. Defaults to the empty string if omitted.
102
103       -n COUNT, --num-cpus=COUNT
104
105       The number of virtual CPUs for the domain. This is  required  when  the
106       domain policy is set to require SEV-ES.
107
108       -0 PATH, --vmsa-cpu0=PATH
109
110       Path  to the VMSA initial state for the boot CPU. This is required when
111       the domain policy is set to require SEV-ES. The file contents  must  be
112       exactly 4096 bytes in length.
113
114       -1 PATH, --vmsa-cpu1=PATH
115
116       Path  to  the VMSA initial state for the non-boot CPU. This is required
117       when the domain policy is set to require SEV-ES and the domain has more
118       than  one  CPU present. The file contents must be exactly 4096 bytes in
119       length.
120
121       --tik PATH
122
123       TIK file for domain. This file must be exactly 16  bytes  in  size  and
124       contains  the unique transport integrity key associated with the domain
125       session launch data.  This is mutually exclusive with  the  --tk  argu‐
126       ment.
127
128       --tek PATH
129
130       TEK  file  for  domain.  This file must be exactly 16 bytes in size and
131       contains the unique transport encryption key associated with the domain
132       session  launch  data.   This is mutually exclusive with the --tk argu‐
133       ment.
134
135       --tk PATH
136
137       TEK/TIK combined file for the domain. This  file  must  be  exactly  32
138       bytes  in size, with the first 16 bytes containing the TEK and the last
139       16 bytes containing the TIK.  This is mutually exclusive with the --tik
140       and --tek arguments.
141
142   Libvirt options
143       These  options are used when connecting to libvirt to automatically ob‐
144       tain state and configuration information about the  domain  to  be  at‐
145       tested.
146
147       -c, --connect URI
148
149       Libvirt  connection URI. For the validation to be trustworthy this must
150       be a URI resolving to a remote virtualization  host.  This  requirement
151       can be overridden using the --insecure argument.
152
153       -o, --domain ID|NAME|UUID
154
155       Domain  ID,  or domain name or domain UUID. Used to identify which lib‐
156       virt domain is to have its launch measured. The domain must be running,
157       and would usually have been started in a paused state, to allow valida‐
158       tion to be performed before guest CPUs begin execution.
159
160       -i, --insecure
161
162       Proceed even if usage scenario is known to be insecure. This allows the
163       program  to connect to a local libvirt hypervisor and rely on file con‐
164       tent from the virtualization host. It also  allows  the  validation  to
165       proceed  even if the virtual machine CPUs are not in the initial paused
166       state. The result of the validation must not be trusted.
167
168       -g, --ignore-config
169
170       Do not attempt to sanity check the domain config. The default behaviour
171       is  to  print  out  errors if identifying configuration elements in the
172       guest XML that would invalidate the launch measurement. This  can  help
173       the guest owner to understand any configuration mistakes that have been
174       made. If the --ignore-config argument is given, this sanity checking of
175       configuration  will  be skipped. The result is that the validation will
176       likely be reported as failed.
177
178   Secret injection options
179       These options provide a way to inject a secret  if  validation  of  the
180       launch measurement passes.
181
182       --inject-secret ALIAS-OR-GUID:PATH
183
184       Path to a file containing a secret to inject into the guest OS. Typical
185       usage would be to supply a password for unlocking the  root  filesystem
186       full disk encryption. ALIAS can be one of the well known secrets:
187
188luks-key - bytes to use as a key for unlocking a LUKS key slot.  GUID
189         of 736869e5-84f0-4973-92ec-06879ce3da0b.
190
191       Alternatively GUID refers to an arbitrary UUID of the callers choosing.
192       The  contents of PATH are defined by the requirements of the associated
193       GUID, and will used  as-is  without  modification.   In  particular  be
194       aware:
195
196          • Avoid unwanted trailing newline characters in PATH unless mandated
197            by the GUID.
198
199          • Any trailing NUL byte must be explicitly included in PATH if  man‐
200            dated by the GUID.
201
202       This argument can be repeated multiple times, provided a different GUID
203       is given for each instance.
204
205       --secret-header PATH
206
207       Path to a file in which the injected secret header will be  written  in
208       base64  format  and later injected into the domain. This is required if
209       there is no connection to libvirt, otherwise the  secret  will  be  di‐
210       rectly injected.
211
212       --secret-payload PATH
213
214       Path  to a file in which the injected secret payload will be written in
215       base64 format and later injected into the domain. This is  required  if
216       there  is  no  connection  to libvirt, otherwise the secret will be di‐
217       rectly injected.
218

EXAMPLES

220   Fully offline execution
221       This scenario allows a measurement to be securely validated in  a  com‐
222       pletely  offline  state  without any connection to the hypervisor host.
223       All required data items must be provided as  command  line  parameters.
224       This  usage  model is considered secure, because all input data is pro‐
225       vided by the user.
226
227       Validate the measurement of a SEV guest booting from disk:
228
229          # virt-qemu-sev-validate \
230              --firmware OVMF.sev.fd \
231              --tk this-guest-tk.bin \
232              --measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
233              --api-major 0 \
234              --api-minor 24 \
235              --build-id 13 \
236              --policy 3
237
238       Validate the measurement of a SEV guest with direct kernel boot:
239
240          # virt-dom-sev-validate \
241              --firmware OVMF.sev.fd \
242              --kernel vmlinuz-5.11.12 \
243              --initrd initramfs-5.11.12 \
244              --cmdline "root=/dev/vda1" \
245              --tk this-guest-tk.bin \
246              --measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
247              --api-major 0 \
248              --api-minor 24 \
249              --build-id 13 \
250              --policy 3
251
252       Validate the measurement of a SEV-ES SMP guest booting from disk:
253
254          # virt-dom-sev-validate \
255              --firmware OVMF.sev.fd \
256              --num-cpus 2 \
257              --vmsa-cpu0 vmsa0.bin \
258              --vmsa-cpu1 vmsa1.bin \
259              --tk this-guest-tk.bin \
260              --measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
261              --api-major 0 \
262              --api-minor 24 \
263              --build-id 13 \
264              --policy 7
265
266       Validate the measurement of a SEV-ES SMP guest booting from disk,  with
267       automatically constructed VMSA:
268
269          # virt-dom-sev-validate \
270              --firmware OVMF.sev.fd \
271              --num-cpus 2 \
272              --cpu-family 23 \
273              --cpu-model 49 \
274              --cpu-stepping 0 \
275              --tk this-guest-tk.bin \
276              --measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
277              --api-major 0 \
278              --api-minor 24 \
279              --build-id 13 \
280              --policy 7
281
282       Validate  the measurement of a SEV guest booting from disk and inject a
283       disk password on success:
284
285          # virt-dom-sev-validate \
286              --loader OVMF.sev.fd \
287              --tk this-guest-tk.bin \
288              --measurement Zs2pf19ubFSafpZ2WKkwquXvACx9Wt/BV+eJwQ/taO8jhyIj/F8swFrybR1fZ2ID \
289              --api-major 0 \
290              --api-minor 24 \
291              --build-id 13 \
292              --policy 3 \
293              --disk-password passwd.txt \
294              --secret-header secret-header.b64 \
295              --secret-payload secret-payload.b64
296
297       The secret-header.b64 and secret-payload.b64 files can now be  sent  to
298       the virtualization host for injection.
299
300   Fetch from remote libvirt
301       This scenario allows fetching certain data from a remote hypervisor via
302       a connection to libvirt. It will aid  in  debugging  by  analysing  the
303       guest  configuration  and  reporting anything that could invalidate the
304       measurement of the guest. This usage model is  considered  secure,  be‐
305       cause  the  limited  information obtained from the untrusted hypervisor
306       cannot be used to change the result.
307
308       Validate the measurement of a SEV guest booting from disk:
309
310          # virt-qemu-sev-validate \
311              --connect qemu+ssh://root@some.remote.host/system \
312              --firmware OVMF.sev.fd \
313              --tk this-guest-tk.bin \
314              --domain fedora34x86_64
315
316       Validate the measurement of a SEV guest with direct kernel boot:
317
318          # virt-dom-sev-validate \
319              --connect qemu+ssh://root@some.remote.host/system \
320              --firmware OVMF.sev.fd \
321              --kernel vmlinuz-5.11.12 \
322              --initrd initramfs-5.11.12 \
323              --cmdline "root=/dev/vda1" \
324              --tk this-guest-tk.bin \
325              --domain fedora34x86_64
326
327       Validate the measurement of a SEV-ES SMP guest booting from disk:
328
329          # virt-dom-sev-validate \
330              --connect qemu+ssh://root@some.remote.host/system \
331              --firmware OVMF.sev.fd \
332              --num-cpus 2 \
333              --vmsa-cpu0 vmsa0.bin \
334              --vmsa-cpu1 vmsa1.bin \
335              --tk this-guest-tk.bin \
336              --domain fedora34x86_64
337
338       Validate the measurement of a SEV-ES SMP guest booting from disk,  with
339       automatically constructed VMSA:
340
341          # virt-dom-sev-validate \
342              --connect qemu+ssh://root@some.remote.host/system \
343              --firmware OVMF.sev.fd \
344              --cpu-family 23 \
345              --cpu-model 49 \
346              --cpu-stepping 0 \
347              --tk this-guest-tk.bin \
348              --domain fedora34x86_64
349
350       Validate  the measurement of a SEV guest booting from disk and inject a
351       disk password on success:
352
353          # virt-dom-sev-validate \
354              --connect qemu+ssh://root@some.remote.host/system \
355              --loader OVMF.sev.fd \
356              --tk this-guest-tk.bin \
357              --domain fedora34x86_64 \
358              --disk-password passwd.txt
359
360   Fetch from local libvirt
361       This scenario allows fetching all data from the local hypervisor via  a
362       connection  to  libvirt. It is only to be used for the purpose of test‐
363       ing, debugging, or demonstrations, because running on the local  hyper‐
364       visor  is  not  a secure scenario. To enable this usage, the --insecure
365       flag must be specified. Given a pointer to the libvirt guest  to  vali‐
366       date,  all  information  needed  to  perform  a  validation, except the
367       TIK/TEK pair can be acquired automatically.
368
369       Validate the measurement of a SEV guest booting from disk:
370
371          # virt-qemu-sev-validate \
372              --insecure \
373              --tk this-guest-tk.bin \
374              --domain fedora34x86_64
375
376       Validate the measurement of a SEV guest with direct kernel boot:
377
378          # virt-dom-sev-validate \
379              --insecure \
380              --tk this-guest-tk.bin \
381              --domain fedora34x86_64
382
383       Validate the measurement of a SEV-ES SMP guest booting from disk:
384
385          # virt-dom-sev-validate \
386              --insecure \
387              --vmsa-cpu0 vmsa0.bin \
388              --vmsa-cpu1 vmsa1.bin \
389              --tk this-guest-tk.bin \
390              --domain fedora34x86_64
391
392       Validate the measurement of a SEV-ES SMP guest booting from disk,  with
393       automatically constructed VMSA:
394
395          # virt-dom-sev-validate \
396              --insecure \
397              --tk this-guest-tk.bin \
398              --domain fedora34x86_64
399
400       Validate  the measurement of a SEV guest booting from disk and inject a
401       disk password on success:
402
403          # virt-dom-sev-validate \
404              --insecure \
405              --tk this-guest-tk.bin \
406              --domain fedora34x86_64 \
407              --disk-password passwd.txt
408

COMMON MISTAKES CHECKLIST

410       The complexity of configuring a guest and validating its boot  measure‐
411       ment means it is very likely to see the failure:
412
413          ERROR: Measurement does not match, VM is not trustworthy
414
415       This  error  message  assumes the worst, but in most cases will failure
416       will be a result of either mis-configuring the guest,  or  passing  the
417       wrong information when trying to validate it. The following information
418       is a guide for what items to check in order to stand the best chance of
419       diagnosing the problem
420
421       • Check the VM configuration for the DH certificate and session blob in
422         the libvirt guest XML.
423
424         The content for these fields should be in  base64  format,  which  is
425         what  sevctl session generates. Other tools may generate the files in
426         binary format, so ensure it has been correctly converted to base64.
427
428       • Check the VM configuration policy value matches the session blob
429
430         The <policy> value in libvirt guest XML has to match the value passed
431         to  the  sevctl session command. If this is mismatched then the guest
432         will not even start, and QEMU will show an error such as:
433
434            sev_launch_start: LAUNCH_START ret=1 fw_error=11 'Bad measurement'
435
436       • Check the correct TIK/TEK keypair are passed
437
438         The TIK/TEK keypair are uniquely tied to each  DH  cert  and  session
439         blob.  Make  sure that the TIK/TEK keypair passed to this program the
440         ones matched to the DH cert and session blob configured for the  lib‐
441         virt guest XML. This is one of the most common mistakes.  Further en‐
442         sure that the TIK and TEK files are not swapped.
443
444       • Check the firmware binary matches the one used to boot
445
446         The firmware binary content is part of the data covered by the launch
447         measurement.  Ensure  that the firmware binary passed to this program
448         matches the one used to launch the guest. The  hypervisor  host  will
449         periodically  get software updates which introduce a new firmware bi‐
450         nary version.
451
452       • Check the kernel, initrd and cmdline match the one used to boot
453
454         If the guest is configured to use direct kernel boot, check that  the
455         kernel, initrd and cmdline passed to this program match the ones used
456         to boot the guest. In the kernel cmdline whitespace must be preserved
457         exactly, including any leading or trailing spaces.
458
459       • Check whether the kernel hash measurement is enabled
460
461         The  kernelHashes  property in the libvirt guest XML controls whether
462         hashes of the kernel, initrd and cmdline content are covered  by  the
463         boot  measurement.  If  enabled,  then  the  matching content must be
464         passed to this program. UIf disabled, then the content  must  NOT  be
465         passed.
466
467       • Check that the correct measurement hash is passed
468
469         The measurement hash includes a nonce, so it will be different on ev‐
470         ery boot attempt. Thus when validating the measuremnt it is important
471         ensure the most recent measurement is used.
472
473       • Check the correct VMSA blobs / CPU SKU values for the host are used
474
475         The  VMSA  blobs  provide the initial register state for the boot CPU
476         and any additional CPUs. One of the registers  encodes  the  CPU  SKU
477         (family,  model,  stepping)  of the physical host CPU. Make sure that
478         the VMSA blob used for validation is one that matches the SKU of  the
479         host  the  guest is booted on. Passing the CPU SKU values directly to
480         the tool can reduce the likelihood of using the wrong ones.
481
482       • Check the CPU count is correct
483
484         When passing VMSA blobs for SEV-ES guests, the number of CPUs present
485         will  influence  the measurement result. Ensure that the correct vCPU
486         count is used corresponding to the guest boot attempt.
487
488       Best practice is to run this tool in completely offline mode  and  pass
489       all  information  as  explicit  command line parameters. When debugging
490       failures, however, it can be useful to tell it to  connect  to  libvirt
491       and  fetch  information. If connecting to a remote libvirt instance, it
492       will fetch any information that can be trusted, which is the  basic  VM
493       launch  state  data. It will also sanity check the XML configuration to
494       identify some common mistakes. If the --insecure flag is passed it  can
495       extract some configuration information and use that for the attestation
496       process.
497
498       If the mistake still can't be identified, then this tool can be run  on
499       the  virtualization  host. In that scenario the only three command line
500       parameters required are for the TIK, TEK and libvirt  domain  name.  It
501       should be able to automatically determine all the other information re‐
502       quired. If it still reports a failure, this points very strongly to the
503       TIK/TEK  pair  not  matching  the configured DH certificate and session
504       blob.
505
506       The --debug flag will display  hashes  and/or  hex  dumps  for  various
507       pieces  of  information  used in the attestation process. Comparing the
508       --debug output from running on the hypervisor host,  against  that  ob‐
509       tained  when running in offline mode can give further guidance to which
510       parameter is inconsistent.
511
512       As mentioned earlier in this document, bear in mind that in general any
513       attestation answers obtained from running on the hypervisor host should
514       not be trusted. So if a  configuration  mistake  is  identified  it  is
515       strongly  recommended  to  re-run  the attestation in offline mode on a
516       trusted machine.
517

EXIT STATUS

519       Upon successful attestation of the launch measurement, an  exit  status
520       of 0 will be set.
521
522       Upon  failure  to  attest  the  launch measurement one of the following
523       codes will be set:
524
5251 - Guest measurement did not validate
526
527         Assuming the inputs to this program are correct, the virtual  machine
528         launch has been compromised and it should not be trusted henceforth.
529
5302 - Usage scenario cannot be supported
531
532         The  way in which this program has been invoked prevent it from being
533         able to validate the launch measurement.
534
5353 - Usage scenario is not secure
536
537         The way in which this program has been invoked means that the  result
538         of any launch measurement validation will not be secure.
539
540         The program can be reinvoked with --insecure argument to force a val‐
541         idation, however, the results of this should  not  be  trusted.  This
542         should only be used for testing, debugging or demonstration purposes,
543         never in a production deployment.
544
5454 - Domain has incorrect configuration to be measured
546
547         The way in which the guest has been configured prevent  this  program
548         from being able to validate the launch measurement. Note that in gen‐
549         eral the guest configuration reported by the hypervisor is not trust‐
550         worthy,  so  it  is possible this error could be a false positive de‐
551         signed to cause a denial of service.
552
553         This program can be reinvoked with the  --ignore-config  argument  to
554         skip  the sanity checks on the domain XML. This will likely result in
555         it failing with an exit code of 1 indicating the measurement  is  in‐
556         valid
557
5585 - Domain is in incorrect state to be measured
559
560         The  domain  has to be running in order to validate a launch measure‐
561         ment.
562
5636 - unexpected error occurred in the code
564
565         A logic flaw in this program means it is unable to complete the vali‐
566         dation  of the measurement. This is a bug which should be reported to
567         the maintainers.
568

AUTHOR

570       Daniel P. Berrangé
571

BUGS

573       Please report all bugs you discover.  This should be done via either:
574
575       1. the mailing list
576
577          https://libvirt.org/contact.html
578
579       2. the bug tracker
580
581          https://libvirt.org/bugs.html
582
583       Alternatively, you may report bugs to your software distributor /  ven‐
584       dor.
585
587       Copyright (C) 2022 by Red Hat, Inc.
588

LICENSE

590       virt-qemu-sev-validate  is  distributed under the terms of the GNU LGPL
591       v2.1+.  This is free software; see the source for  copying  conditions.
592       There  is  NO  warranty;  not even for MERCHANTABILITY or FITNESS FOR A
593       PARTICULAR PURPOSE
594

SEE ALSO

596       virsh(1), SEV launch security usage, https://www.libvirt.org/
597
598
599
600
601                                                     VIRT-QEMU-SEV-VALIDATE(1)
Impressum