Skip to main content

tools for confidential virtual machines

Project description

Prepare OS image to run with encrypted root volume

Purpose

This tool prepares RHEL/Fedora image to run with encrypted root volume. The key to the volume is sealed to the target TPM.

Image pre-requisites

  • GUID Partition Table (GPT)
  • Image should contain ESP partition, GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B
  • Image should contain 'Linux root (x86-64)' partition, GUID 4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709
  • Root partition should have ext4 filesystem
  • The expected post boot PCR7 (sha256) value must be known, it must passed to the 'deploy' stage as '--pcr7' option or via an override file on the ESP ('--pcrs-json' option).
  • Alternatively, PCR7 value can be predicted ('--pcr7 auto' option), this requires providing either UEFI profile ('--uefi-profile') or Azure Disk Profile ('--az-disk-profile'), examples are present in 'test-data'.
  • PCR4 can also be used in the set of PCRs for root volume key sealing. Its expected value can be specified directly ('--pcr4 sha256value') or can be predicted by passing '--pcr4 auto' option.
  • ESP may contain a JSON file containing the expected PCR values in JSON format:
{
    "bank": "sha256",
    "pcrs": [4, 7],
    "4": "0x7A94FFE8A7729A566D3D3C577FCB4B6B1E671F31540375F80EAE6382AB785E35",
    "7": "0xB5710BF57D25623E4019027DA116821FA99F5C81E9E38B87671CC574F9281439"
}

The name of the file can be passed as '--pcrs-json' option to 'deploy' stage, in that case values from the file override '--pcr4'/'--pcr7' values from the command line. The file can specify additional PCRs.

  • ESP may contain "efivars.json" file in Azure format:
{
    "type": "Microsoft.Compute/disks",
    "properties": {
        "uefiSettings": {
            "Boot0004": {
                "guid": "Yd/ki8qT0hGqDQDgmAMrjA==",
                "attributes": "Bw==",
                "value": "AQAAAGIAUwBoAGkAbQAgAGIAbwBvAHQAIAB0AG8AIAA1AC4AMQA0AC4AMAAtADIAMwA4AF8AdQBrAGkAXwB0AGUAcwB0ADEAOQAuAGUAbAA5AC4AeAA4ADYAXwA2ADQAAAAEASoAAgAAAAAoAAAAAAAAAOAHAAAAAABibF3EAi9J4o1TPhDbQRiuAgIEBDQAXABFAEYASQBcAHIAZQBkAGgAYQB0AFwAcwBoAGkAbQB4ADYANAAuAGUAZgBpAAAAf/8EAFwARQBGAEkAXABMAGkAbgB1AHgAXAB2AG0AbABpAG4AdQB6AC0ANQAuADEANAAuADAALQAyADMAOABfAHUAawBpAF8AdABlAHMAdAAxADkALgBlAGwAOQAuAHgAOAA2AF8ANgA0AC0AdgBpAHIAdAAuAGUAZgBpAAAA"
            }
        }
    }
}

in case it does, its size and content will be written to a special 'Linux reserved' GUID 8DA63339-0007-60C0-C436-083AC8230908) partition starting at offset 2048 * 512 = 1048576.

TPM2

SRK public key is required for 'deploy' phase. It can be obtained with

$ systemd-analyze srk > public.srk  

or

$ tpm2_readpublic -c 0x81000001 -o public.srk -t primary.handle

Basic usage

$ ./encrypt-rhel-image.py encrypt /path/to/image.vhd  
$ ./encrypt-rhel-image.py deploy -s /path/to/public.srk --pcr7 auto /path/to/image.vhd  

Running in a container

The tool can run in a container and 'Containerfile.fedora'/'Containerfile.c9s' are provided as examples to build it. Optionally, 'quay.io/vkuznets/encrypt-rhel-image' (c9s based) can be used directly. Here is an example for Ubuntu 20.04. Assuming all data is stored in '/data' on the host,

# apt update && apt install docker.io  
# docker pull quay.io/vkuznets/encrypt-rhel-image:latest  
# modprobe nbd  
# docker run -it --privileged --mount type=bind,source=/data,target=/data --mount type=bind,source=/run/udev,target=/run/udev --mount type=bind,source=/dev,target=/dev quay.io/vkuznets/encrypt-rhel-image:latest /usr/bin/encrypt-rhel-image.py encrypt -v /data/image.qcow2  
# docker run -it --privileged --mount type=bind,source=/data,target=/data --mount type=bind,source=/run/udev,target=/run/udev --mount type=bind,source=/dev,target=/dev quay.io/vkuznets/encrypt-rhel-image:latest /usr/bin/encrypt-rhel-image.py deploy -s /data/public.srk -r /data/recovery_key --pcr7 auto --uefi-profile /data/uefi-profile-ovmf.json -v /data/image.qcow2  

Red Hat UBI can be used for the 'deploy' phase. As qemu-nbd is currently missing in the UBI, the image must be passed to the container as a device. RHEL UBI container can also be used sealing:

# podman build -f Containerfile.ubi9 -t encrypt-rhel-image-ubi9  
# qemu-nbd -c /dev/nbd2 /var/lib/libvirt/images/rhel9-azure-cvm-20240820-2.qcow2  
# podman run -it --privileged --mount type=bind,source=/var/lib/libvirt/images,target=/mnt --mount type=bind,source=/root,target=/root --mount type=bind,source=/run/udev,target=/run/udev --mount type=bind,source=/dev,target=/dev localhost/encrypt-rhel-image-ubi9:latest /usr/bin/encrypt-rhel-image.py deploy -s /root/public.srk -r /root/recovery_key --pcr7 auto --uefi-profile /root/encrypt-rhel-image/test-data/uefi-profiles/uefi-profile-ovmf.json -v /dev/nbd2  
# qemu-nbd --disconnect /dev/nbd2  

Testing

The tool comes with unit tests which can be executed with 'pytest'. Note that 'test-data' submodule must be checked out.

$ git submodule update
$ pytest

Dependencies

Basic:

  • python3.x

'Encrypt' phase:

  • qemu-nbd
  • e2fsprogs
  • cryptsetup
  • growpart (optional)

'Deploy' phase additionally requires:

  • openssl
  • systemd-cryptenroll >= 255

TODO:

  • Add support for UKI extensions ($ESP/EFI/Linux/<uki-name.efi>.extra.d/) to PCR4/7 predictors.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cvmutils-0.1.2.tar.gz (29.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cvmutils-0.1.2-py3-none-any.whl (29.6 kB view details)

Uploaded Python 3

File details

Details for the file cvmutils-0.1.2.tar.gz.

File metadata

  • Download URL: cvmutils-0.1.2.tar.gz
  • Upload date:
  • Size: 29.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.9

File hashes

Hashes for cvmutils-0.1.2.tar.gz
Algorithm Hash digest
SHA256 2126251f1f5d7bc5b9f8b88306b1bb02a54abd96a3a21a27a9f3098a28e20b27
MD5 13c104904de94d6ea61f185f801dd676
BLAKE2b-256 c4a526bb9f133b4035a903d57a6afa36f7a719ad3537ec26113549847c16b3b4

See more details on using hashes here.

File details

Details for the file cvmutils-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: cvmutils-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 29.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.9

File hashes

Hashes for cvmutils-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1d215399e33ab808ec9fab485e17235cdc3bff1867754a1250200a7ade528784
MD5 3c2156e98263a884249736f784a55d7e
BLAKE2b-256 34086d28b33c79fb7ba98b0ce4bccc44ec27add33e4292d8dd2c3b3b03edd58c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page