1VIRT-QEMU-SEV-VALIDATE(1) Virtualization Support VIRT-QEMU-SEV-VALIDATE(1)
2
3
4
6 virt-qemu-sev-validate - validate a domain AMD SEV launch measurement
7
9 virt-qemu-sev-validate [OPTIONS]
10
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
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
188 • luks-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
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-qemu-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-qemu-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-qemu-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-qemu-sev-validate \
286 --firmware 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 --inject-secret 736869e5-84f0-4973-92ec-06879ce3da0b: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-qemu-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-qemu-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-qemu-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-qemu-sev-validate \
354 --connect qemu+ssh://root@some.remote.host/system \
355 --firmware OVMF.sev.fd \
356 --tk this-guest-tk.bin \
357 --domain fedora34x86_64 \
358 --inject-secret 736869e5-84f0-4973-92ec-06879ce3da0b: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-qemu-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-qemu-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-qemu-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-qemu-sev-validate \
404 --insecure \
405 --tk this-guest-tk.bin \
406 --domain fedora34x86_64 \
407 --inject-secret 736869e5-84f0-4973-92ec-06879ce3da0b:passwd.txt
408
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
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
525 • 1 - 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
530 • 2 - 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
535 • 3 - 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
545 • 4 - 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
558 • 5 - 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
563 • 6 - 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
570 Daniel P. Berrangé
571
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
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
596 virsh(1), SEV launch security usage, https://libvirt.org/
597
598
599
600
601 VIRT-QEMU-SEV-VALIDATE(1)