xref: /qemu/docs/specs/spdm.rst (revision 4f947b10)
1*4f947b10SWilfred Mallawa======================================================
2*4f947b10SWilfred MallawaQEMU Security Protocols and Data Models (SPDM) Support
3*4f947b10SWilfred Mallawa======================================================
4*4f947b10SWilfred Mallawa
5*4f947b10SWilfred MallawaSPDM enables authentication, attestation and key exchange to assist in
6*4f947b10SWilfred Mallawaproviding infrastructure security enablement. It's a standard published
7*4f947b10SWilfred Mallawaby the `DMTF`_.
8*4f947b10SWilfred Mallawa
9*4f947b10SWilfred MallawaQEMU supports connecting to a SPDM responder implementation. This allows an
10*4f947b10SWilfred Mallawaexternal application to emulate the SPDM responder logic for an SPDM device.
11*4f947b10SWilfred Mallawa
12*4f947b10SWilfred MallawaSetting up a SPDM server
13*4f947b10SWilfred Mallawa========================
14*4f947b10SWilfred Mallawa
15*4f947b10SWilfred MallawaWhen using QEMU with SPDM devices QEMU will connect to a server which
16*4f947b10SWilfred Mallawaimplements the SPDM functionality.
17*4f947b10SWilfred Mallawa
18*4f947b10SWilfred MallawaSPDM-Utils
19*4f947b10SWilfred Mallawa----------
20*4f947b10SWilfred Mallawa
21*4f947b10SWilfred MallawaYou can use `SPDM Utils`_ to emulate a responder. This is the simplest method.
22*4f947b10SWilfred Mallawa
23*4f947b10SWilfred MallawaSPDM-Utils is a Linux applications to manage, test and develop devices
24*4f947b10SWilfred Mallawasupporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
25*4f947b10SWilfred Mallawaand utilises libspdm.
26*4f947b10SWilfred Mallawa
27*4f947b10SWilfred MallawaTo use SPDM-Utils you will need to do the following steps. Details are included
28*4f947b10SWilfred Mallawain the SPDM-Utils README.
29*4f947b10SWilfred Mallawa
30*4f947b10SWilfred Mallawa 1. `Build libspdm`_
31*4f947b10SWilfred Mallawa 2. `Build SPDM Utils`_
32*4f947b10SWilfred Mallawa 3. `Run it as a server`_
33*4f947b10SWilfred Mallawa
34*4f947b10SWilfred Mallawaspdm-emu
35*4f947b10SWilfred Mallawa--------
36*4f947b10SWilfred Mallawa
37*4f947b10SWilfred MallawaYou can use `spdm emu`_ to model the
38*4f947b10SWilfred MallawaSPDM responder.
39*4f947b10SWilfred Mallawa
40*4f947b10SWilfred Mallawa.. code-block:: shell
41*4f947b10SWilfred Mallawa
42*4f947b10SWilfred Mallawa    $ cd spdm-emu
43*4f947b10SWilfred Mallawa    $ git submodule init; git submodule update --recursive
44*4f947b10SWilfred Mallawa    $ mkdir build; cd build
45*4f947b10SWilfred Mallawa    $ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
46*4f947b10SWilfred Mallawa    $ make -j32
47*4f947b10SWilfred Mallawa    $ make copy_sample_key # Build certificates, required for SPDM authentication.
48*4f947b10SWilfred Mallawa
49*4f947b10SWilfred MallawaIt is worth noting that the certificates should be in compliance with
50*4f947b10SWilfred MallawaPCIe r6.1 sec 6.31.3. This means you will need to add the following to
51*4f947b10SWilfred Mallawaopenssl.cnf
52*4f947b10SWilfred Mallawa
53*4f947b10SWilfred Mallawa.. code-block::
54*4f947b10SWilfred Mallawa
55*4f947b10SWilfred Mallawa    subjectAltName = otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
56*4f947b10SWilfred Mallawa    2.23.147 = ASN1:OID:2.23.147
57*4f947b10SWilfred Mallawa
58*4f947b10SWilfred Mallawaand then manually regenerate some certificates with:
59*4f947b10SWilfred Mallawa
60*4f947b10SWilfred Mallawa.. code-block:: shell
61*4f947b10SWilfred Mallawa
62*4f947b10SWilfred Mallawa    $ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
63*4f947b10SWilfred Mallawa        -out end_responder.req -sha384 -batch \
64*4f947b10SWilfred Mallawa        -subj "/CN=DMTF libspdm ECP384 responder cert"
65*4f947b10SWilfred Mallawa
66*4f947b10SWilfred Mallawa    $ openssl x509 -req -in end_responder.req -out end_responder.cert \
67*4f947b10SWilfred Mallawa        -CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
68*4f947b10SWilfred Mallawa        -extensions v3_end -extfile ../openssl.cnf
69*4f947b10SWilfred Mallawa
70*4f947b10SWilfred Mallawa    $ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
71*4f947b10SWilfred Mallawa
72*4f947b10SWilfred Mallawa    $ cat ca.cert.der inter.cert.der end_responder.cert.der > bundle_responder.certchain.der
73*4f947b10SWilfred Mallawa
74*4f947b10SWilfred MallawaYou can use SPDM-Utils instead as it will generate the correct certificates
75*4f947b10SWilfred Mallawaautomatically.
76*4f947b10SWilfred Mallawa
77*4f947b10SWilfred MallawaThe responder can then be launched with
78*4f947b10SWilfred Mallawa
79*4f947b10SWilfred Mallawa.. code-block:: shell
80*4f947b10SWilfred Mallawa
81*4f947b10SWilfred Mallawa    $ cd bin
82*4f947b10SWilfred Mallawa    $ ./spdm_responder_emu --trans PCI_DOE
83*4f947b10SWilfred Mallawa
84*4f947b10SWilfred MallawaConnecting an SPDM NVMe device
85*4f947b10SWilfred Mallawa==============================
86*4f947b10SWilfred Mallawa
87*4f947b10SWilfred MallawaOnce a SPDM server is running we can start QEMU and connect to the server.
88*4f947b10SWilfred Mallawa
89*4f947b10SWilfred MallawaFor an NVMe device first let's setup a block we can use
90*4f947b10SWilfred Mallawa
91*4f947b10SWilfred Mallawa.. code-block:: shell
92*4f947b10SWilfred Mallawa
93*4f947b10SWilfred Mallawa    $ cd qemu-spdm/linux/image
94*4f947b10SWilfred Mallawa    $ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
95*4f947b10SWilfred Mallawa
96*4f947b10SWilfred MallawaThen you can add this to your QEMU command line:
97*4f947b10SWilfred Mallawa
98*4f947b10SWilfred Mallawa.. code-block:: shell
99*4f947b10SWilfred Mallawa
100*4f947b10SWilfred Mallawa    -drive file=blknvme,if=none,id=mynvme,format=raw \
101*4f947b10SWilfred Mallawa        -device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
102*4f947b10SWilfred Mallawa
103*4f947b10SWilfred MallawaAt which point QEMU will try to connect to the SPDM server.
104*4f947b10SWilfred Mallawa
105*4f947b10SWilfred MallawaNote that if using x64-64 you will want to use the q35 machine instead
106*4f947b10SWilfred Mallawaof the default. So the entire QEMU command might look like this
107*4f947b10SWilfred Mallawa
108*4f947b10SWilfred Mallawa.. code-block:: shell
109*4f947b10SWilfred Mallawa
110*4f947b10SWilfred Mallawa    qemu-system-x86_64 -M q35 \
111*4f947b10SWilfred Mallawa        --kernel bzImage \
112*4f947b10SWilfred Mallawa        -drive file=rootfs.ext2,if=virtio,format=raw \
113*4f947b10SWilfred Mallawa        -append "root=/dev/vda console=ttyS0" \
114*4f947b10SWilfred Mallawa        -net none -nographic \
115*4f947b10SWilfred Mallawa        -drive file=blknvme,if=none,id=mynvme,format=raw \
116*4f947b10SWilfred Mallawa        -device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
117*4f947b10SWilfred Mallawa
118*4f947b10SWilfred Mallawa.. _DMTF:
119*4f947b10SWilfred Mallawa   https://www.dmtf.org/standards/SPDM
120*4f947b10SWilfred Mallawa
121*4f947b10SWilfred Mallawa.. _SPDM Utils:
122*4f947b10SWilfred Mallawa   https://github.com/westerndigitalcorporation/spdm-utils
123*4f947b10SWilfred Mallawa
124*4f947b10SWilfred Mallawa.. _spdm emu:
125*4f947b10SWilfred Mallawa   https://github.com/dmtf/spdm-emu
126*4f947b10SWilfred Mallawa
127*4f947b10SWilfred Mallawa.. _Build libspdm:
128*4f947b10SWilfred Mallawa   https://github.com/westerndigitalcorporation/spdm-utils?tab=readme-ov-file#build-libspdm
129*4f947b10SWilfred Mallawa
130*4f947b10SWilfred Mallawa.. _Build SPDM Utils:
131*4f947b10SWilfred Mallawa   https://github.com/westerndigitalcorporation/spdm-utils?tab=readme-ov-file#build-the-binary
132*4f947b10SWilfred Mallawa
133*4f947b10SWilfred Mallawa.. _Run it as a server:
134*4f947b10SWilfred Mallawa   https://github.com/westerndigitalcorporation/spdm-utils#qemu-spdm-device-emulation
135