coconut-svsm / svsm

COCONUT-SVSM
MIT License
122 stars 42 forks source link

Attestation driver and proxy (with KBS attestation) #528

Open tylerfanelli opened 1 day ago

tylerfanelli commented 1 day ago

This series introduces the attestation module in SVSM as well as the attestation proxy to facilitate communication between SVSM and a remote server for TEE evidence evaluation.

Abstract

To unlock early persistent state in SVSM (for example, persistent vTPM data), an attestation of the launch environment must take place to ensure that SVSM is running on trusted hardware and launched correctly. As SVSM does not have a network stack available, we have opted to introduce a proxy that would run on the host (for now, although this may change as other options are explored) and facilitate attestation between SVSM and a remote verification server such as KBS.

Much of what is implemented here is described in the Early Attestation and Measurement Architecture in COCONUT SVSM document.

Changes

There are three main modules introduced into SVSM with this series:

Attestation

There exists two different phases of attestation:

As there exists multiple protocols for TEE attestation, the proxy was built to be configurable to different protocols. As such, SVSM can be completely agnostic of the attestation protocol used. This is done by splitting the proxy up into two main components:

                                          ┌───────────┐
┌────┐               ┌─────┐              │Attestation│
│SVSM│◄─────────────►│Proxy│◄────────────►│Server     │
└────┘               └─────┘              └───────────┘
      │             │       │            │             
      └─────────────┘       └────────────┘             
         FRONT-END             BACK-END                
       (independent          (dependent                
       of attestation        on attestation            
       server)               server and                
                             protocol)        

Try for yourself

To try for yourself, I've set up a quick demo with a "dummy" KBS server that requires no configuration and simply returns a secret: hello, SVSM! that SVSM can then print. This requires a SEV-SNP machine with a SVSM-enabled kernel.

  1. In one window, clone and run the dummy KBS server used for testing:

    $ git clone https://github.com/tylerfanelli/kbs-test.git
    $ cd kbs-test
    $ cargo run

    This will run a "KBS server" (at least suitable for testing) at http://0.0.0.0:8080.

  2. Clone and build this branch of SVSM

    
    $ git clone https://github.com/tylerfanelli/svsm.git

... build OVMF, qemu, SVSM IGVM, etc...

$ FW_FILE=... make

3. Run the proxy on the host

$ cd svsm $ cargo build --target=x86_64-unknown-linux-gnu -p aproxy $ target/x86_64-unknown-linux-gnu/debug/aproxy --protocol kbs --url http://0.0.0.0:8080 --unix /tmp/svsm-proxy.sock --force

This runs the proxy with the following specified in the arguments:

- `--url http://0.0.0.0:8080`: The attestation server is running at http://0.0.0.0:8080.
- `--protocol kbs`: The attestation server communicates via the KBS protocol, configure the backend to use the KBS protocol.
- `--unix /tmp/svsm-proxy.sock`: Listen for messages from SVSM on a socket created in file `/tmp/svsm-proxy-sock`.
- `--force`: Remove the `/tmp/svsm-proxy.sock` file (if it already exists) before creating the socket.

4. Run a guest with SVSM

Initially, SVSM communicates over the COM3 serial port. The attestation proxy socket will need to be available in the correct `-serial` port argument position to ensure it communicates with the right socket.

$ sudo ./qemu/build/qemu-system-x86_64 \ -enable-kvm \ -cpu EPYC-v4 \ -machine q35,confidential-guest-support=sev0,memory-backend=ram1 \ -object memory-backend-memfd,id=ram1,size=8G,share=true,prealloc=false,reserve=false \ -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,igvm-file=$IGVM \ -smp 8 \ -no-reboot \ -netdev user,id=vmnic -device e1000,netdev=vmnic,romfile= \ -drive file=$QCOW2,if=none,id=disk0,format=qcow2,snapshot=off \ -device virtio-scsi-pci,id=scsi0,disable-legacy=on,iommu_platform=on \ -device scsi-hd,drive=disk0,bootindex=0 \ -vga std \ -serial stdio \ -serial pty \ -serial unix:/tmp/svsm-proxy.sock \


### NOTE

Upon running, you may think that there is a hang in the proxy, as SVSM seems to freeze:

[SVSM] Validating 0x0000000000800000-0x0000000000809000 [SVSM] Validating 0x000000000080a000-0x0000000000820000 [SVSM] Flash region 0 at 0x00000000ffc00000 size 000000000000400000



This is not a hang, but rather, the creation of a 3072-bit RSA (as well as decryption with this key) is very slow at present (sometimes taking around ~1 minute for creation+decryption in my tests). Eventually, SVSM should begin running again and show the following message:

`[SVSM] Decrypted secret from attestation server: hello, SVSM!`

And thus we have decrypted secrets from a KBS attestation server (via the proxy).

### TODO

The only purpose of https://github.com/coconut-svsm/svsm/commit/b19279210d84e5f82b1c29a177aba6e9ba5b66b0  is for others to see a secret decrypted from the server available and printed by SVSM. This must be removed once others have tried for themselves.

Other TODOs before this can be considered for merging:

- [ ] Hide the `kernel/attest` module behind a feature flag in the `kernel` module. Perhaps a feature called `attest`?
- [ ] Make relevant changes in SVSM `Makefile` to build the `kernel` module with the `attest` feature.
- [ ] Ensure that aproxy's KBS backend works with production KBS servers such as [Trustee](https://github.com/confidential-containers/trustee)

Future work:

- Right now, SVSM communicates with the proxy over a serial port. Work on virtio-vsock support to use that instead.

Co-developed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Tyler Fanelli <tfanelli@redhat.com>

cc/ @stefano-garzarella @joergroedel @deeglaze @berrange @fitzthum @stringlytyped @IT302 @Isaac-Matthews
berrange commented 13 hours ago

This is not a hang, but rather, the creation of a 3072-bit RSA (as well as decryption with this key) is very slow at present (sometimes taking around ~1 minute for creation+decryption in my tests).

Do you have any insight on why this is so slow, or is it remaining for a future debugging effort ?

tlendacky commented 12 hours ago

This is not a hang, but rather, the creation of a 3072-bit RSA (as well as decryption with this key) is very slow at present (sometimes taking around ~1 minute for creation+decryption in my tests).

Do you have any insight on why this is so slow, or is it remaining for a future debugging effort ?

Have you tried using RdRand instead of RdSeed?

berrange commented 10 hours ago

There are three main modules introduced into SVSM with this series:

  • kernel/attest.rs: Attestation driver that communicates with the proxy through the COM3 serial port. This will eventually communicate over another channel (virtio-vsock, etc..) when available.
  • aproxy: Attestation proxy that runs on a host and facilitates communication with a remote attestation server.
  • libaproxy: Shared types between kernel/attest.rs and aproxy for (de)serialization of data.

As a general point, I wonder whether these should really all live in the 'svsm' git repo.

Consider that the execution context of the proxy is the host OS, and the context of SVSM's driver is in guest VM. With this we're defining an ABI for a protocol between the host OS and guest VM, that potentially needs to remain stable & backwards compatible more or less indefinitely (forever). ie it is unlikely to be viable to mandate that the deployed host side proxy is upgraded in lock-step with SVSM releases, and thus we need to expect mis-matched releases of the two and ensure things continue to work. Splitting the proxy off as a separate repository, and defining a formal document specifying the interaction between SVSM & the proxy, will re-inforce the message that these two sides are independent and need to retain backwards compatibility as their respective impls evolve over time.