Skip to content

Commit

Permalink
Merge pull request #19 from ultravioletrs/attest-hal
Browse files Browse the repository at this point in the history
CUBE - 7 - Implement Attestation
  • Loading branch information
drasko authored Oct 4, 2024
2 parents 2b23ec9 + 9f2b480 commit 6b6c447
Show file tree
Hide file tree
Showing 19 changed files with 396 additions and 19 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ acme.json

# Proxy Build
proxy/build

# Filesystem
*.ext4
80 changes: 80 additions & 0 deletions buildroot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Buildroot

To build the HAL for Linux, you need to install [Buildroot](https://buildroot.org/). Checkout [README.md](./linux/README.md) for more information.

## To run using qemu

After following the steps in [README.md](./linux/README.md), you will have bzImage and rootfs.cpio.gz files.

Next we need to create a filesystem image. We will use `mkfs.ext4` to create the filesystem image.

```bash
dd if=/dev/zero of=rootfs.img bs=1M count=30720
mkfs.ext4 ./rootfs.img
```

Now we can run the QEMU VM with the filesystem image.

```bash
sudo bash buildroot/qemu.sh start_cvm
```

If you want to start a normal VM, you can run:

```bash
sudo bash buildroot/qemu.sh start
```

Login to the VM using the following credentials:

- Username: `root`

Attest the VM by running the following command:

```bash
bash /cube/attest.sh
```

You will see a report similar to the following:

```bash
The AMD ARK was self-signed!
The AMD ASK was signed by the AMD ARK!
The VCEK was signed by the AMD ASK!
Reported TCB Boot Loader from certificate matches the attestation report.
Reported TCB TEE from certificate matches the attestation report.
Reported TCB SNP from certificate matches the attestation report.
Reported TCB Microcode from certificate matches the attestation report.
Chip ID from certificate matches the attestation report.
VEK signed the Attestation Report!
Measurement from SNP Attestation Report: daa2e216eafd8c6404b72157a130500ab0c0944064c8e1009ebf5e910371caf57a6711654108a01a69baaa1a05759cf0
```

Clone the repository. Since this is a private repository, you need to create a classic personal access token with `repo` and `read:packages` permissions.

```bash
git clone https://github.com/ultravioletrs/cube.git
```

Your username is your github username and your password is the access token you generated in step above.

Login to the docker registry

```bash
docker login ghcr.io
```

Your username is your github username and your password is the access token you generated in step above.

Pull the docker images

```bash
cd cube/docker-compose/
docker compose pull
```

Start the docker composition

```bash
docker compose up -d
```
3 changes: 2 additions & 1 deletion buildroot/linux/Config.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@

source "$BR2_EXTERNAL_CUBE_PATH/package/setup/Config.in"
source "$BR2_EXTERNAL_CUBE_PATH/package/snpguest/Config.in"
2 changes: 1 addition & 1 deletion buildroot/linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ HAL uses [Buildroot](https://buildroot.org/)'s [_External Tree_ mechanism](https

```bash
git clone https://gitlab.com/buildroot.org/buildroot.git
git clone https://github.com/ultravioletrs/cube.git
cd buildroot
git checkout 2023.08
make BR2_EXTERNAL=../cube/buildroot/linux cube_defconfig
# Execute 'make menuconfig' only if you want to make additional configuration changes to Buildroot.
make menuconfig
Expand Down
11 changes: 0 additions & 11 deletions buildroot/linux/board/cube/README.md

This file was deleted.

13 changes: 13 additions & 0 deletions buildroot/linux/board/cube/linux.config
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_AUTOFS4_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
Expand Down Expand Up @@ -65,3 +66,15 @@ CONFIG_PREEMPT_DYNAMIC=n
CONFIG_DEBUG_PREEMPT=n
CONFIG_CGROUP_MISC=y
CONFIG_X86_CPUID=y
CONFIG_X86_MSR=y

CONFIG_KERNEL_EXT4_FS_SECURITY=y
CONFIG_EXT4_FS_SECURITY=y

CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_DEBUG=y
CONFIG_QUOTA_TREE=y
CONFIG_QFMT_V2=y
CONFIG_EXT4_FS_QUOTA=y
7 changes: 7 additions & 0 deletions buildroot/linux/board/cube/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Run the emulation with:

qemu-system-x86_64 -M pc -kernel output/images/bzImage -drive file=output/images/rootfs.ext2,if=virtio,format=raw -append "rootwait root=/dev/vda console=tty1 console=ttyS0" -serial stdio -net nic,model=virtio -net user # cube_defconfig

Optionally add -smp N to emulate a SMP system with N CPUs.

The login prompt will appear in the graphical window.
27 changes: 26 additions & 1 deletion buildroot/linux/configs/cube_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
BR2_x86_64=y

# System
BR2_TARGET_GENERIC_HOSTNAME="Cube AI"
BR2_TARGET_GENERIC_HOSTNAME="cube"
BR2_TARGET_GENERIC_ISSUE="Welcome to Cube AI"
BR2_PACKAGE_DHCP=y
BR2_PACKAGE_DHCP_CLIENT=y
Expand Down Expand Up @@ -39,6 +39,7 @@ BR2_LINUX_KERNEL_PATCH=""
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_CUBE_PATH)/board/cube/linux.config"
BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y

# host-qemu for gitlab testing
BR2_PACKAGE_HOST_QEMU=y
Expand All @@ -54,3 +55,27 @@ BR2_PACKAGE_DOCKER_ENGINE=y
BR2_PACKAGE_CONTAINERD=y
BR2_PACKAGE_RUNC=y
BR2_PACKAGE_IPTABLES=y

BR2_PACKAGE_GIT=y

BR2_PACKAGE_LIBCURL=y
BR2_PACKAGE_OPENSSL=y
BR2_PACKAGE_LIBOPENSSL=y
BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBRESSL_ARCH_SUPPORTS=y
BR2_PACKAGE_HAS_OPENSSL=y
BR2_PACKAGE_PROVIDES_OPENSSL="libopenssl"
BR2_PACKAGE_PROVIDES_HOST_OPENSSL="host-libopenssl"

BR2_PACKAGE_QUOTA=y
BR2_PACKAGE_QUOTATOOL=y

BR2_TARGET_GENERIC_PASSWD_SHA512=y
BR2_TARGET_GENERIC_PASSWD_METHOD="sha-512"

BR2_TARGET_ENABLE_ROOT_LOGIN=y
BR2_TARGET_GENERIC_ROOT_PASSWD="m2N2Lfno"

BR2_PACKAGE_HOST_MKPASSWD=y

BR2_PACKAGE_HTOP=y
2 changes: 1 addition & 1 deletion buildroot/linux/external.desc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
name: Cube
name: CUBE
desc: External buildroot tree for Cube AI
2 changes: 1 addition & 1 deletion buildroot/linux/external.mk
Original file line number Diff line number Diff line change
@@ -1 +1 @@

include $(sort $(wildcard $(BR2_EXTERNAL_CUBE_PATH)/package/*/*.mk))
9 changes: 9 additions & 0 deletions buildroot/linux/package/setup/Config.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config BR2_PACKAGE_SETUP
bool "setup"
default y
help
This Setup package it used to setup the Docker environment used in the HAL
It does the following:
- Start networking
- Mounts the rootfs.ext4 file system
- Configure the docker daemon to use the rootfs.ext4 file system
11 changes: 11 additions & 0 deletions buildroot/linux/package/setup/setup.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
define SETUP_INSTALL_TARGET_CMDS
mkdir -p $(TARGET_DIR)/cube/
endef

define SETUP_INSTALL_INIT_SYSTEMD
cp ../cube/buildroot/linux/systemd/cube.service $(TARGET_DIR)/usr/lib/systemd/system/cube.service
cp ../cube/buildroot/linux/systemd/setup-cube.sh $(TARGET_DIR)/cube/setup-cube.sh
cp ../cube/buildroot/linux/systemd/attest.sh $(TARGET_DIR)/cube/attest.sh
endef

$(eval $(generic-package))
8 changes: 8 additions & 0 deletions buildroot/linux/package/snpguest/Config.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
config BR2_PACKAGE_SNPGUEST
bool "snpguest"
default y
depends on BR2_PACKAGE_HOST_RUSTC_TARGET_ARCH_SUPPORTS
select BR2_PACKAGE_HOST_RUSTC
help
snpguest is a CLI tool for interacting with SEV-SNP guest environment
https://github.com/virtee/snpguest
17 changes: 17 additions & 0 deletions buildroot/linux/package/snpguest/snpguest.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
SNPGUEST_VERSION = main
SNPGUEST_SITE = $(call github,virtee,snpguest,$(SNPGUEST_VERSION))
SNPGUEST_LICENSE = Apache-2.0
SNPGUEST_LICENSE_FILES = LICENSE

SNPGUEST_DEPENDENCIES = host-rustc

define SNPGUEST_BUILD_CMDS
$(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) \
$(HOST_DIR)/bin/cargo build --release --manifest-path=$(@D)/Cargo.toml
endef

define SNPGUEST_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/target/release/snpguest $(TARGET_DIR)/usr/bin/snpguest
endef

$(eval $(generic-package))
21 changes: 21 additions & 0 deletions buildroot/linux/systemd/attest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh

function attest() {
snpguest report attestation-report.bin request-data.txt --random

snpguest fetch ca pem milan . --endorser vcek
snpguest fetch vcek pem milan . attestation-report.bin

# Verifies that ARK, ASK and VCEK are all properly signed
snpguest verify certs .

# Verifies the attestation-report trusted compute base matches vcek
snpguest verify attestation . attestation-report.bin

snpguest_report_measurement=$(snpguest display report attestation-report.bin | tr '\n' ' ' | sed "s|.*Measurement:\(.*\)Host Data.*|\1\n|g" | sed "s| ||g")
# Remove any special characters and print the value
snpguest_report_measurement=$(echo ${snpguest_report_measurement} | sed $'s/[^[:print:]\t]//g')
echo -e "Measurement from SNP Attestation Report: ${snpguest_report_measurement}\n"
}

attest
10 changes: 10 additions & 0 deletions buildroot/linux/systemd/cube.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Cube Network Agent
After=network.target
Before=docker.service

[Service]
ExecStart=/cube/setup-cube.sh

[Install]
WantedBy=default.target
44 changes: 44 additions & 0 deletions buildroot/linux/systemd/setup-cube.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh

# IFACES are all network interfaces excluding lo (LOOPBACK) and sit interfaces
IFACES=$(ip link show | grep -vE 'LOOPBACK|sit*' | awk -F': ' '{print $2}')

# This for loop brings up all network interfaces in IFACES and dhclient obtains an IP address for the every interface
for IFACE in $IFACES; do
STATE=$(ip link show $IFACE | grep DOWN)
if [ -n "$STATE" ]; then
ip link set $IFACE up
fi

IP_ADDR=$(ip addr show $IFACE | grep 'inet ')
if [ -z "$IP_ADDR" ]; then
dhclient $IFACE
fi
done

# Change the docker.service file to allow the Docker to run in RAM
mkdir -p /etc/systemd/system/docker.service.d

# Create or overwrite the override.conf file with the new Environment variable
tee /etc/systemd/system/docker.service.d/override.conf > /dev/null <<EOF
[Service]
Environment=DOCKER_RAMDISK=true
EOF

systemctl daemon-reload

# Mount filesystem
mkdir -p /mnt/docker
mount /dev/vda /mnt/docker

systemctl stop docker

mkdir -p /etc/docker

tee /etc/docker/daemon.json > /dev/null <<EOF
{
"data-root": "/mnt/docker"
}
EOF

systemctl start docker
Loading

0 comments on commit 6b6c447

Please sign in to comment.