Skip to content

acompany-develop/Humane-RAChain-NS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Humane NVIDIA-CC/SEV-SNP Remote Attestation Chain Framework (Humane-RAChain-NS)

Note: An English version of this document is provided in the first half of this file. A Japanese version follows after the separator below. 日本語版は本ドキュメントの後半に掲載しています。

This repository provides a Remote Attestation (RA) chain framework that performs RA against both NVIDIA Confidential Computing (a GPU TEE supported from the NVIDIA Hopper architecture onward; hereafter "NCC") and AMD SEV-SNP, primarily intended for execution on Azure's Standard_NCC40ads_H100_v5.

NCC requires that attestation be performed from a Confidential VM (CVM) such as an SEV-SNP CVM; a remote user (Relying Party) of the CVM cannot perform RA directly against NCC without going through the CVM. SEV-SNP itself also has a large Trusted Computing Base (TCB) and a multi-stage boot sequence, which makes performing security best-practice RA — while accounting for the environment — extremely difficult, and there are few existing frameworks for it.

To address this, Humane-RAChain-NS first performs attestation against NCC, then binds the resulting evidence and verification result to a trust chain anchored at SEV-SNP (specifically, the AMD Root Key) — namely, a vTPM Quote whose Attestation Key is bound to the SEV-SNP Attestation Report. By then verifying the SEV-SNP Attestation Report and the vTPM Quote as appropriately as possible, trust can be established in a chained manner — from NCC, through SEV-SNP, through the VM's lower-layer components (vTPM, OVMF, etc.), the kernel, and finally the workload of interest — thereby establishing an RA chain.

At this time, operation on platforms other than Azure is not supported.

What Humane-RAChain-NS Achieves

Specifically, Humane-RAChain-NS performs processing that satisfies the following assumptions and goals. In principle, all of the processing below is executed automatically by Humane-RAChain-NS; developers and users who simply use this library do not need to be aware of (or implement) these steps.

  • The flow is: first the SEV-SNP CVM performs attestation of the NCC, and then the CVM itself (SEV-SNP) is attested, thereby establishing an RA chain from the NCC up to the Relying Party. Therefore, NCC attestation is performed first.

  • Using NVIDIA's Attestation SDK, the CVM obtains the NCC Evidence (equivalent to a Quote in SGX). Humane-RAChain-NS then requests NRAS (NVIDIA Remote Attestation Service) to verify this Evidence (Remote GPU Attestation). This realizes CVM↔NCC attestation. The client (Relying Party) sends a nonce, which the CVM uses, as countermeasure against replay attacks on the Evidence.

    • The hash of this Evidence and verification result (Attestation Report) is stored in the PCR (Platform Configuration Register) of a vTPM whose trust is anchored at AMD (hereafter simply "vTPM"). By using this data along with the TPM Quote, its integrity is guaranteed.

    • Regarding PCR banks: each hash algorithm (sha1, sha256, sha384) has its own dedicated bank, but Humane-RAChain-NS uses the sha256 bank uniformly.

  • For TLS communication between the CVM and the Relying Party, a self-signed certificate dynamically generated per session by the CVM and a TLS session (including the TLS channel key) are used. Since the self-signed certificate is hash-measured by the vTPM's PCR, the Relying Party can be confident — as long as it has accepted RA and continues TLS communication tied to this self-signed certificate — that the communication peer is the expected CVM.

    • The binding between the self-signed certificate and the TLS encryption key is automatically guaranteed by verifying — via RA — that Humane-RAChain-NS is operating correctly.
  • After NCC attestation, the CVM next generates the SEV-SNP Attestation Report (a structure that resembles a combined Quote and Attestation Report in SGX). On Azure CVMs, it is generated wrapped inside an HCL Report (a structure consisting of the SEV-SNP Report, a JSON bound into REPORT_DATA, hash-algorithm and TEE-type metadata, etc.). At the same time, the CVM also obtains the certificate for the VCEK used to sign the Attestation Report (VCEK Cert) and the TPM AK (Attestation Key) public key, which is also embedded in (i.e. bound to AMD's trust chain through) the SEV-SNP Attestation Report.

    • These are delivered to the Relying Party. The implementation has the Relying Party verify the authenticity of the SEV-SNP Attestation Report and the TPM AK on the Relying Party side (the Relying Party performs verification of attestation).
  • Once the SEV-SNP-related attestation data has been acquired, the runtime workload — including Humane-RAChain-NS itself — is then measured into vTPM PCR bank 23. Specifically, the following data and files are sequentially Extend-ed into PCR23, so that PCR23 can track the integrity of the required components:

    • The TLS self-signed certificate dynamically generated inside the CVM. As noted above, this is data that can be referenced to uniquely identify the session with the CVM.
    • The VCEK Cert corresponding to the VCEK used to sign the SEV-SNP Attestation Report.
    • The TPM AK public key.
    • The Evidence from NCC Attestation.
    • The NCC Attestation Report.
    • The Humane-RAChain-NS server-side scripts and the NCC Attestation policy.
    • The workload script to run after RA.

    This allows the Relying Party to be confident that the above data definitely originates from the CVM it is communicating with.

  • At this point the SEV-SNP Attestation Report has been generated, the necessary measurements have been registered in the PCRs, and the AK public key — used to sign the TPM Quote based on those PCRs — is bound into the SEV-SNP Attestation Report. So the next step is to actually generate the TPM Quote. When generating the Quote, as with NCC attestation, the nonce sent by the Relying Party is included to prevent replay attacks.

    • By default, the PCR banks included in the TPM Quote are 0–10, 12, 14, and 23. PCR0–7 cover the firmware layer up to just before the guest OS (VMPL0–2). PCR10 holds the IMA (Integrity Measurements Architecture) policy (the OS kernel layer and some runtime workloads). PCR23 stores the hash values of the various data registered above. Banks 9, 10, 12, and 14 are included as a precaution because IMA-related changes may cause them to vary. The boot_aggregate entry in the IMA log is the hash of PCR0–9 concatenated, so PCR8 is also included to allow verification.

    • By loading at boot time an IMA policy that targets Humane-RAChain-NS scripts and the runtime workload, a trust chain analogous to Secure Boot / Measured Boot — SEV-SNP → firmware → OS kernel → Humane-RAChain-NS / workload — can be guaranteed at the SEV-SNP level. However, there is currently no mechanism to bind the IMA policy itself, so the trust chain remains incomplete.

    • The firmware layer corresponding to PCR0–7 (which includes OVMF, SVSM, the vTPM implementation itself, etc.) has its source code unpublished by Azure, so on Azure these become so-called self-asserted measurements. However, if used on a cloud where the source is published, fully zero-trust verification can be achieved by also verifying measurements against the source.

  • At this point all the evidence needed to prove the chain from SEV-SNP through Humane-RAChain-NS and the workload is available, so the CVM transmits the following data to the Relying Party:

    • The dynamically generated self-signed TLS certificate.
    • The VCEK Cert.
    • The HCL Report (including the SEV-SNP Attestation Report).
    • The NCC Attestation Evidence and Attestation Report.
    • The TPM AK public key.
    • The TPM Quote.
    • The IMA policy and measurement log.
  • Ultimately, Linux IMA can measure all runtime content from the OS kernel onward, so depending on IMA policy configuration, Extending into PCR23 is semantically redundant. However, IMA logs tend to be extremely long, which makes manual inspection burdensome. From a usability standpoint, we therefore adopt a two-tier configuration: minimal content (as described above) is also Extended into PCR23 for easy inspection, while PCR10 can also be checked if complete and exhaustive verification is desired.

  • After receiving the above data from the CVM, the Relying Party first verifies the VCEK Cert. It is verified using the AMD intermediate CA certificate (ASK) and the AMD root CA certificate (ARK), confirming the authenticity of the VCEK used.

  • Next, using the verified VCEK Cert, the Relying Party verifies the HCL Report.

    • The signature of the SEV-SNP Attestation Report is verified with the VCEK Cert, and the report is checked against the expected SEV-SNP measurement and against expected machine-configuration requirements (SMT disabled, TSME enabled status, vulnerability mitigations status, etc.).
    • The REPORT_DATA in the SEV-SNP Attestation Report is checked against the hash of the JSON (Runtime Claims) in the HCL Report, and the JSON is checked to confirm that the nonce is included as user-data.
  • Next, in order to verify the TPM Quote, the Relying Party first verifies the TPM AK used to sign the TPM Quote. By verifying that the TPM AK bound in the JSON within the SEV-SNP Attestation Report matches the AK received from the CVM (obtained directly from vTPM) as part of the response, the integrity of the TPM AK is verified.

  • After TPM AK verification, the TPM Quote received is verified using the AK's signature. The integrity of the received PCR list is also verified at this time.

  • Once TPM Quote verification is complete, the PCR banks are checked to see if they match the expected hashes.

    • For PCR0–7, strict checking of the firmware layer could in principle be done by logging into the CVM beforehand and obtaining the hash values to compare against the PCR values in the attestation result, but this check is not currently implemented.

    • For PCR23, the expected PCR23 value is computed from (copies of) the files that are the measurement targets. Specifically, the hash is Updated on the client side in the same order in which it was PCR-Extended on the CVM side, and the final hash value is then checked to match the value of PCR bank 23.

    • For PCR10, the authenticity of the IMA log is confirmed by verifying that the PCR value reproduced from the IMA log matches the received PCR10. Then, by checking whether each entry in the IMA log records the expected hash value, workload integrity is guaranteed.

  • Finally, to address the need for the Relying Party to also be able to perform NCC Attestation as a safeguard (for example, users who suspect that the guest OS might somehow bypass NCC Attestation, even though strict Measured Boot would make this unlikely), the Relying Party can also run NCC Attestation on its own. Similar to the CVM side, it sends the NCC Attestation Evidence to NRAS and obtains verification. Since the Evidence includes a Relying Party-specified nonce, the Relying Party can reliably perform NCC Attestation on its own.

Verified Environments

Server (CVM with NCC)

  • OS: Ubuntu 22.04.5 LTS
  • Azure VM instance: Azure Standard_NCC40ads_H100_v5
  • Linux kernel: 6.8.0-1018-azure
  • nvattest CLI: nvattest 1.2.0+1772475102 (Linux/x86_64) (successor of the legacy nv-attestation-sdk)
  • snpguest: version 0.8.2
  • Python: 3.10.12
  • tpm2_pytss: version 2.3.0
  • tpm2-tools: version 5.2-1build1

Server (CVM without NCC)

  • OS: Ubuntu 24.04.1 LTS
  • Azure VM instance: Azure Standard DC2ads_v6
  • Linux kernel: 6.14.0-1017-azure-fde
  • snpguest: v0.10.0
  • Python: v3.12.3
  • tpm2_pytss: Commit c7fd022
  • tpm2-tools: Commit d15fc36 (next release v5.8.0)

Client

Operation on the same machine (environment) as the server has been verified.

Remote operation has also been verified in the following environment:

  • OS: Ubuntu 22.04.3 LTS
  • Azure VM instance: Standard_DC4s_v3
  • Linux kernel: 6.8.0-1018-azure

Other libraries that overlap with the server have been confirmed to work using the versions on the server. For client-side remote operation we have used an Intel SGX instance (Standard_DC4s_v3) due to local environment constraints, but neither the client nor the server requires Intel SGX functionality. The client is implemented assuming execution on an instance with no TEE at all (including SGX).

Use of Python Virtual Environments (venv)

The server and client in this repository manage Python packages collectively via requirements.txt and are designed to run inside a venv. As of Ubuntu 23.04 and later, direct pip install into the system package directory is restricted by default (PEP 668), making venv use essentially mandatory.

The setup instructions that follow assume that a venv is created under Humane-RAChain-NS/server/ for the server and under Humane-RAChain-NS/client/ for the client. The creation, activation, and installation of dependencies into the venv are expected to be performed by the user in advance; scripts like run-server.sh do not activate the venv or run pip install.

If the venv package is not installed, install it with the following command:

sudo apt install -y python3-venv

Installation

Server (CVM)

The description below assumes installation on an Azure NCC instance.

Cloning the Repository

  • Clone the Humane-RAChain-NS repository. The following prerequisite-installation steps assume that the repository has already been cloned.

    git clone https://github.com/acompany-develop/Humane-RAChain-NS.git

Installing Prerequisite Packages

  • If Python or pip is not installed, install them by following the official procedure. Python 3.10.12 is the verified version.

  • Install the prerequisite packages required for TPM operations from Python via apt:

    sudo apt -y install libtss2-dev pkg-config python3-dev
  • Install the following for the TPM operations used when extracting the Measurement (described later):

    sudo apt -y install tpm2-tools
  • The required Python packages are listed in server/requirements.txt (for tpm2-pytss, the latest version is fetched from GitHub to avoid an unfixed bug on PyPI). Create a server venv under the server directory, activate it, and install them collectively:

    cd Humane-RAChain-NS/server/
    python3 -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt

    All subsequent server-side operations (installation of NCC-related packages described below, execution of run-server.sh, etc.) must be performed with source venv/bin/activate already executed.

Granting vTPM Access Permissions

  • Log in as the user who will run Humane-RAChain-NS and run the following commands. This grants vTPM access without sudo. After running, reboot to make the group addition take effect.

    sudo usermod -aG tss $USER
    newgrp tss

Installing NCC-related Packages

If NCC Attestation is not being performed, this section can be skipped.

  • For NCC GPU Attestation, the NVIDIA-distributed nvattest CLI is used (the legacy nv-attestation-sdk is deprecated). nvattest only needs to be placed on PATH as a system binary; it does not need to be installed inside the Python venv. To install, run the following commands as shown on the download page:

    wget https://developer.download.nvidia.com/compute/nvat/1.2.0/local_installers/nvat-repo-ubuntu2204-1-2-local_1.0-1_amd64.deb
    sudo dpkg -i nvat-repo-ubuntu2204-1-2-local_1.0-1_amd64.deb
    sudo cp /var/nvat-local-repo-ubuntu2204-1.2.0/nvat-*-keyring.gpg /usr/share/keyrings/
    sudo apt-get update
    sudo apt-get -y install nvattest

    Note that the above commands are expected to change with version updates, so verifying the actual command at the linked page is recommended. For different OS versions or distributions, make the appropriate selection at the link above and follow the displayed commands.

  • After installation, verify that the binary is visible on PATH with the following command:

    nvattest --version

    Humane-RAChain-NS calls this nvattest from the server-side attester.py via subprocess and performs attestation in two steps:

    1. nvattest collect-evidence to obtain GPU Evidence (equivalent to a Quote in SGX).
    2. nvattest attest --verifier local to verify the authenticity of the Evidence and obtain an Attestation Report.

    By default, this nvattest binary is also Extended into PCR23 (described later), so prepare a version (including distribution) identical to that of the client for client-side recomputation. Alternatively, it can be excluded from the PCR23 extension targets, as described later.

  • Since CUDA Toolkit is not installed by Azure's official procedure, install it for GPU programming with workloads running on Humane-RAChain-NS:

    wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
    sudo dpkg -i cuda-keyring_1.1-1_all.deb
    sudo apt update
    sudo apt -y install cuda-toolkit-13-1

    Running the following will print version info if installation is successful:

    export PATH=/usr/local/cuda-13.1/bin:$PATH
    nvcc --version

IMA Configuration

To measure content beyond the OS kernel — such as user workloads — Linux's IMA feature must be used. Therefore, IMA-related configuration must also be performed.

  • Log into the TD and create a folder named ima under /etc/.

    sudo mkdir /etc/ima
  • Move into the created folder and create a file named ima-policy. From here on, since shutting down the TD in an incomplete state can result in unrecoverable damage, do not shut down the TD by any means other than the procedure described below.

    cd /etc/ima
    sudo touch ima-policy
  • Populate the file with the following contents. The FILE_CHECK line can remain commented out for now. A more detailed configuration that matches actual operation is described later in the "IMA Detailed Configuration" section.

    # PROC_SUPER_MAGIC
    dont_measure fsmagic=0x9fa0
    # SYSFS_MAGIC
    dont_measure fsmagic=0x62656572
    # DEBUGFS_MAGIC
    dont_measure fsmagic=0x64626720
    # TMPFS_MAGIC
    dont_measure fsmagic=0x1021994
    # DEVPTS_SUPER_MAGIC
    dont_measure fsmagic=0x1cd1
    # BINFMTFS_MAGIC
    dont_measure fsmagic=0x42494e4d
    # SECURITYFS_MAGIC
    dont_measure fsmagic=0x73636673
    # SELINUX_MAGIC
    dont_measure fsmagic=0xf97cff8c
    # SMACK_MAGIC
    dont_measure fsmagic=0x43415d53
    # CGROUP_SUPER_MAGIC
    dont_measure fsmagic=0x27e0eb
    # CGROUP2_SUPER_MAGIC
    dont_measure fsmagic=0x63677270
    # NSFS_MAGIC
    dont_measure fsmagic=0x6e736673 
    
    # Measurement targets and measurement triggers
    
    # Measure files MMAP-ed for program execution
    measure func=MMAP_CHECK mask=MAY_EXEC
    
    # Measure executed binary programs
    measure func=BPRM_CHECK mask=MAY_EXEC
    
    # Measure files opened by root (uid=0)
    # measure func=FILE_CHECK mask=MAY_READ uid=0
    
    # Measure loaded kernel modules
    measure func=MODULE_CHECK
    
    # Measure firmware loaded into the kernel
    measure func=FIRMWARE_CHECK
    
  • Reboot the VM instance.

Client

Cloning the Repository

  • Clone the Humane-RAChain-NS repository. The following prerequisite-installation steps assume that the repository has already been cloned.

    git clone https://github.com/acompany-develop/Humane-RAChain-NS.git

Installing Prerequisite Packages

  • As with the server installation, install Python and pip following the official procedure if they are not already installed. Python 3.10.12 is the verified version.

  • Install the following library required for TPM operations (TPM Quote verification):

    sudo apt -y install tpm2-tools

    As of February 2026, the latest tpm2-tools version 5.7 contains an unfixed bug that affects parts of this repository. The bug will be fixed in the next release 5.8. For now, build the latest patched version from GitHub yourself with the following:

    sudo apt install -y build-essential autoconf autoconf-archive automake libtool pkg-config libssl-dev libtss2-dev libcurl4-openssl-dev
    git clone https://github.com/tpm2-software/tpm2-tools.git
    cd tpm2-tools
    ./bootstrap
    mkdir -p build
    cd build
    ../configure
    make -j"$(nproc)"
    cd tools
    sudo install -m 0755 ./tpm2 /usr/local/bin/tpm2
    sudo ln -sf /usr/local/bin/tpm2 /usr/local/bin/tpm2_checkquote
  • Install snpguest — used for SEV-SNP Attestation Report and VCEK Cert verification — and the Rust toolchain required for it:

    sudo apt install -y build-essential clang
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    source "$HOME/.cargo/env"
    git clone https://github.com/virtee/snpguest.git
    cd snpguest
    cargo build -r
  • The required Python packages (requests, cryptography, pyyaml, and the IMA-log verification tool IMA-PCR-Utils) are listed in client/requirements.txt. Create a client venv under the client directory, activate it, and install them collectively:

    cd Humane-RAChain-NS/client/
    python3 -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt

    All subsequent client-side operations (installation of NCC-related packages described below, execution of client.py, etc.) must be performed with source venv/bin/activate already executed.

Installing NCC-related Packages

If NCC Attestation is not being performed, this section can be skipped.

  • If the client also performs a double-check of the NCC Evidence (verify_ncc_flag: true in settings.yaml), the NVIDIA-distributed nvattest CLI needs to be on PATH in the client environment as on the server (the legacy nv-attestation-sdk is deprecated). It also does not need to be installed inside the Python venv.

    After installation, verify that the binary is visible on PATH with the following command:

    nvattest --version

    The Humane-RAChain-NS client writes the Evidence array received from the server to a temporary file and re-verifies it by calling nvattest attest --verifier local --gpu-evidence-source file via subprocess.

    By default, this nvattest binary is also Extended into PCR23 (described later), so prepare a version (including distribution) identical to that of the server for client-side recomputation. Alternatively, it can be excluded from the PCR23 extension targets, as described later.

Configuration

If you just want to verify operation, follow this section only to obtain expected_measurement.dat and specify PLATFORM_INFO (setting it to [2, 2, 2, 2, 2, 2] skips all PLATFORM_INFO checks), then proceed to the "Execution" section.

Server (CVM)

  • The Humane-RAChain-NS scripts, NCC Attestation policy, and runtime workload (the script Humane-RAChain-NS executes after RA acceptance) that are registered into PCR bank 23 are configured in the following portion of Humane-RAChain-NS/server/attester.py:

    # Humane-RAChain-NS script filenames targeted for PCR Extend
    PCR_EXTEND_TARGET_HUMANE_BASE = [
        "api.py", 
        "attester.py", 
        "cert_gen.py",
    ]
    
    # Files added when NCC Attestation is enabled
    PCR_EXTEND_TARGET_HUMANE_GPU = [
        "policy/server_gpu_ra_policy.json",
        "/usr/bin/nvattest",
    ]
    
    # ...
    
    # Workload filenames targeted for PCR Extend
    PCR_EXTEND_TARGET_WORKLOADS = [
        "sample.py"
    ]

    If you change the script structure of Humane-RAChain-NS itself or the NCC Attestation policy file structure, be sure to update the upper PCR_EXTEND_TARGET_HUMANE_* lists. Files not listed here will not have their measurement registered in PCR bank 23 when the TPM Quote is created. Conversely, when changing the runtime workload, add to or modify entries in the lower PCR_EXTEND_TARGET_WORKLOADS list. For example, if you want to run a script other than the default sample, you must edit this section. If a folder is specified, its contents are also measured recursively.

  • The NRAS URL is specified at the following location inside attest_ncc() in Humane-RAChain-NS/server/attester.py:

    NRAS_URL = "https://nras.attestation.nvidia.com/v3/attest/gpu"

    If you need to change this endpoint for any reason — e.g. when NRAS API versions are updated — modify this line directly.

  • Which PCR banks are included when generating the TPM Quote is specified at the following location inside get_tpm_quote() in Humane-RAChain-NS/server/attester.py:

    # PCR list-file generation
    # By default, PCR banks 0-10, 12, 14, and 23 are included
    # Specify sha256:all to include all PCR banks
    selector_str = "sha256:0,1,2,3,4,5,6,7,8,9,10,12,14,23"
    pcr_indices = selector_str_to_pcr_indices(selector_str)
  • Currently, the IMA files are simply copied from the CVM's existing policy and log and presented to the client (the application of IMA-related hashes into PCR bank 10 is performed automatically). The locations of these files are specified in Humane-RAChain-NS/server/run-server.sh:

    SRC_POLICY="/etc/ima/ima-policy"
    SRC_MEASUREMENTS="/sys/kernel/security/ima/ascii_runtime_measurements"

    If these paths need to be changed for any reason — environment differences, etc. — modify these lines.

  • If you want to change the port on which client requests are received, directly modify the following section (port=8080) of Humane-RAChain-NS/server/api.py:

    config = uvicorn.Config(
        app=app,
        host="0.0.0.0",
        port=8080,
        ssl_certfile=cert_file_path,
        ssl_keyfile=key_file_path,
    )
    config.load()
    config.ssl.options |= ssl.OP_NO_TICKET
    
    server = uvicorn.Server(config)
    server.run()

Client

  • Specify the path to the directory containing the built snpguest in the following entry of client/settings.yaml:

    # snpguest_path = "$HOME/snpguest/target/release"
    snpguest_path: "~/snpguest/target/release"

    The default is the path where snpguest has been cloned and built directly under the home directory of the logged-in user (e.g. under /home/username/). Adjust the path if it is cloned elsewhere or if a debug build is used.

  • If you are using an SEV-SNP CVM that is not NCC-compatible, or otherwise not performing NCC Attestation, change the following item in client/settings.yaml from true to false:

    # Flag for whether NCC Attestation is enabled. true means enabled.
    gpu_enabled: true
  • For SEV-SNP Attestation, the SEV-SNP Measurement (identity measurement) must be obtained in advance. For example, log in to the CVM in a previously-trusted situation (e.g. locally before VM deployment) and run Humane-RAChain-NS/subtools/measurement_extractor.py to generate expected_measurement.dat:

    cd subtools
    python3 measurement_extractor.py

    The default is configured for a setup where the server and client run on localhost, so simply running this script will automatically place the above dat file under the client folder. When running remotely, move the generated dat file to the client folder of the client environment yourself.

  • Depending on the use case, you may not want to expose the Humane-RAChain-NS server-side source or runtime workload implementation, or you may not want to recompute file hashes on the client side. For such cases, an option is provided to use a pre-supplied hash list to reproduce PCR23. Change the following part of client/settings.yaml:

    # If you want to simply compare a provided hash list against the PCR23
    # value of the TPM Quote — rather than performing client-side hash
    # recomputation — set this variable to false.
    # The hash list can be generated with subtools/hashlist_generator.py.
    # Set to true if you want recomputation.
    recalculate_pcr23_flag: true

    Setting it to false directly Extends using the hash list in expected_pcr23_hash.dat placed directly under the client folder (no file-hash recomputation is performed). This hash-list file can be generated with subtools/hashlist_generator.py:

    cd subtools/
    python3 hashlist_generator.py

    If NCC Attestation is disabled, run with the --no-gpu flag:

    python3 hashlist_generator.py --no-gpu

    For attestation evidence dynamically delivered per RA session (i.e. non-file evidence), the hash is recomputed from the received data regardless of this option. If you change the files targeted by PCR23, also edit the following part of hashlist_generator.py:

    # Humane-RAChain-NS script filenames targeted for PCR Extend (no GPU)
    PCR_EXTEND_TARGET_HUMANE_BASE = [
        "../server/api.py",
        "../server/attester.py",
        "../server/cert_gen.py",
    ]
    
    # Files added when GPU is enabled
    PCR_EXTEND_TARGET_HUMANE_GPU = [
      "../server/policy/server_gpu_ra_policy.json",
      "/usr/bin/nvattest",
    ]
    
    # Workload filenames targeted for PCR Extend
    PCR_EXTEND_TARGET_WORKLOADS = ["../server/sample.py"]
  • PLATFORM_INFO — a bit string representing SEV-SNP configuration (SMT-enabled status, etc.) — is included in the Attestation Report, and Humane-RAChain-NS verifies it. The client can specify the expected value in the following part of Humane-RAChain-NS/client/settings.yaml:

    # List used to check PLATFORM_INFO in the SEV-SNP Report.
    # Size is 6, ordered from the top: SMT enabled, Transparent SME enabled,
    # ECC enabled, RAPL disabled, DRAM ciphertext hiding enabled, BadRAM
    # mitigation enabled. Use 0 or 1 to indicate what is expected. Use 2 for
    # members that should not be verified.
    expected_platform_info: [0, 2, 0, 0, 0, 2]

    Description of each element's corresponding configuration feature (starting from index 0):

    1. Whether Simultaneous Multi-Threading (SMT) is enabled. 0 = disabled, 1 = enabled. SMT is often abused in various attacks, especially in TEE contexts, so disabling is preferable.
    2. Whether Transparent SME is enabled. 0 = disabled, 1 = enabled. This is an AMD SME feature that automatically encrypts all memory regardless of the C-bit.
    3. Whether ECC is enabled. 0 = disabled, 1 = enabled. ECC provides some resistance to unintended bit flips or deliberate bit-flip attacks (e.g. RowHammer).
    4. Whether RAPL is disabled. 0 = enabled, 1 = disabled. RAPL is a CPU-level power-monitoring interface; if enabled, it may be abused in certain side-channel attacks (e.g. PLATYPUS in the SGX context).
    5. Whether SEV-SNP's Ciphertext Hiding is enabled. 0 = disabled, 1 = enabled. When enabled, reads of SEV-SNP-protected memory from outside return a specific fixed value rather than ciphertext. Similar to SGX's Abort Page Semantics.
    6. Whether mitigation against the BadRAM attack is enabled. 0 = disabled, 1 = enabled. While "enabled" is preferable, as of January 2025 there are still many cases in which this bit is unused.

    Given the above, generally specify the expected bit as 0 or 1. For items that may be either, specify 2 to skip verification. With this in mind, expected_platform_info = [0, 2, 0, 0, 0, 2] means:

    • Require SMT disabled.
    • Do not care about Transparent SME.
    • Require ECC disabled.
    • Require RAPL enabled.
    • Require Ciphertext Hiding disabled.
    • Do not care about BadRAM mitigation.

    However, this is by no means the optimal setup. From a purely security viewpoint, [0, 2, 1, 1, 1, 1] would be best, but whether this is satisfiable depends strongly on the cloud's machines. Adjust this flexibly to your needs and environment.

    To directly check the current value of PLATFORM_INFO on the target CVM, the SEV-SNP Attestation Report can be inspected (run on the CVM):

    export PATH=$PATH:$HOME/snpguest/target/release
    tpm2_nvread -C o 0x01400001 > ./snp_report.bin
    dd skip=32 bs=1 count=1184 if=./snp_report.bin of=./guest_report.bin
    snpguest display report guest_report.bin

    The output of snpguest display includes PLATFORM_INFO information like the following (the ALIAS_CHECK_COMPLETE corresponding to BadRAM mitigation is not yet supported):

    Platform Info (0):
    SMT Enabled:               0
    TSME Enabled:              0
    ECC Enabled:               0
    RAPL Disabled:             0
    Ciphertext Hiding Enabled: 0
  • The CVM URL is specified in the following part of client/configs.yaml, so modify here when running remotely, etc.:

    # Don't forget the trailing "/".
    server_url: "https://localhost:8080/"
  • The Humane-RAChain-NS scripts, policies, and runtime workload expected to be measured into PCR bank 23 are listed on the client side in the following part of Humane-RAChain-NS/client/ra_verifier.py:

    # Humane-RAChain-NS script filenames targeted for PCR Extend
    PCR_EXTEND_TARGET_HUMANE_BASE = [
        "../server/api.py",
        "../server/attester.py",
        "../server/cert_gen.py",
    ]
    
    # Files added for NCC Attestation
    PCR_EXTEND_TARGET_HUMANE_GPU = ["../server/policy/server_gpu_ra_policy.json"]

    As with the server configuration, add to or modify this list as needed. Note that when running the client remotely, the server-side scripts/policies on the client side and the actual ones used on the server (those PCR23-registered on the server side) are assumed to be exactly identical. Therefore, any changes to them must be applied identically to the server-side files on both server and client (otherwise the PCR23 hash check will fail).

  • The NRAS URL is specified at the following location inside verify_ncc_attestation() in Humane-RAChain-NS/client/ra_verifier.py:

    NRAS_URL = "https://nras.attestation.nvidia.com/v3/attest/gpu"

    If you need to change this endpoint for any reason — e.g. NRAS API version updates — modify this line directly.

  • Currently, the functionality to reproduce hashes of the firmware-layer PCR0–7 by building from firmware source on the client side is unimplemented. If needed, you can implement firmware verification after check_tpm_quote() completes successfully inside verify_response() of Humane-RAChain-NS/client/ra_verifier.py, using your prepared reproduced hashes.

  • If self-verification of NCC Attestation Evidence is not needed, as described in the usage section, set the corresponding argument in verify_response() (in Humane-RAChain-NS/client/settings.yaml, this is verify_ncc_flag) to False.

  • If you want each entry of the IMA log to be verified, specify the path to the verification policy in the following part of Humane-RAChain-NS/client/settings.yaml:

    # Path to the IMA appraise policy file (YAML). Specify as a relative
    # path from client.py or as an absolute path. Can be generated by
    # subtools/ima_appraise_policy_generator.py. Only referenced when
    # verify_pcr10_flag is true.
    ima_appraise_policy_path: "ima_appraise_policy.yaml"

    ima_appraise_policy.yaml consists of measurement-target paths (in fnmatch format) and an allow list (or deny list) of hash values:

    home_Humane_RAChain_NS_server_sh:
      path: /home/**/Humane-RAChain-NS/server/*.sh
      allow:
      - 28f97e660dd1061224c64ee4ad9d3a63c9b402465323de962f70ee318d8a88e7
    home_Humane_RAChain_NS_server_py:
      path: /home/**/Humane-RAChain-NS/server/*.py
      allow:
      - 0dce80960c8b3464639aeb7a49eb8a1f13964617f3c06c095db8795a4069245a
      - 0e0de7474b3e4b368d518fd657b4fd6701b27c962b258992dd55e418b96262aa
      - 4ed066d8cc9ea214d78d7de5ad65b76e953c82023efe43f76c1006a3403a5e4b
      - aebf70b1aa84c4bdccd288462ae4c4cb7228695ae27797b0e5c2325481b95a9b
    home_Humane_RAChain_NS_server_policy_server_gpu_ra_policy_json:
      path: /home/**/Humane-RAChain-NS/server/policy/server_gpu_ra_policy.json
      allow:
      - 61e6919e3834b4a07a857de19e475695fa7db1d9bd3d247e8ce828ed8fcbf59b
    usr_bin_python3:
      path: /usr/bin/python3
      allow:
      - e1efa562c2cc2e35521a5c9c9b9939921001ff8ca9708a13ef15ace68cc2ccd7

    For example, by logging into the CVM in a previously-trusted situation and running Humane-RAChain-NS/subtools/ima_appraise_policy_generator.py, the IMA verification policy can be auto-generated based on the hash values of the target files at that point in time:

    python3 ima_appraise_policy_generator.py

    Measurement targets for IMA verification-policy generation are configured at the following location in ima_appraise_policy_generator.py:

    # List of path patterns to be specified as IMA appraise policy.
    # Each element is a path pattern interpreted as a glob (and at run time as fnmatch).
    # If you want recursive expansion, include "**"; this script expands with glob.glob(recursive=True).
    # Note: at runtime, matching is done with fnmatch.fnmatchcase, so write
    # patterns as strict as possible matching the file_path in the actual IMA log.
    APPRAISE_TARGETS = [
        "/home/**/Humane-RAChain-NS/server/*.sh",
        "/home/**/Humane-RAChain-NS/server/*.py",
        "/home/**/Humane-RAChain-NS/server/policy/server_gpu_ra_policy.json",
        "/usr/bin/python3",
    ]

Execution

This section describes the execution procedure for running Humane-RAChain-NS as-is.

Server (CVM)

With the server venv activated, run the launcher shell script as follows. Since run-server.sh itself does not activate the venv or install dependencies, the venv must be created in advance per the installation procedure, and source venv/bin/activate must already have been performed:

cd Humane-RAChain-NS/server/
source venv/bin/activate
./run-server.sh

To disable NCC Attestation, run with the --no-gpu flag:

source venv/bin/activate
./run-server.sh --no-gpu

An example of execution is shown below (only the tail of the log is shown since stdout is large):

[Fetch TPM Attestation PubKey]
Fetched TPM Attestation PubKey successfully.

[Reset PCR bank 23]
PCR 23 was successfully reset.

[Extend PCR with evidences]
Extended PCR 23 with VCEK Cert/AK Pub successfully.
Extended PCR 23 with NCC evidences successfully.

[Get TPM Quote]
Generated TPM Quote successfully.
Generated PCR values list successfully.

[Get IMA-related files]
Got IMA-related files successfully.

INFO:     127.0.0.1:36756 - "POST /attestation HTTP/1.1" 200 OK

[Execute sample secret addition]
Added secrets successfully.

INFO:     127.0.0.1:36756 - "POST /sample-addition HTTP/1.1" 200 OK

Client

With the client venv activated, run client.py as follows. The venv must be created in advance per the installation procedure, and source venv/bin/activate must already have been performed:

cd Humane-RAChain-NS/client/
source venv/bin/activate
python3 client.py

An example of execution is shown below (excerpted because stdout is large):

GPU attestation: disabled
[Send attestation challenge]
Generated Nonces:
 NCC Nonce: 5aab8cd9863372289fb2ad9fb9a412e9ab09545926537ac5afccdd80e1820f08
 TPM Nonce: e3891742fbd624d256fb2acb119f7c699abc24722954f16bec4cafa9a80dd136
 SNP Nonce: 75bef4d5574b8a3625c09e3ec796d7f692cf2e0e12f5cc1ec84b0037a3d9bafae16129df2a9cadd103290b1abf51c4d782a1caee0206676a8d8ad4cd069c6343

...

[Verify HCL Report Data binding]
REPORT_DATA expected (sha256, zero-padded) ->
c855dd11a2ba68ab08653b6becb99e91cc22ca9257db5b596ee3605636b8b3710000000000000000000000000000000000000000000000000000000000000000
REPORT_DATA actual ->
c855dd11a2ba68ab08653b6becb99e91cc22ca9257db5b596ee3605636b8b3710000000000000000000000000000000000000000000000000000000000000000
SNP REPORT_DATA matches hash of Runtime Claims.
Runtime Claims user_data matches client-supplied nonce.

[Verify VCEK Cert with ARK Cert]
The AMD ARK was self-signed!
The AMD ASK was signed by the AMD ARK!
The VCEK was signed by the AMD ASK!

SEV-SNP VCEK is valid.

[Verify SEV-SNP Report]
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.
VEK signed the Attestation Report!

SEV-SNP's measurement hash->
e14f74982d655d4cbd686b91bcb9431ddb98b6e210e59647089d203035cf99d9a76efbdee19f0958ff3f1aa4518e86e0

Expected measurement ->
e14f74982d655d4cbd686b91bcb9431ddb98b6e210e59647089d203035cf99d9a76efbdee19f0958ff3f1aa4518e86e0

...

[Verify PCR 10]

Received PCR 10 hash (IMA related PCR) ->
f0d6af60d98acded3c1d509922d1d0579e210dc3431fee065631e03f30d36b18

Calculated PCR 10 hash ->
f0d6af60d98acded3c1d509922d1d0579e210dc3431fee065631e03f30d36b18

Received PCR 10 hash matched calculated PCR 10 hash.

[Verify boot_aggregate]

Received boot_aggregate ->
bbdbca85a82cf96aad024bdfedaa4fcc791d857b338b6f7c5a4625bce0118ac4

Calculated boot_aggregate ->
bbdbca85a82cf96aad024bdfedaa4fcc791d857b338b6f7c5a4625bce0118ac4

Received boot_aggregate matched calculated boot_aggregate.

[Appraise IMA log against IMA appraise policy]
IMA appraise policy path -> /home/azureuser/Humane-RAChain-NS/client/ima_appraise_policy.yaml
IMA appraisal passed: 525 entries (1 allow, 524 neutral).

IMA evidences verification passed.

[Skip NVIDIA CC Attestation]

Accepted RA. Proceed to next process.
Pinned session to attested cert (SHA-256 DER): 089413c0c2f90cb264f5356910955aa909322c27371b3512e69a6f1a16945145

[Request sample secret addition]
Sample secret addition result ->
300

Example of Attestation-evidence JSON

An example of the Attestation-evidence JSON returned in response to an Attestation request sent to the Humane-RAChain-NS server is shown below (the --no-gpu case). This JSON example is shared by both the English and Japanese versions of this document; the Japanese version references this section.

{
  "status": "success",
  "message": "Attestation completed",
  "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIBxDCCAWqgAwIBAgIUFGJCY7pAQRM+lmRUW6n1IU+d0E4wCgYIKoZIzj0EAwIw\nYjELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBUFpY2hpMQ8wDQYDVQQHDAZOYWdveWEx\nGzAZBgNVBAoMEkFjb21wYW55IGNvLiwgTHRkLjEVMBMGA1UEAwwMYXR0ZXN0ZWQt\nY3ZtMB4XDTI2MDUyMDA0MjEzM1oXDTI2MDYxOTA0MjEzM1owYjELMAkGA1UEBhMC\nSlAxDjAMBgNVBAgMBUFpY2hpMQ8wDQYDVQQHDAZOYWdveWExGzAZBgNVBAoMEkFj\nb21wYW55IGNvLiwgTHRkLjEVMBMGA1UEAwwMYXR0ZXN0ZWQtY3ZtMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAERlr4Def7dhTa8ZZA11cSXt/NY5YZUHjC9a//3GLN\n2dm89/WN+WHPDd4pw4pL8cGVUKpBWRocDHKl9Y7RFjNCSjAKBggqhkjOPQQDAgNI\nADBFAiEA0ZC9gK/iBXt5eFr/8ZbFLdU6YyVW5szJuO+Obr0cA5MCIEDNEwfl3nYp\nvdE9FflbOn2qk6hOLQBXPXPIL8K5/fdt\n-----END CERTIFICATE-----\n",
  "vcek_cert": "-----BEGIN CERTIFICATE-----\nMIIFPzCCAvOgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAgUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCATAwezEUMBIGA1UECwwL\nRW5naW5lZXJpbmcxCzAJBgNVBAYTAlVTMRQwEgYDVQQHDAtTYW50YSBDbGFyYTEL\nMAkGA1UECAwCQ0ExHzAdBgNVBAoMFkFkdmFuY2VkIE1pY3JvIERldmljZXMxEjAQ\nBgNVBAMMCVNFVi1HZW5vYTAeFw0yNTAyMDkxNjA5MDNaFw0zMjAyMDkxNjA5MDNa\nMHoxFDASBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwL\nU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNy\nbyBEZXZpY2VzMREwDwYDVQQDDAhTRVYtVkNFSzB2MBAGByqGSM49AgEGBSuBBAAi\nA2IABOEBbhhd+xsYLHvfExQV2Splb3+8Jw49jCxvmgtsd0eD1kX3gR+t8BDUqUmz\nLA8PTQ3elvF8/jPazeWm3JPawojMiX8sWR5qwNlsodSgtkYKc16clIwrUzEhJllL\nM0cIVKOCARMwggEPMBAGCSsGAQQBnHgBAQQDAgEAMBQGCSsGAQQBnHgBAgQHFgVH\nZW5vYTARBgorBgEEAZx4AQMBBAMCAQowEQYKKwYBBAGceAEDAgQDAgEAMBEGCisG\nAQQBnHgBAwQEAwIBADARBgorBgEEAZx4AQMFBAMCAQAwEQYKKwYBBAGceAEDBgQD\nAgEAMBEGCisGAQQBnHgBAwcEAwIBADARBgorBgEEAZx4AQMDBAMCARcwEQYKKwYB\nBAGceAEDCAQDAgFUME0GCSsGAQQBnHgBBARAd2a1bXO9BnkuUrp2RTlmNLJdfW2p\nfn8EvCMg/BmG/UsuU4gxoxr3eL9cRsaZiVM0xTgFlDSie1GYmmc+grTRkDBBBgkq\nhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAgUAoRwwGgYJKoZIhvcNAQEIMA0GCWCG\nSAFlAwQCAgUAogMCATADggIBAI3gcYG3rXc+Uo2/wrsxhUIeU5tmOwEOUKToZJwM\no5EFywhHR8ZdYuJFRo4Ne3mbRKh8zZZY+h6g+0bibx9QvNquGMSmJWld1r86ioT0\n/dR4Zh/e0Cqbqdz19j52WD6PZ9xEUkoEBaber9ptE6Du0PiPpfS7Yj3bhkuhJn83\nK9jA/nyfe1mVKdzYp8TIq7m7MIijJOjjylgYvmDj3lOim2cPXCnzJSl8nBwvl3Yz\nIUwAKJbc/zL/Ost7PG3QQCzdHUqP/vFGIJ8BN8kMYPiw/0atoUyf1RqClT7lKGlk\nldB//aF9anXszvEC0EvQ7V9ggOLGT5uhio+KJdUouphTiwW039jipuiE1b3V6+Du\nIn23iWM0rnEyRqvqbREdN9lPVbrvXMEYZV5sqbj9TenB9DZM6srKuCMVwQjK2Ui9\nntpZi6fiv6T3gNSzkbZTXMV+5+HwU+QdnLE5n/DFNW83uExBYA4v5qnbTmCExbWL\nTdl6ovkDwrwneCUmsdMtwoZv41RBnFqiThIOQ3D6wQSCxuCKoSdjbN7RpIb8AeTB\nMGYkn3kWIN4D55T9kdanMPGektFeeRlPZSLtnoIGFfO5eG+b4FNgY0W5oZMKuPEP\nqgb/DRNOin+rZiZlOpV32X99SrF69gsr9CHR0RctviutlSGoTz1NTJzCi52kXfc6\nSwGH\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\n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\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n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\n/wMz1R1BHg==\n-----END CERTIFICATE-----\n",
  "snp_report": "SENMQQIAAACECQAAAgAAAAAAAAAAAAAAAAAAAAAAAAADAAAACwABAB8AAwAAAAAAASMgAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAoAAAAAABdUJwAAAAAAAAAAAAAAAAAAAB2E/DzDm6+Z0zNss8df/1UAMmlL0gh5h+QBksimEJcxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhT3SYLWVdTL1oa5G8uUMd25i24hDllkcInSAwNc+Z2adu+97hnwlY/z8apFGOhuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJQv2T695up6lu+t6vxg8caz0Q5wOx2v11Vbkvfz0y0OAGdnZIy6WxAq89ZXVq9BdwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkrBaBucfyTg1fPjkrWsGseXlbHPZC9ZsJ1jeoy4IzS//////////////////////////////////////////8KAAAAAAAXVBkRAQAAAAAAAAAAAAAAAAAAAAAAAAAAAHdmtW1zvQZ5LlK6dkU5ZjSyXX1tqX5/BLwjIPwZhv1LLlOIMaMa93i/XEbGmYlTNMU4BZQ0ontRmJpnPoK00ZAKAAAAAAAXVCg3AQAoNwEACgAAAAAAF1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAz4rDC5riTKnnZ88/SFAC9YclpL+NofMT6irgWRznuj+QVMu2kGf9GOHvcDc4JEHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACygEQM3ZeJTX6kZ8l/8Xa6OgoYWsCsOTKfDpnIcj12+E/FHRLdevOxvfffmufzgGsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQEAAABAAAAAgAAAAEAAACwBAAAeyJrZXlzIjpbeyJraWQiOiJIQ0xBa1B1YiIsImtleV9vcHMiOlsic2lnbiJdLCJrdHkiOiJSU0EiLCJlIjoiQVFBQiIsIm4iOiJweVJmTWdBQktfejV0aTRUNmZwcGRxNzBMUEp2bU5mVTY1T3hoOWdaNTlPNk5rVWYySzF2MmsyanF0ODZBb3NNSHExc1N5V2R6U1JmT2ZfTjk1c3hzNXkwTG51ZXg0bW5YeGtKVmNOd3BKMktiVlpGVkRHTGdkdi1IV1Z4NDIzU0g5ejhQX215QVdaRFJuR2MyZmJNaENoLXZMNlQ4eVZaS2ZmOEh0R2dHUm9nczdQWUY1d1VsSGJzZnQ0RENVVldxUDJXVG1jcEVwR0dLdzIxeUg5cEdMZklvbV9ybjA0TlBHblc3WG9TSm13c0I5dzh4Z0JVZUIxWFgxcjVfR3RrU05iRnE4TFRIRFZVcVA4S0dvOEJLRDI2RFJobkxJM0REWWhnSWE5QTVWUlc4a1Z4dk93ZEd6VHkxdnQtTEV1ZzNGbWJaOURQcFRadEl6VDR3T2dYMXcifSx7ImtpZCI6IkhDTEVrUHViIiwia2V5X29wcyI6WyJlbmNyeXB0Il0sImt0eSI6IlJTQSIsImUiOiJBUUFCIiwibiI6InNuaDVQd0FBWTRKQjlBQ3l1SDMtdHpWVTljQTFkekpOT0VMVkhUMUJrSFg3THVVVXRrbU5PRGRkNTZUemhHLW5CSHc4N3dQU0dKX1ZqZ3lXcDZoQUctZFhxeTJ2QmplT0ZxdWhYVnF4N2NrdTA1a3FONTRRSUt0VWN0aVM3eFJtMmhUM3RZeEJwWjFDa1ZiVkFHSWk4dUFnMjFMWWVEZmdDRjN3cGVKaFEycUZwVWQwS2JYYi1ZMWFzZkZMUGg5SDY5ekZXeUV4VnlVaVY2blBxQnctUlB5SWNXZnZkRGNmWjNVSjRPQVRIWHVfNkxUSEp1NjZKd3ZFTkVxdlRnS0FnWWx6OC01UUVhYUZidENoVC1RMy1IYk10NjNCVUEwQUVsVTV3SzV4VENoTlloLXlFVTRIVFkzbTVNVWxqWjNETnpZUGpQRllrTG9xdTlLNGJMRlhnUSJ9XSwidm0tY29uZmlndXJhdGlvbiI6eyJjb25zb2xlLWVuYWJsZWQiOnRydWUsInJvb3QtY2VydC10aHVtYnByaW50IjoiNm5aWm5ZYUpjNEtxVVpfeXZBLW11Y0ZkWU5vdXZsUG5JVG5OTVhzSGwtMCIsInNlY3VyZS1ib290Ijp0cnVlLCJ0cG0tZW5hYmxlZCI6dHJ1ZSwidHBtLXBlcnNpc3RlZCI6dHJ1ZSwidm1VbmlxdWVJZCI6Ijg2OTg1MjYzLTE4NzItNEQzOS04OTAzLTQxNjE2MkU4OTg4MyJ9LCJ1c2VyLWRhdGEiOiI0QkE4RTdCN0U5NDUzOTBFRTAxOTk4MjM2ODUwRkUxMzZCODExRDUxNTNBOEU0MUJCNjExMDRCMTc5Njc0NjJCMzBEQ0Y1NzdGMDk5QTk4ODc2NzJFQzY0NDMwMTk3MkM2NTQ4OTc1NjE1QzhCNzI4MDg3RDU3RjY4MDhFRENCMCJ9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
  "ak_pub": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApyRfMgABK/z5ti4T6fpp\ndq70LPJvmNfU65Oxh9gZ59O6NkUf2K1v2k2jqt86AosMHq1sSyWdzSRfOf/N95sx\ns5y0Lnuex4mnXxkJVcNwpJ2KbVZFVDGLgdv+HWVx423SH9z8P/myAWZDRnGc2fbM\nhCh+vL6T8yVZKff8HtGgGRogs7PYF5wUlHbsft4DCUVWqP2WTmcpEpGGKw21yH9p\nGLfIom/rn04NPGnW7XoSJmwsB9w8xgBUeB1XX1r5/GtkSNbFq8LTHDVUqP8KGo8B\nKD26DRhnLI3DDYhgIa9A5VRW8kVxvOwdGzTy1vt+LEug3FmbZ9DPpTZtIzT4wOgX\n1wIDAQAB\n-----END PUBLIC KEY-----\n",
  "tpm_quote": {
    "quote": "/1RDR4AYACIACznDprW0htDuqmRPKNUVnkO5hFe9rEuIJeaYccnceYruACClF1EbFAmH5nW+y1UUQKqE0wQOLKD8jJkZtXO0dPdY9QAAAAAGtAdAAAAACwAAAAABICADEgASAAMAAAABAAsD/1eAACAExyvnvb4FwY7he9B45yEzOhvD/uQUTMl4nbyXf7nSZQ==",
    "signature": "ABQACwEAG5GrMFbZwcbLaNQPxqrEeH9DNNT+yll5PB89J+Lbx/w3BymHo0vvPPA1P0x1zl0dfauj80gdAYsbJDCV0SMWSf21dnAfChC47NGTdmF0MoH7aVjPTM0v5YRVnIXqx+A4F0BNd0gA/N6s8fS+jkSiJip9wLCdJxmgLVGAszUYSnWYWzGprJ/ChWdGFJ6iZpaKy6jQ6LosCMBWUu57CdgSsfD/vs1bGdKbJ/SHFMgvGXxklJL0K7LvYSZWHK137UcahG0CVsDMttWuBAFIDKillrn2DDIRN+xG+EGg5s/gKGIrExF6oZ0iAuDtR9Wnwu31jFJRg4J69QaOXT6QdF51Iw==",
    "pcr_selector": "sha256:0,1,2,3,4,5,6,7,8,9,10,12,14,23",
    "pcr_value": "Exd6ZTW63xlBXAZYlwXdWhiQ9zVFxKn+96z+LGF3ore5FD92r/7VVdhir88GqppoKsaJryHLgOkLhU/ag7htFT1FjP5VzAPqH0Q/FWK+7I31HHXhSp/PmnI0oT8ZjnlpPUWM/lXMA+ofRD8VYr7sjfUcdeFKn8+acjShPxmOeWmrYTRrL+U6POY47LGG9VgNu/e9UinSYYB66Z/YvOgZThjIxWvpP16a3HM2px0ZTDXCRpLGcfI6hi3871QTU6UC+3hn1x1u4jAuw4zvSzIrLZyk0U8yFjNzeXcab3x4DME7IOAiQW/fYdcuTaMrQ1R4G+PeBggRaXbSj/2tjDQdKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAKnGa8k7WMM0xrJIAPtZgP1Jvpk8FPWfhwpFAwwtYxaOw2/+baFA8jnJlszzkBjPWYJyf5xJCe8jHCxKNxK/fGhQsU1hufiIj7HTl9NGklClWsf2ax4+vzfhRF6o0XaMG+di5TxfZPcbnz49cedZS60xsTRPeLd3CSvQW4T7K+aHhPEDAyltmo5GjA/IOToey3BpbEWsspQXkBtgMYYUA=="
  },
  "ima": {
    "ima-policy": "",
    "ima-measurement": "10 498c9bbfb84cee61be6e0768d4190c4b9b385b3a ima-ng sha256:bbdbca85a82cf96aad024bdfedaa4fcc791d857b338b6f7c5a4625bce0118ac4 boot_aggregate\n10 5a9c34240b2f0cca9f47b4c1fab6d23829392470 ima-ng sha256:9b403ac5877723c568548723d1988e91d30d8a8bb171bdae001126729ee93047 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/fs/autofs/autofs4.ko.zst\n10 a66f62e131afe972f8eec94f91070f5a35499860 ima-ng sha256:910c77268babfc7ea567615d11e393f247db00ee988a8a27117974c1c81d8d2b /usr/lib/modules/6.17.0-1005-azure-fde/kernel/fs/nls/nls_iso8859-1.ko.zst\n10 7d26cfd812dfaf0aad0eef0241bcb2200d7e1e62 ima-ng sha256:1dab38e3bdfa4237150b16a0d07acf273ba72fb691c7008a8cc2cafb5755bcdb /usr/lib/modules/6.17.0-1005-azure-fde/kernel/drivers/md/dm-crypt.ko.zst\n10 3a37c30e81aac2549f1be949be782fa8e0224aad ima-ng sha256:9f0a3cd745d9d1a1726b8da9d4f8c2075b467e5bb5eb479c93db5b8301034e55 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/x_tables.ko.zst\n10 1e09e1660f6614fd151bd082fe83872cbe5187a4 ima-ng sha256:e0a0aa856a800bfe0d6942e69797a22dac5f204c0d5977c56c78452f41926e8e /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/ipv4/netfilter/ip_tables.ko.zst\n10 a83d1f35ea2bc128d40dec0d1cc02c10c6df00c5 ima-ng sha256:6fae76abacca399f5ca92d9c12402c43a48aa11d9ffd835454a9bd57c03a55db /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/nfnetlink.ko.zst\n10 15b66c4d41920e9da332c26f04893be851c05f30 ima-ng sha256:ff91a4f45969da556f8a0f4ee4eaac5e7c5dfaec38eb8b9544da9aad155b08f0 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/drivers/firmware/efi/efi-pstore.ko.zst\n10 e2e6a22495b392f04137f01a6ed6a3536148e897 ima-ng sha256:1f83aa67d4970d43f0b9146d0ef8cd86797b29c100db4a777a9e8529605ec734 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/drivers/nvme/host/nvme-fabrics.ko.zst\n10 d193ce1b99c0451593bb3b5bc2505ff64f40bb4c ima-ng sha256:c415957fe3da568a97bba088238f58667d9e87f5abc45fc4872b201cbd52e8b2 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/arch/x86/kernel/msr.ko.zst\n10 8f5e95c8825c166037826b24539c7bf0395f3981 ima-ng sha256:599765c622fbe9422bf69e18ed17ff83acc794e7096b7027c02429120101fafd /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/sched/sch_fq_codel.ko.zst\n10 90a59ada9f6241995896eea56ff4caadfacf4d98 ima-ng sha256:b57bd3d7025ff272b4a2da2605798c0456e2b2a80b8947c8e652d4aca1617789 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/drivers/net/hyperv/hv_netvsc.ko.zst\n10 b4c505fcf67959a6b8fef4b3c35b4906abf29279 ima-ng sha256:7b0db1906a3faaf1f2617c07c28b455a471d49e39a2cb05e5f8aa73567cdd9af /usr/lib/modules/6.17.0-1005-azure-fde/kernel/arch/x86/crypto/ghash-clmulni-intel.ko.zst\n10 8d23f2ab9a30a70fbb6d3bfb011a8b2837990bc7 ima-ng sha256:b3d8ec65d4a58030d218dfa89feacd8d56260a3af354350ef51de9bf37792b80 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/arch/x86/crypto/polyval-clmulni.ko.zst\n10 ffeebc34d50b1204fe51d778c9c10fbb25e3c470 ima-ng sha256:22c06a98f245471ef184b55b87ab9f48c2f5222c1f737378a5f237b28d484694 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/fs/binfmt_misc.ko.zst\n10 2cce7cca474ace0c092c1560cf42971a2bf42b95 ima-ng sha256:87b05612f1a971db4b0699eb3e920201a8accf97d4cb9f84ef9d7fec74595c49 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/nf_tables.ko.zst\n10 9ef38d7864eff99d1373d245ce182c5aed085d2f ima-ng sha256:77f0a0b4fe97b6587d5aec481674d1a954a1f2a53b873ed58f07176f70667d2f /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/nft_compat.ko.zst\n10 4e72419b8787154d060effd4cb2f494361ee8126 ima-ng sha256:29cdd6c455f23f709db5f4f8e0af114ce61f73cc3f2833e67b4d8f3ce97932b9 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/ipv4/netfilter/nf_defrag_ipv4.ko.zst\n10 0fd73de3de67a4b9fd0f91cbb6e41100fd2a009d ima-ng sha256:ea6a9d2e3ced16a0e2019d7ddaa884c19ef871261894b9035eeba76ecac37517 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/ipv6/netfilter/nf_defrag_ipv6.ko.zst\n10 f1219752b5c5f246a1d06bfd78418bd83860850e ima-ng sha256:5c1a9b00749a9279915f6f3e205eff617d4a3ffba601e537aa51908bcc886218 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/nf_conntrack.ko.zst\n10 a487a4980cf8602376f0bafd66cc294775031038 ima-ng sha256:c3f37be880c51223066903933cb0d53e91e9c8c1486a05ff462f38eb4cec4d71 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/xt_conntrack.ko.zst\n10 d9b00a070e8d534f61f58afd84e7ec9995e9c5de ima-ng sha256:d1252ae6be621cbc1837fefc3e175744659f61675b959b64754c507d33173ffb /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/xt_tcpudp.ko.zst\n10 ab08356ffee1e35c96504084d0a6da81439c03ac ima-ng sha256:6b181e5b5eb63c84801c7daf982fc77533ebb6ce13205c76a8fba42157e2c7de /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/netfilter/xt_owner.ko.zst\n10 8e2f0c0e4d094cae01b252f4c0682f61e1f0255e ima-ng sha256:9ecded669738c8b4662a977f1861479813c469abd008fbd5cac9f1b80dbd2548 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/llc/llc.ko.zst\n10 8ee6f3faaf41dce57f8f9fae75a8b0629542a177 ima-ng sha256:583908083e80875d126b8549e0b49e5388b5a53af046ffccbbade7795183dddf /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/802/stp.ko.zst\n10 b296405c888119c34f313f86a545d4930a3c299e ima-ng sha256:d749d850fca26cd0f26f08c933788702ad2b9cacc9ed2949daf76ae18add1e2a /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/802/mrp.ko.zst\n10 e9595e6002ea3ba2ab0a23ddaee9a72240dbee4d ima-ng sha256:4484903ef010b3d7c381c706243fa2fc93a7804262acfae4111e6101de1c2553 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/802/garp.ko.zst\n10 6ce809c30c77453b22a78e8e03ce5cb2e3687377 ima-ng sha256:41b59c82e3cb2909a3655461d177ba2359959903d7ec7de59fe98d6ecb869710 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/8021q/8021q.ko.zst\n10 1803758d74c3fdb901039974bcb956efd6d411e5 ima-ng sha256:4006fc13e5cab0cbacf448a049ae8f0e468a67ad099242a9d923d867b0b5f593 /usr/lib/modules/6.17.0-1005-azure-fde/kernel/net/tls/tls.ko.zst\n"
  }
}

IMA Detailed Configuration

Because the range of what IMA can measure is extremely broad, it is difficult to define a single optimal configuration for IMA policy. The default IMA policy assumed in this repository is shown again below:

# PROC_SUPER_MAGIC
dont_measure fsmagic=0x9fa0
# SYSFS_MAGIC
dont_measure fsmagic=0x62656572
# DEBUGFS_MAGIC
dont_measure fsmagic=0x64626720
# TMPFS_MAGIC
dont_measure fsmagic=0x1021994
# DEVPTS_SUPER_MAGIC
dont_measure fsmagic=0x1cd1
# BINFMTFS_MAGIC
dont_measure fsmagic=0x42494e4d
# SECURITYFS_MAGIC
dont_measure fsmagic=0x73636673
# SELINUX_MAGIC
dont_measure fsmagic=0xf97cff8c
# SMACK_MAGIC
dont_measure fsmagic=0x43415d53
# CGROUP_SUPER_MAGIC
dont_measure fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC
dont_measure fsmagic=0x63677270
# NSFS_MAGIC
dont_measure fsmagic=0x6e736673 

# Measurement targets and measurement triggers
# Measure files MMAP-ed for program execution
measure func=MMAP_CHECK mask=MAY_EXEC

# Measure executed binary programs
measure func=BPRM_CHECK mask=MAY_EXEC

# Measure files opened by root (uid=0)
# measure func=FILE_CHECK mask=MAY_READ uid=0

# Measure loaded kernel modules
measure func=MODULE_CHECK

# Measure firmware loaded into the kernel
measure func=FIRMWARE_CHECK

With measure func=BPRM_CHECK mask=MAY_EXEC present, all executed binaries are measured. Combined with measurement of kernel modules, etc., at least basic execution can be traced.

The issue is the commented-out measure func=FILE_CHECK mask=MAY_READ uid=0 portion. Since execution is measured by BPRM_CHECK, measuring all other file reads, writes, and appends requires replacing this part with the following:

measure func=FILE_CHECK mask=MAY_READ
measure func=FILE_CHECK mask=MAY_WRITE
measure func=FILE_CHECK mask=MAY_APPEND

However, this measures all file operations by all users and produces an enormous log volume, raising performance concerns.

There is also a behavior in which the measurement value becomes all-zero when a Read-Open is performed during a Write-Open, so there are operational concerns beyond simple policy definition. In the extreme, this means excluding content that can perform such operations from the source — but in real operation this is not always feasible.

These difficulties with IMA configuration are out of scope for Humane-RAChain-NS, so here we only note that there is a gradient of strictness in IMA configuration.

Limitations

Although many of these overlap with what has been described, the limitations are restated:

  • For the firmware-layer PCR0–7, the functionality to build from firmware source, reproduce the hash, and verify it is not implemented. In Azure's case, since the firmware layer is non-public, such implementation would have to assume another cloud or on-premises environment.

  • Root-filesystem hash measurement is not implemented. If needed, it would have to be combined appropriately with the technique proposed by e.g. SNPGuard; the difficulty is high.

  • Measurement acquisition and RA binding for various Python libraries and the interpreter itself are not implemented. This is fundamentally delegated to IMA.

  • While IMA can measure content beyond the OS kernel, IMA itself does not measure the IMA policy, so the policy can be changed — an IMA-specific issue. We plan to publish a solution to this on the repository when it is resolved.

  • The IMA policy included as evidence is copied from either the loaded policy at /sys/kernel/security/ima/policy or the custom IMA policy file at /etc/ima/ima-policy. The latter is the policy loaded at the next CVM boot, and can be freely rewritten once the CVM is running, so it is not guaranteed to match the former. Read permission to the former is set by the kernel configuration option CONFIG_IMA_READ_POLICY. On Azure NCC machines it is set to false by default, so /etc/ima/ima-policy is used.

Advanced Development Using Humane-RAChain-NS

Server (CVM)

  • On the server side, the simplest approach is to write additional definitions (such as additional workload-execution requests) directly into Humane-RAChain-NS/server/api.py. If you write a server script from scratch — for example because you do not wish to use FastAPI/uvicorn — first add the following import:

    from attester import do_attestation

    Then call the Humane-RAChain-NS server-side Attestation API in your endpoint function as follows:

    result = do_attestation(
        data.ncc_nonce,
        data.tpm_nonce,
        cert_pem.decode("utf-8"),
        gpu_enabled
    )

    Note that cert_pem is the TLS self-signed certificate dynamically generated per session; this dynamic generation and the directive to use it must also be implemented separately.

  • In Humane-RAChain-NS/server/api.py, after creating uvicorn.Config, the SSL context is built with config.load(), and TLS session-ticket resumption is disabled with config.ssl.options |= ssl.OP_NO_TICKET. This ensures that a full TLS handshake is always performed on each reconnect, so that client-side certificate pinning (AttestedCertPinningAdapter in client/client.py) is evaluated every time. Only subsequent requests over a TLS session using the same RA-confirmed certificate are accepted after Attestation.

Client

For the client-side usage example, the do_attestation() function in Humane-RAChain-NS/client/client.py is a necessary-and-sufficient sample. Detailed implementation details are documented as comments inside that function — refer to those. The do_attestation() function can also of course be reused as-is. Some of the configuration written inside this function is also described in subsequent sections.

  • To use Humane-RAChain-NS on the client side, first add the following import:

    from ra_verifier import init_verifier, send_attestation_challenge, verify_response
  • After specifying the server URL and the snpguest path, call the init_verifier() function for initialization.

  • While taking the server response, the NCC Attestation nonce, and the TPM Quote nonce as return values, call send_attestation_challenge() to send the Attestation request to the CVM. The nonces are randomly generated on the client side inside the called function.

  • If the above request completes successfully, call verify_response() to verify the Attestation evidence and judge whether RA is accepted.

  • Output like the following is displayed because a self-signed certificate is used. As previously described, this is intentional for RA-TLS-style operation and can be ignored:

    /usr/lib/python3/dist-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
    warnings.warn(
  • If RA is accepted, that TLS session is maintained almost permanently until the client closes it, so use that TLS session to send further processing requests to the CVM. In the Humane-RAChain-NS sample, Humane-RAChain-NS/server/sample.py is invoked, which simply adds two integers (no GPU is used); however, GPU-using requests are of course possible. With NCC enabled, GPU processing also runs in a TEE-protected state.

Repository Structure

Tree:

Humane-RAChain-NS/
├── README.md
├── sequence.pu
├── sequence.svg
├── client
│   ├── client.py
│   ├── policy
│   │   └── client_gpu_ra_policy.json
│   ├── ra_verifier.py
│   └── settings.yaml
├── server
│   ├── api.py
│   ├── attester.py
│   ├── cert_gen.py
│   ├── policy
│   │   └── server_gpu_ra_policy.json
│   ├── run-server.sh
│   └── sample.py
└── subtools
    ├── hashlist_generator.py
    ├── ima_appraise_policy_generator.py
    └── measurement_extractor.py
  • README.md: this file.

  • sequence.pu: sequence-diagram source.

  • sequence.svg: sequence diagram.

  • client: stores client-side scripts and policy files.

    • client.py: script that uses Humane-RAChain-NS to request RA processing and subsequent Confidential Computing. When writing your own application with Humane-RAChain-NS, this is the script-equivalent portion you implement.
    • policy
      • client_gpu_ra_policy.json: Attestation policy file for NCC Attestation. Used on the client side, but since the server is expected to verify at the same level as the client, keeping it identical to server_gpu_ra_policy.json is safest.
    • ra_verifier.py: module that handles the client-side RA processing. When developing your own application, import this.
    • settings.yaml: client config file. Configures the snpguest install path, NCC-Attestation enable/disable, PLATFORM_INFO Appraise Policy, enable/disable of per-PCR reproduction-and-verification, etc.
  • server:

    • api.py: script to run the Humane-RAChain-NS-augmented RA-enabled server. When writing your own application with Humane-RAChain-NS, this is the script-equivalent portion you implement.
    • cert_gen.py: script implementing the logic to dynamically generate the per-session TLS self-signed certificate.
    • policy:
      • server_gpu_ra_policy.json: NCC Attestation policy file. Used on the server side, but since it should be verified at the same level as the client, keeping it identical to the client policy is safest.
    • run-server.sh: server-side launcher script. After verifying that IMA-related files exist, it invokes api.py. To disable NCC Attestation, run with the --no-gpu flag.
    • sample.py: sample secure-computation script. Just adds two integers it receives. No GPU computation is performed; if you want to benefit from NCC, supply your own.
  • subtools:

    • hashlist_generator.py: script that computes the hash list of files targeted for PCR23 Extend. To disable NCC Attestation, run with the --no-gpu flag.
    • ima_appraise_policy_generator.py: script that generates the verification policy for IMA logs.
    • measurement_extractor.py: script that obtains the SEV-SNP Attestation Report on the SEV-SNP CVM and extracts the Measurement. Its significance and usage are as described earlier.

License

The portions specific to this repository are provided under the MIT License.

client/policy/client_gpu_ra_policy.json and server/policy/server_gpu_ra_policy.json are derived from NVGPURemotePolicyExample.json of nvtrust (Apache-2.0 License), so the Apache-2.0 License applies to these.

For details, see LICENSE.


日本語版

本リポジトリは、主にAzureのStandard_NCC40ads_H100_v5での実行を想定した、NVIDIA Confidential Computing(NVIDIA HopperアーキテクチャGPUから対応しているGPU TEE;以下、NCC)とAMD SEV-SNP双方に対して、Remote Attestation(RA)を実施するためのRAチェーンフレームワークを提供するものである。

NCCは、SEV-SNPをはじめとしたCVM(Confidential VM)からAttestationを実行する必要があり、CVMに対するリモートユーザ(Relying Party)が、CVMを経由せずにリモートから直接RAを行う事はできない。また、SEV-SNP自体もTCB(Trusted Computing Base)が大きい事やブートシーケンスの多段性から、環境も鑑みた上でセキュリティ的にベストプラクティスでのRAを行う事は非常に難しく、既存のフレームワークもなかなか存在しない状況である。

そこで、Humane-RAChain-NSは、まずNCCに対するAttestationを実施し、その証跡やその結果を、SEV-SNP(のAMD Root Key)をトラストアンカーとしたトラストチェーン(具体的には、そのAttestation KeyがSEV-SNP Attestation ReportにバインドされているvTPM Quote)に縛り付ける。その上で、SEV-SNP Attestation ReportやvTPM Quoteを可能な限り適切に検証する事で、NCC、SEV-SNP、VMの低レイヤ層(vTPMやOVMF等)、カーネル、そして希望するワークロードに至るまで、連鎖的にRAによる信頼性の確立を行う(RAチェーンを確立する)事ができる。

現時点では、Azure以外での動作は動作保証外としている。

Humane-RAChain-NSが実現できる処理について

具体的には、以下のような前提・目標を実現する処理を、このHumane-RAChain-NSにより実施する事ができる。なお、原則的に以下の全ての処理はHumane-RAChain-NSにより自動的に実行されるものであり、このライブラリを用いる開発者・ユーザは、単に利用する上ではこれらの処理を意識(実装)する必要はない。

  • まずはSEV-SNP CVMがNCCのAttestationを実施し、その後そのSEV-SNPをはじめとしたCVMのAttestationを実施する事で、NCCからRelying PartyまでのRAチェーンを確立するという手続きの流れを取る。よって、まずはNCCのAttestationから実施する。

  • CVMは、NVIDIAのAttestation SDKを用いる事により、NCCのEvidence(SGXにおけるQuote相当)を取得する。その後、Humane-RAChain-NSでは、NRAS(NVIDIA Remote Attestation Service)に依頼する事で、Evidenceの検証を実現している(Remote GPU Attestation)。これにより、CVM-NCC間のAttestationを実現できる。クライアント(Relying Party)がnonceを送信し、それをCVM側で用いる事で、Evidenceの再生攻撃対策を行っている。

    • このEvidenceや検証結果(Attestation Report)は、AMDをトラストアンカーとしたトラストチェーンで信頼性の担保されたvTPM(以下、単にvTPMとも表現する)のPCR(プラットフォーム構成レジスタ)にそのハッシュ値を格納する。よって、これらデータ及びTPM Quoteを用いる事で、その完全性を保証できる仕組みとなっている。

    • PCRバンクについては、ハッシュアルゴリズム(sha1, sha256, sha384)それぞれが別々の領域(PCRバンク空間)を持つが、Humane-RAChain-NSではsha256のバンクを一律で使用している。

  • CVMとRelying PartyとのTLS通信には、CVMがセッションごとに動的に生成した自己署名証明書及びTLSセッション(TLS通信路鍵含む)を使用する。自己署名証明書はvTPMのPCRでハッシュ測定されるため、RAを受理した上でこの自己署名証明書に紐づくTLS通信を続ける限り、Relying Partyは通信相手が期待するCVMである事を確信する事ができる。

    • 自己署名証明書とTLS暗号鍵がバインドされている事は、RAによりHumane-RAChain-NSが正しく動作している事を検証する事で、自動的に保証される。
  • NCCのAttestation後、次にCVMはSEV-SNPのAttestation Report(SGXにおけるQuoteとAttestation Reportを兼ねたような構造)を生成する。Azure CVMにおいては、HCL Report(SEV-SNP Report、REPORT_DATAにバインドされるJSON、ハッシュアルゴリズム,TEEタイプ等のメタデータからなる構造体)に格納された状態で生成される。同時に、Attestation Reportへの署名に使用するVCEKに対する証明書(VCEK Cert)や、SEV-SNPのAttestation Reportにも同梱(即ち、AMDのトラストチェーンにバインド)されているTPM AK(Attestation Key)公開鍵の取得も実施する。

    • これらはRelying Partyに受け渡され、SEV-SNP Attestation Reportの真正性の確認や、TPM AKの真正性の確認をRelying Party側で実施する実装にしている(Relying Party側でAttestationの検証を実施する)。
  • SEV-SNPのAttestation関連データの取得が完了したら、次はvTPMのPCRバンク23番に対する、Humane-RAChain-NS含むランタイムワークロードの測定を行う。具体的には、以下のデータやファイルを逐次PCR23番にExtendする事により、PCR23番により必要なコンポネントの完全性追跡を行えるようにしている:

    • CVM内で動的生成したTLS自己署名証明書。前述の通りCVMとのセッションの一意な識別のために参照できるデータである
    • SEV-SNP Attestation Reportへの署名に使用されたVCEKに対するVCEK Cert
    • TPM AK公開鍵
    • NCC AttestationのEvidence
    • NCC Attestation Report
    • Humane-RAChain-NSのサーバ側スクリプト及びNCC Attestationポリシ
    • RA後に実行するワークロードスクリプト

    これにより、上記データの出所が確実に通信相手のCVMである事を、Relying Partyは確信する事ができる。

  • この時点でSEV-SNP Attestation Reportの生成が完了しており、かつPCRへの必要なデータの測定値登録が済んでおり、そしてこのPCR等に基づくTPM Quoteへの署名のためのAKに対する公開鍵はSEV-SNP Attestation Reportにバインドされている。よって、次は実際にTPM Quoteの生成を実施する。この生成の際には、NCCのAttestation時同様、Relying Partyから送信されたnonceを含める事により、再生攻撃対策を実施している。

    • TPM Quoteに含めるPCRバンクは、デフォルトでは0〜10、12、14、23である。PCR0〜7はゲストOSの直前までのファームウェア層(VMPL0〜2)、PCR10はIMA(Integrity Measurements Architecture)ポリシ(OSカーネル層及び一部のランタイムワークロード)、23は上述で登録した各種データに対するハッシュ値が格納されている。9、10、12、14はIMA関係で変動が発生する可能性があるため念の為同梱している。IMAログのboot_aggregateエントリはPCR0〜9の連結のハッシュ値であり、これを検証するためにPCR8番も同梱している。

    • Humane-RAChain-NSの各種スクリプトやランタイムワークロードを測定対象とするIMAポリシをブート時にロードしておく事で、SEV-SNP→ファームウェア→OSカーネル→Humane-RAChain-NS・ワークロードという、セキュアブートやMeasured Boot的なトラストチェーンをSEV-SNPレベルで保証する事ができる。ただし、現時点ではIMAポリシ自体を縛る機構が存在しないため、トラストチェーンの繋がりが不完全である。

    • PCR0〜7に対応するファームウェア層(OVMFやSVSM、vTPM実装本体等の含まれる層)は、Azureによってソースコードが公開されていないため、Azure上で動作させる場合にはいわゆるオレオレ測定値の状況となっている。ただし、ソースが公開されているクラウドで使用すると、ソースとの測定値検証を併せる事で、完全にゼロトラスト的に検証できるようになる。

  • これにより、SEV-SNP〜Humane-RAChain-NS及びワークロードに及ぶチェーンを証明するための証跡が揃ったため、CVMはRelying Partyに以下のデータを転送する:

    • 動的生成した自己署名TLS証明書
    • VCEK Cert
    • HCL Report(SEV-SNP Attestation Reportを含む)
    • NCC AttestationのEvidence及びAttestation Report
    • TPM AK公開鍵
    • TPM Quote
    • IMAポリシ及び測定ログ
  • 究極的にはLinuxのIMAにより全てのOSカーネル以降のランタイムコンテンツを測定できるため、PCR23番へのExtendはIMAポリシの設定次第では意味的には冗長となる。しかし、IMAログは非常に長大となる事が多く、これを目視確認するというのは負担が大きい。よってユーザビリティの観点から、最低限のコンテンツ(前述の通り)に関してはPCR23番にもExtendして簡易的に確認できるようにし、完全かつ網羅的に確認したい場合にはPCR10番をチェックする事も可能、という2段構えの構成としている。

  • Relying Partyは、CVMから上記各データを受信後、まずはVCEK Certの検証を実施する。AMDの中間CA証明書(ASK)及びAMDルートCA証明書(ARK)により検証し、使用されたVCEKの真正性を確認する。

  • 次に、検証したVCEK Certを用いながら、HCL Reportの検証を実施する。

    • SEV-SNP Attestation Reportの署名をVCEK Certで検証し、その上で期待するSEV-SNP測定値と一致するか、期待するマシン構成(SMT無効化、TSME有効化状況、脆弱性軽減策有効化状況等)要件を満たしているかを確認する。
    • SEV-SNP Attestation Report内のREPORT_DATAが、HCL Report内のJSON(Runtime Claims)のハッシュ値と一致するか、JSON内の"user-data"としてnonceが含まれているかを確認する。
  • その後、次はTPM Quoteの検証を行いたいため、まずはTPM Quoteへの署名に使用されているTPM AKの検証を実施する。SEV-SNP Attestation ReportにバインドされたJSON内のTPM AKと、レスポンスの一部としてCVMから受け取った(vTPMから直接取得した)AKとで一致するかを確認する事で、このTPM AKの完全性の検証を実施する。

  • TPM AKの検証後は、受け取ったTPM Quoteについて、AKを用いての署名の検証を実施する。この時、受信したPCRリストの完全性についても同時に検証している。

  • TPM Quoteの検証が完了したら、PCRバンクについて、期待するハッシュと一致するかを確認する。

    • PCR0〜7については、予め事前にCVMにログインしてそのハッシュ値を取得しておき、それとAttestation結果内のPCR値と一致するかを確認する事等でファームウェア層の厳重なチェックもできるが、現時点ではそのチェック機能は実装していない。

    • PCR23については、測定対象であるファイル(のコピー)から期待されるPCR23値を計算する。具体的には、CVM側でPCR Extendしたのと同じ順序で、クライアント側でもハッシュのUpdateを行う。ここから最終的なハッシュ値がPCRバンク23番と一致するかを確認する。

    • PCR10については、IMAログから再現されるPCR値と一致することを確認することで、IMAログの真正性を確証する。その上で、IMAログの各エントリに、期待されるハッシュ値が記録されているかどうかを確認することで、ワークロードの完全性を保証する。

  • 最後に、NCC Attestationを念の為Relying Party側で実施したいというニーズのため(例:厳密にMeasured Bootで縛れば無いとは思うが、ゲストOSが何らかの方法でNCC Attestationを迂回した事を疑うユーザ等)、Relying Partyが自前でNCC Attestationを実行できるようにしている。CVM側同様、NCC AttestationのEvidenceを、NRASに投げる事によってAttestation検証を行う。EvidenceにはRelying Party指定のnonceが含まれるため、これにより自前で確実にNCCのAttestationをRelying Partyの手によって実施する事ができる。

動作確認済み環境

サーバ(CVM with NCC)

  • OS: Ubuntu 22.04.5 LTS
  • Azure VMインスタンス: Azure Standard_NCC40ads_H100_v5
  • Linuxカーネル: 6.8.0-1018-azure
  • nvattest CLI: nvattest 1.2.0+1772475102 (Linux/x86_64)(旧nv-attestation-sdkの後継)
  • snpguest: バージョン0.8.2
  • Python: 3.10.12
  • tpm2_pytss: バージョン2.3.0
  • tpm2-tools: バージョン5.2-1build1

サーバ(CVM without NCC)

  • OS: Ubuntu 24.04.1 LTS
  • Azure VMインスタンス: Azure Standard DC2ads_v6
  • Linuxカーネル: 6.14.0-1017-azure-fde
  • snpguest: v0.10.0
  • Python: v3.12.3
  • tpm2_pytss: Commit c7fd022
  • tpm2-tools: Commit d15fc36 (次期リリースv5.8.0)

クライアント

サーバと同一マシン(環境)上での動作は確認済み。

同時に、以下の環境でのリモートでの動作も確認済みである。

  • OS: Ubuntu 22.04.3 LTS
  • Azure VMインスタンス: Standard_DC4s_v3
  • Linuxカーネル: 6.8.0-1018-azure

その他、サーバと重複している各種ライブラリ等はサーバのバージョンに合わせて動作確認済み。また、手元の環境の関係上、クライアント側についてはIntel SGXインスタンス(Standard_DC4s_v3)でリモートの動作確認を行っているが、クライアント・サーバ共にIntel SGX機能は一切不要である。クライアント側は、SGX含む、一切のTEEを搭載していないインスタンスでの実行を前提に実装している。

Python仮想環境(venv)の利用について

本リポジトリのサーバ・クライアントは、Pythonパッケージを requirements.txt でまとめて管理しており、venv配下で実行する事を前提としている。Ubuntu 23.04以降では、そもそも pip install によるシステムパッケージへの直接インストールがデフォルトで制限されている(PEP 668)ため、venvの使用はほぼ必須になる。

以下の導入手順では、サーバ側は Humane-RAChain-NS/server/ 配下、クライアント側は Humane-RAChain-NS/client/ 配下にそれぞれ venv を作成する運用を前提に記述する。venvの作成・有効化・依存パッケージの導入は利用者側で事前に実施する方式とし、run-server.sh 等の実行スクリプト側ではvenvの有効化やpip installは行わない。

venvパッケージが導入されていない場合は、以下のコマンドで導入しておく。

sudo apt install -y python3-venv

導入方法

サーバ(CVM)

AzureのNCCインスタンスに導入する事を前提とし説明する。

リポジトリのクローン

  • Humane-RAChain-NSのリポジトリをクローンする。以降の前提パッケージ導入手順では、クローン済みである事を前提とする。

    git clone https://github.com/acompany-develop/Humane-RAChain-NS.git

前提パッケージのインストール

  • Pythonやpipがインストールされていない場合は、公式手順に従いインストールしておく。Pythonは3.10.12にて動作確認済みである。

  • PythonでTPM操作を行うために必要な前提パッケージをaptにてインストールする。

    sudo apt -y install libtss2-dev pkg-config python3-dev
  • 後述のMeasurement抽出のTPM操作の際に使用するため、以下のインストールを実施する。

    sudo apt -y install tpm2-tools
  • 必要なPythonパッケージは server/requirements.txt にまとめて記述している(tpm2-pytss についてはPyPI上で未修正のバグを回避するためGitHubから最新版を取得するようにしてある)。サーバ用のvenvをサーバディレクトリ配下に作成し、有効化した上でまとめて導入する。

    cd Humane-RAChain-NS/server/
    python3 -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt

    以降、サーバ側の操作(後述のNCC関連パッケージのインストールや run-server.sh の実行等)は全て source venv/bin/activate を行った状態で実施する事。

vTPMへのアクセス権限の付与

  • Humane-RAChain-NSを実行するユーザにログインし、以下のコマンドを実行する。これにより、vTPMに対してsudo無しでアクセスできるようになる。実行後は再起動する事で、グループ追加を反映させる。

    sudo usermod -aG tss $USER
    newgrp tss

NCC関連パッケージのインストール

NCC Attestationを実施しない場合、以下の手順は省略してよい。

  • NCC GPU Attestationには、NVIDIA公式配布の nvattest CLIを使用する(旧 nv-attestation-sdk はDeprecated)。nvattest はシステムバイナリとしてPATH上に配置しておけばよく、Pythonのvenvにインストールする必要はない。インストールをするには、こちらに表示されている以下のコマンドを実行する。

    wget https://developer.download.nvidia.com/compute/nvat/1.2.0/local_installers/nvat-repo-ubuntu2204-1-2-local_1.0-1_amd64.deb
    sudo dpkg -i nvat-repo-ubuntu2204-1-2-local_1.0-1_amd64.deb
    sudo cp /var/nvat-local-repo-ubuntu2204-1.2.0/nvat-*-keyring.gpg /usr/share/keyrings/
    sudo apt-get update
    sudo apt-get -y install nvattest

    ただし、上記コマンドはバージョンアップデートに伴い変わる事が予想されるため、リンク先で実際のコマンドを確かめる事を推奨する。また、違うOSバージョンやディストリビューションの場合には、上記リンク先にて自身の環境に合わせた選択を行い、その後表示されたコマンドに従いインストールを実施する事。

  • インストール後、以下のコマンドでバイナリがPATH上から見えていることを確認しておく。

    nvattest --version

    Humane-RAChain-NSは、サーバ側の attester.py からこの nvattestsubprocess 経由で呼び出し、以下の2ステップでAttestationを実施する。

    1. nvattest collect-evidence で GPU Evidence(SGXにおけるQuote相当)を取得
    2. nvattest attest --verifier local でEvidenceの真正性を検証し、Attestation Reportを取得

    デフォルトでは、後述のPCR23番にこのnvattestのバイナリもExtendするため、クライアント側での再計算のためにクライアントと同じバージョン(ディストリビューション含む)のものを用意する事。あるいは、後述の説明に従い、PCR23番への拡張対象から除外する事も可能である。

  • Azureの公式手順ではCUDA Toolkitがインストールされないため、Humane-RAChain-NS上で動作するワークロード向けのGPUプログラミングを行う時のために、これをインストールしておく。

    wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
    sudo dpkg -i cuda-keyring_1.1-1_all.deb
    sudo apt update
    sudo apt -y install cuda-toolkit-13-1

    以下のコマンドを実行し、バージョン情報が出れば正常に導入できている。

    export PATH=/usr/local/cuda-13.1/bin:$PATH
    nvcc --version

IMA設定

ユーザワークロード等、OSカーネルよりも先のコンテンツを測定するには、LinuxのIMA機能を用いる必要がある。よって、このIMAに関する設定も実施する。

  • TDにログインし、/etc/フォルダ配下にimaというフォルダを作成する。

    sudo mkdir /etc/ima
  • 作成したフォルダに移動し、ima-policyというファイルを作成する。これ以降、不完全な状態でTDの電源が落ちると復元不能な破壊を招くおそれがあるため、続く手順以外の方法では絶対にTDを落とさない事。

    cd /etc/ima
    sudo touch ima-policy
  • 作成した上記ファイルに以下の内容を記載する。FILE_CHECKの行は、一旦はコメントアウトのままで良い。後述の「IMAの詳細設定」セクションにて、より実態に即した詳細な設定方法について説明する。

    # PROC_SUPER_MAGIC
    dont_measure fsmagic=0x9fa0
    # SYSFS_MAGIC
    dont_measure fsmagic=0x62656572
    # DEBUGFS_MAGIC
    dont_measure fsmagic=0x64626720
    # TMPFS_MAGIC
    dont_measure fsmagic=0x1021994
    # DEVPTS_SUPER_MAGIC
    dont_measure fsmagic=0x1cd1
    # BINFMTFS_MAGIC
    dont_measure fsmagic=0x42494e4d
    # SECURITYFS_MAGIC
    dont_measure fsmagic=0x73636673
    # SELINUX_MAGIC
    dont_measure fsmagic=0xf97cff8c
    # SMACK_MAGIC
    dont_measure fsmagic=0x43415d53
    # CGROUP_SUPER_MAGIC
    dont_measure fsmagic=0x27e0eb
    # CGROUP2_SUPER_MAGIC
    dont_measure fsmagic=0x63677270
    # NSFS_MAGIC
    dont_measure fsmagic=0x6e736673 
    
    # 測定対象及び測定トリガの設定
    
    # プログラムの実行に際してMMAPされるファイルの測定
    measure func=MMAP_CHECK mask=MAY_EXEC
    
    # 実行されたバイナリプログラムの測定
    measure func=BPRM_CHECK mask=MAY_EXEC
    
    # root (uid=0) によってopenされたファイルの測定
    # measure func=FILE_CHECK mask=MAY_READ uid=0
    
    # ロードされたカーネルモジュールの測定
    measure func=MODULE_CHECK
    
    # カーネルにロードされたファームウェアの測定
    measure func=FIRMWARE_CHECK
    
  • VMインスタンスを再起動する。

クライアント

リポジトリのクローン

  • Humane-RAChain-NSのリポジトリをクローンする。以降の前提パッケージ導入手順では、クローン済みである事を前提とする。

    git clone https://github.com/acompany-develop/Humane-RAChain-NS.git

前提パッケージのインストール

  • サーバの導入手順同様、Pythonやpipがインストールされていない場合は、公式手順に従いインストールしておく。Pythonは3.10.12にて動作確認済みである。

  • TPM操作(TPM Quote検証)に必要な以下のライブラリのインストールを実施する。

    sudo apt -y install tpm2-tools

    2026年2月現在、tpm2-toolsの最新バージョン5.7で未修正のバグが存在し、本リポジトリは一部のバグの影響を受ける。当該バグは次期リリース5.8で修正予定である。当面の間は、以下のコマンドにより、GitHubからパッチ適用済みの最新版を自前でビルドする。

    sudo apt install -y build-essential autoconf autoconf-archive automake libtool pkg-config libssl-dev libtss2-dev libcurl4-openssl-dev
    git clone https://github.com/tpm2-software/tpm2-tools.git
    cd tpm2-tools
    ./bootstrap
    mkdir -p build
    cd build
    ../configure
    make -j"$(nproc)"
    cd tools
    sudo install -m 0755 ./tpm2 /usr/local/bin/tpm2
    sudo ln -sf /usr/local/bin/tpm2 /usr/local/bin/tpm2_checkquote
  • SEV-SNP Attestation ReportやVCEK Certの検証に用いる、snpguestとそれに必要なRustのインストールを実施する。

    sudo apt install -y build-essential clang
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    source "$HOME/.cargo/env"
    git clone https://github.com/virtee/snpguest.git
    cd snpguest
    cargo build -r
  • 必要なPythonパッケージ(requestscryptographypyyaml、及びIMAログ検証用のIMA-PCR-Utils)は client/requirements.txt にまとめて記述している。クライアント用のvenvをクライアントディレクトリ配下に作成し、有効化した上でまとめて導入する。

    cd Humane-RAChain-NS/client/
    python3 -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt

    以降、クライアント側の操作(後述のNCC関連パッケージのインストールや client.py の実行等)は全て source venv/bin/activate を行った状態で実施する事。

NCC関連パッケージのインストール

NCC Attestationを実施しない場合、以下の手順は省略してよい。

  • クライアント側でNCCのEvidenceをダブルチェック(settings.yamlverify_ncc_flag: true)する場合は、サーバ側と同様にNVIDIA公式配布の nvattest CLIをクライアント環境のPATH上に配置しておく必要がある(旧 nv-attestation-sdk はDeprecated)。こちらもPythonのvenvにインストールする必要はない。

    インストール後、以下のコマンドでバイナリがPATH上から見えていることを確認しておく。

    nvattest --version

    Humane-RAChain-NSのクライアントは、サーバから受信したEvidence配列を一時ファイルに書き出し、nvattest attest --verifier local --gpu-evidence-source filesubprocess 経由で呼び出す事で再検証を行う。

    デフォルトでは、後述のPCR23番にこのnvattestのバイナリもExtendするため、クライアント側での再計算のためにサーバと同じバージョン(ディストリビューション含む)のものを用意する事。あるいは、後述の説明に従い、PCR23番への拡張対象から除外する事も可能である。

各種設定

とにかく実行確認だけしたい場合は、このセクションではexpected_measurement.datの取得とPLATFORM_INFOの指定([2, 2, 2, 2, 2, 2]とすると全てのPLATFORM_INFO検証をスキップする)のみ確認・実施し、後続の「実行」セクションの手順に従い実行する事を勧める。

サーバ(CVM)

  • PCRバンク23番に登録する、Humane-RAChain-NSの各スクリプトやNCC Attestation用ポリシ、及びランタイムワークロード(Humane-RAChain-NSによりRA受理後に実行させるスクリプト)は、Humane-RAChain-NS/server/attester.pyの以下の部分で設定している。

    # PCR Extend対象のHumane-RAChain-NSスクリプトファイル名
    PCR_EXTEND_TARGET_HUMANE_BASE = [
        "api.py", 
        "attester.py", 
        "cert_gen.py",
    ]
    
    # NCC Attestation有効時に追加されるファイル
    PCR_EXTEND_TARGET_HUMANE_GPU = [
        "policy/server_gpu_ra_policy.json",
        "/usr/bin/nvattest",
    ]
    
    # ...
    
    # PCR Extend対象のワークロードファイル名
    PCR_EXTEND_TARGET_WORKLOADS = [
        "sample.py"
    ]

    もしHumane-RAChain-NS本体のスクリプト構成やNCC Attestationポリシファイル構成に変更を加える場合には、上側のPCR_EXTEND_TARGET_HUMANE部分の編集を忘れないようにする事。ここに記載されていないファイルは、TPM Quote作成の際にPCRバンク23番に測定値が登録されなくなる。
    一方で、ランタイムワークロードの方を変更する場合は、下側のPCR_EXTEND_TARGET_WORKLOADSの方に追記や変更を適用する事。例えば、デフォルトのサンプルスクリプト以外を実行させる場合には、必ずこの部分の変更が必要になる。
    フォルダを指定すると、その中身についても再帰的に測定する。

  • NRASのURLは、Humane-RAChain-NS/server/attester.pyattest_ncc()内の以下の部分で指定している。

    NRAS_URL = "https://nras.attestation.nvidia.com/v3/attest/gpu"

    NRASのAPIバージョンがアップデートされた等、何らかの理由でこのエンドポイント指定に変更を加えたい場合には、この部分を直接変更する。

  • TPM Quoteの生成の際、どのPCRバンクを含めるかについては、Humane-RAChain-NS/server/attester.pyget_tpm_quote()内の以下の部分で指定している。

    # PCRリストファイルの生成
    # デフォルトでは0〜10、12、14、23番のPCRバンクを含める
    # 全てのPCRバンクを含める場合は sha256:all と指定する
    selector_str = "sha256:0,1,2,3,4,5,6,7,8,9,10,12,14,23"
    pcr_indices = selector_str_to_pcr_indices(selector_str)
  • 現状、IMAファイルはCVM内に存在するポリシとログをコピーしてクライアントに提示するだけである(PCRバンク10番へのIMA関連ハッシュの適用は自動的に実施されている)が、それらのファイルの位置指定はHumane-RAChain-NS/server/run-server.shにて実施している。

    SRC_POLICY="/etc/ima/ima-policy"
    SRC_MEASUREMENTS="/sys/kernel/security/ima/ascii_runtime_measurements"

    環境の相違等により、何らかの理由でこのパスを変更する必要がある場合は、上記の箇所を変更する。

  • クライアントからのリクエストを受信するポートを変更したい場合には、Humane-RAChain-NS/server/api.pyの以下の部分(port=8080)を直接変更する。

    config = uvicorn.Config(
        app=app,
        host="0.0.0.0",
        port=8080,
        ssl_certfile=cert_file_path,
        ssl_keyfile=key_file_path,
    )
    config.load()
    config.ssl.options |= ssl.OP_NO_TICKET
    
    server = uvicorn.Server(config)
    server.run()

クライアント

  • ビルドした snpguest の存在するディレクトリのパスを client/settings.yaml 内の

    # snpguest_path = "$HOME/snpguest/target/release"
    snpguest_path: "~/snpguest/target/release"

    で指定する。デフォルト設定は、ログイン中のホームディレクトリ直下(例:/home/username/配下)にsnpguestをクローンしてビルドした場合のパスである。それ以外の場所にクローンした場合や、デバッグビルドを実行した場合は適宜パスを修正する事。

  • NCC非対応のSEV-SNP CVMを使用している等、NCC Attestationを実施しない場合は、client/settings.yaml 内の以下の項目をtrueからfalseに変更する。

    # NCC Attestationが有効か無効かのフラグ。trueで有効。
    gpu_enabled: true
  • SEV-SNPのAttestationのためには、予めSEV-SNPのMeasurement(同一性測定値)を取得しておく必要がある。例えば事前に信頼可能な状況下(例:VMデプロイ前の手元)でCVMにログインし、Humane-RAChain-NS/subtools/measurement_extractor.pyを実行する事で、expected_measurement.datを生成しておく。

    cd subtools
    python3 measurement_extractor.py

    デフォルトでは、サーバとクライアントがローカルホスト上で動作させる構成での設定にしているため、単にこのスクリプトを実行すれば、自動的にclientフォルダ配下に上記のdatファイルが格納される。リモートで実行する場合等は、生成されたdatファイルをクライアント環境のclientフォルダ直下に自前で移動させる。

  • ユースケースによっては、Humane-RAChain-NSのサーバ側ソースやランタイムワークロードの実装コードを非公開にしたい、あるいはわざわざクライアント側でファイルハッシュの再計算をしたくない、というケースも十分に考えられる。そのような場合、予め渡されたり用意したりしたハッシュリストでPCR23の再現処理を行うオプションを提供している。client/settings.yaml の以下の部分

    # PCR23番のハッシュチェックの際、クライアント側でハッシュ再計算を行うのではなく、
    # 単に渡されたハッシュリストをTPM QuoteのPCR23番値と比較したい場合は、
    # 以下の変数にfalseを設定する。ハッシュリストの生成には、
    # subtools/hashlist_generator.pyを使用可能。
    # 再計算したい場合はTrueにする事。
    recalculate_pcr23_flag: true

    をtrueからfalseに変えると、clientフォルダ直下のexpected_pcr23_hash.dat内のハッシュリストにより直接Extendを実施する(ファイルハッシュの再計算は行わない)。このハッシュリストファイルは、subtools/hashlist_generator.pyにより生成できる。

    cd subtools/
    python3 hashlist_generator.py

    NCC Attestationを無効に設定している場合は、以下のように --no-gpu フラグを立てて実行する。

    python3 hashlist_generator.py --no-gpu

    ファイル以外の、RAセッションごとに動的に渡されるAttestation証跡については、このオプションに関わらず受信したデータからのハッシュ再計算を実施する。
    もしPCR23対象のファイルを変更する場合は、hashlist_generator.py配下の以下の部分も編集する事。

    # PCR Extend対象のHumane-RAChain-NSスクリプトファイル名(GPU無し)
    PCR_EXTEND_TARGET_HUMANE_BASE = [
        "../server/api.py",
        "../server/attester.py",
        "../server/cert_gen.py",
    ]
    
    # GPU有効時に追加されるファイル
    PCR_EXTEND_TARGET_HUMANE_GPU = [
      "../server/policy/server_gpu_ra_policy.json",
      "/usr/bin/nvattest",
    ]
    
    # PCR Extend対象のワークロードファイル名
    PCR_EXTEND_TARGET_WORKLOADS = ["../server/sample.py"]
  • PLATFORM_INFOという、SEV-SNPの構成(前述のSMT有効化状況等)を示すビット列がAttestation Reportに含まれ、Humane-RAChain-NSでもその検証を行っている。クライアントは、Humane-RAChain-NS/client/settings.yamlの以下の部分で、期待する値を指定可能である。

    # SEV-SNP Report内のPLATFORM_INFOのチェックに使うリスト。
    # サイズは6であり、頭から順にSMT有効、透過的SME有効、ECC有効、RAPL無効、
    # DRAMの暗号文隠蔽機能有効、BadRAM軽減策有効について保持する。
    # 0か1で期待するものを入れる。検証しない項目のメンバは2にしておく。
    expected_platform_info: [0, 2, 0, 0, 0, 2]

    各要素に対応する構成機能の説明は以下の通り(先頭の0番目要素から説明):

    1. 同時マルチスレッディング(SMT)が有効化されているか。0は無効、1は有効を示す。SMTは特にTEEの文脈では様々な攻撃に悪用される事が多いため、無効化されている事が望ましい。
    2. 透過的SMEが有効化されているか。0は無効、1は有効を示す。Cビットに関係なく、全てのメモリが自動的に暗号化される、AMD SMEの機能。
    3. ECCが有効化されているか。0は無効、1は有効を示す。ECCが有効化されていると、意図しないメモリのビット反転や、あるいは意図的にメモリビットを反転させる攻撃(RowHammer攻撃等)に対する一定の耐性が得られる。
    4. RAPLが無効化されているか。0は有効、1は無効。RAPLとはCPUレベルで提供されている消費電力監視インタフェースであるが、有効化されているとSGXにおけるPLATYPUSをはじめとしたような、一定のサイドチャネル攻撃に悪用される可能性がある点に注意。
    5. SEV-SNPのCiphertext Hidingが有効化されているか。0は無効、1は有効を示す。これが有効化されていると、SEV-SNPで保護されたメモリを外側から読み出した場合、通常は暗号文が得られる所を特定の固定値を返すようになる。SGXにおけるAbort Page Semanticsに近い機能。
    6. BadRAM攻撃に対する軽減策が有効化されているか。0は無効、1は有効を示す。有効化されているに越した事は無いが、2025年1月現在ではまだこのビットが使われていないケースも多いと思われる。

    以上を踏まえ、基本的には0または1で期待するビットを指定する。ただし、どちらでも良いと判断したものに関しては、2と指定する事により、その検証のスキップを指定できる。前述のexpected_platform_info = [0, 2, 0, 0, 0, 2]は、これを踏まえると以下の意味を持つ事になる:

    • SMT無効化を要求
    • 透過的SMEの有効化状況は関知しない
    • ECC無効化を要求
    • RAPL有効化を要求
    • Ciphertext Hiding無効化を要求
    • BadRAM脆弱性軽減策は関知しない

    ただし、これはこのセットアップが最適である事を示すものでは決して無い。セキュリティ面だけで見れば、[0, 2, 1, 1, 1, 1]が最善ではあろうが、これを満たせるかはクラウドの用意しているマシンにも強く依存する。よって、自身のニーズや環境に合わせ、この部分は柔軟に変更する事。

    ちなみに、対象CVMでPLATFORM_INFOがどうなっているかを直接確認したい場合には、以下のようにSEV-SNP Attestation Reportを確認する事でチェックできる(CVM上で実行する):

    export PATH=$PATH:$HOME/snpguest/target/release
    tpm2_nvread -C o 0x01400001 > ./snp_report.bin
    dd skip=32 bs=1 count=1184 if=./snp_report.bin of=./guest_report.bin
    snpguest display report guest_report.bin

    snpguest displayの実行結果には、以下のようにPLATFORM_INFOに関する情報が含まれている(BadRAM軽減策に対応するALIAS_CHECK_COMPLETEついては現時点では未対応):

    Platform Info (0):
    SMT Enabled:               0
    TSME Enabled:              0
    ECC Enabled:               0
    RAPL Disabled:             0
    Ciphertext Hiding Enabled: 0
  • CVMのURL指定は、client/configs.yamlの以下の部分で実施しているため、リモートで実行する場合等変更の際には、この部分を編集する。

    # 末尾の"/"を忘れないようにする事。
    server_url: "https://localhost:8080/"
  • PCRバンク23番に測定値が登録されている事を期待する、Humane-RAChain-NSのスクリプトやポリシ、そしてランタイムワークロードは、クライアント側ではHumane-RAChain-NS/client/ra_verifier.pyの以下の部分において列挙している:

    # PCR Extend対象のHumane-RAChain-NSスクリプトファイル名
    PCR_EXTEND_TARGET_HUMANE_BASE = [
        "../server/api.py",
        "../server/attester.py",
        "../server/cert_gen.py",
    ]
    
    # NCC Attestationに追加されるファイル
    PCR_EXTEND_TARGET_HUMANE_GPU = ["../server/policy/server_gpu_ra_policy.json"]

    サーバの設定時同様、必要に応じてこの部分を追記・変更の事。なお、リモートでクライアントを動作させる場合、クライアントの手元にあるサーバ用スクリプト・ポリシと、サーバで実際に使用されているもの(サーバ側でPCR23番に登録されるもの)は、完全に一致するものであるという前提がある。よって、それらに対して何らかの変更を加える場合には、サーバとクライアント双方に配置されているサーバ関係ファイルを、全く同じ形で変更する必要がある(でないとPCR23番のハッシュチェックに失敗する)。

  • NRASのURLは、Humane-RAChain-NS/client/ra_verifier.pyverify_ncc_attestation()内の以下の部分で指定している。

    NRAS_URL = "https://nras.attestation.nvidia.com/v3/attest/gpu"

    NRASのAPIバージョンがアップデートされた等、何らかの理由でこのエンドポイント指定に変更を加えたい場合には、この部分を直接変更する。

  • 現状では、ファームウェア層に相当するPCR0〜7のハッシュ値を、クライアント側にてファームウェアソースからビルドしハッシュを再現する機能は未実装である。必要な場合には、再現したハッシュを用意した上で、Humane-RAChain-NS/client/ra_verifier.pyverify_response()関数の内、check_tpm_quote()関数の正常実行が完了した後でPCR0〜7の検証処理を実施すると良い。

  • NCC AttestationのEvidenceの自前検証を必要としない場合には、使用方法のセクションでも記述の通り、verify_reponse()関数の呼び出し時の当該引数(Humane-RAChain-NS/client/settings.yamlではverify_ncc_flag)をFalseにする。

  • IMAログの各エントリの検証を実施する場合は、Humane-RAChain-NS/client/settings.yamlの以下の部分で検証ポリシのパスを指定する。

    # IMA appraise policyファイル(YAML)へのパス。client.pyからの相対パス、
    # もしくは絶対パスで指定する。subtools/ima_appraise_policy_generator.pyで
    # 生成可能。verify_pcr10_flagがtrueの場合のみ参照される。
    ima_appraise_policy_path: "ima_appraise_policy.yaml"

    ima_appraise_policy.yaml は測定対象のパス(fnmatchフォーマット)及びハッシュ値のAllowリスト(またはDenyリスト)からなる。

    home_Humane_RAChain_NS_server_sh:
      path: /home/**/Humane-RAChain-NS/server/*.sh
      allow:
      - 28f97e660dd1061224c64ee4ad9d3a63c9b402465323de962f70ee318d8a88e7
    home_Humane_RAChain_NS_server_py:
      path: /home/**/Humane-RAChain-NS/server/*.py
      allow:
      - 0dce80960c8b3464639aeb7a49eb8a1f13964617f3c06c095db8795a4069245a
      - 0e0de7474b3e4b368d518fd657b4fd6701b27c962b258992dd55e418b96262aa
      - 4ed066d8cc9ea214d78d7de5ad65b76e953c82023efe43f76c1006a3403a5e4b
      - aebf70b1aa84c4bdccd288462ae4c4cb7228695ae27797b0e5c2325481b95a9b
    home_Humane_RAChain_NS_server_policy_server_gpu_ra_policy_json:
      path: /home/**/Humane-RAChain-NS/server/policy/server_gpu_ra_policy.json
      allow:
      - 61e6919e3834b4a07a857de19e475695fa7db1d9bd3d247e8ce828ed8fcbf59b
    usr_bin_python3:
      path: /usr/bin/python3
      allow:
      - e1efa562c2cc2e35521a5c9c9b9939921001ff8ca9708a13ef15ace68cc2ccd7

    例えば、事前に信頼可能な状況下でCVMにログインし、Humane-RAChain-NS/subtools/ima_appraise_policy_generator.pyを実行することにより、その時点でのターゲットファイルのハッシュ値に基づき、IMA検証ポリシを自動生成できる。

    python3 ima_appraise_policy_generator.py

    IMA検証ポリシ生成時の測定ターゲットはima_appraise_policy_generator.pyの以下の箇所で設定されている。

    # IMA appraise policyとして指定したいパスのパターンのリスト。
    # 各要素はglob(および実行時にはfnmatch)として解釈されるパスパターン。
    # 再帰展開したい場合は "**" を含めて、本スクリプトはglob.glob(recursive=True)で展開する。
    # 注: 実行時の照合はfnmatch.fnmatchcaseなので、できるだけ実際のIMA log上の
    # file_pathと一致するように厳密なパターンを書くこと。
    APPRAISE_TARGETS = [
        "/home/**/Humane-RAChain-NS/server/*.sh",
        "/home/**/Humane-RAChain-NS/server/*.py",
        "/home/**/Humane-RAChain-NS/server/policy/server_gpu_ra_policy.json",
        "/usr/bin/python3",
    ]

実行

Humane-RAChain-NSをそのまま実行する場合の実行手順について説明する。

サーバ(CVM)

サーバ用venvを有効化した状態で、以下のコマンドで実行シェルスクリプトを実行する。run-server.sh 自体はvenvの有効化や依存パッケージの導入を行わないため、導入手順に従って事前に venv を作成し、source venv/bin/activate を済ませておく必要がある。

cd Humane-RAChain-NS/server/
source venv/bin/activate
./run-server.sh

NCC Attestationを無効に設定する場合は、以下のように --no-gpu フラグを立てて実行する。

source venv/bin/activate
./run-server.sh --no-gpu

実行例は以下の通り(標準出力が大きいため、ログの最後の方のみ掲載):

[Fetch TPM Attestation PubKey]
Fetched TPM Attestation PubKey successfully.

[Reset PCR bank 23]
PCR 23 was successfully reset.

[Extend PCR with evidences]
Extended PCR 23 with VCEK Cert/AK Pub successfully.
Extended PCR 23 with NCC evidences successfully.

[Get TPM Quote]
Generated TPM Quote successfully.
Generated PCR values list successfully.

[Get IMA-related files]
Got IMA-related files successfully.

INFO:     127.0.0.1:36756 - "POST /attestation HTTP/1.1" 200 OK

[Execute sample secret addition]
Added secrets successfully.

INFO:     127.0.0.1:36756 - "POST /sample-addition HTTP/1.1" 200 OK

クライアント

クライアント用venvを有効化した状態で、以下のコマンドにより client.py を実行する。導入手順に従って事前に venv を作成し、source venv/bin/activate を済ませておく必要がある。

cd Humane-RAChain-NS/client/
source venv/bin/activate
python3 client.py

実行例は以下の通り(標準出力が大きいため抜粋):

GPU attestation: disabled
[Send attestation challenge]
Generated Nonces:
 NCC Nonce: 5aab8cd9863372289fb2ad9fb9a412e9ab09545926537ac5afccdd80e1820f08
 TPM Nonce: e3891742fbd624d256fb2acb119f7c699abc24722954f16bec4cafa9a80dd136
 SNP Nonce: 75bef4d5574b8a3625c09e3ec796d7f692cf2e0e12f5cc1ec84b0037a3d9bafae16129df2a9cadd103290b1abf51c4d782a1caee0206676a8d8ad4cd069c6343

...

[Verify HCL Report Data binding]
REPORT_DATA expected (sha256, zero-padded) ->
c855dd11a2ba68ab08653b6becb99e91cc22ca9257db5b596ee3605636b8b3710000000000000000000000000000000000000000000000000000000000000000
REPORT_DATA actual ->
c855dd11a2ba68ab08653b6becb99e91cc22ca9257db5b596ee3605636b8b3710000000000000000000000000000000000000000000000000000000000000000
SNP REPORT_DATA matches hash of Runtime Claims.
Runtime Claims user_data matches client-supplied nonce.

[Verify VCEK Cert with ARK Cert]
The AMD ARK was self-signed!
The AMD ASK was signed by the AMD ARK!
The VCEK was signed by the AMD ASK!

SEV-SNP VCEK is valid.

[Verify SEV-SNP Report]
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.
VEK signed the Attestation Report!

SEV-SNP's measurement hash->
e14f74982d655d4cbd686b91bcb9431ddb98b6e210e59647089d203035cf99d9a76efbdee19f0958ff3f1aa4518e86e0

Expected measurement ->
e14f74982d655d4cbd686b91bcb9431ddb98b6e210e59647089d203035cf99d9a76efbdee19f0958ff3f1aa4518e86e0

...

[Verify PCR 10]

Received PCR 10 hash (IMA related PCR) ->
f0d6af60d98acded3c1d509922d1d0579e210dc3431fee065631e03f30d36b18

Calculated PCR 10 hash ->
f0d6af60d98acded3c1d509922d1d0579e210dc3431fee065631e03f30d36b18

Received PCR 10 hash matched calculated PCR 10 hash.

[Verify boot_aggregate]

Received boot_aggregate ->
bbdbca85a82cf96aad024bdfedaa4fcc791d857b338b6f7c5a4625bce0118ac4

Calculated boot_aggregate ->
bbdbca85a82cf96aad024bdfedaa4fcc791d857b338b6f7c5a4625bce0118ac4

Received boot_aggregate matched calculated boot_aggregate.

[Appraise IMA log against IMA appraise policy]
IMA appraise policy path -> /home/azureuser/Humane-RAChain-NS/client/ima_appraise_policy.yaml
IMA appraisal passed: 525 entries (1 allow, 524 neutral).

IMA evidences verification passed.

[Skip NVIDIA CC Attestation]

Accepted RA. Proceed to next process.
Pinned session to attested cert (SHA-256 DER): 089413c0c2f90cb264f5356910955aa909322c27371b3512e69a6f1a16945145

[Request sample secret addition]
Sample secret addition result ->
300

Attestation証跡のJSONの例

Humane-RAChain-NSのサーバ側にAttestation要求を送り、返送されるAttestation証跡JSONの例(--no-gpuの場合)は、本ドキュメント前半の英文版「Example of Attestation-evidence JSON」セクションに掲載しているので、そちらを参照されたい。掲載しているJSONは英文版・日本語版に共通である。

IMAの詳細設定

IMAポリシに関しては、IMAの測定対象が非常に多岐にわたるものであるというのもあり、一概に設定の最適解を定めるというのは難しい。以下に、本リポジトリで前提としているデフォルトのIMAポリシを再掲する:

# PROC_SUPER_MAGIC
dont_measure fsmagic=0x9fa0
# SYSFS_MAGIC
dont_measure fsmagic=0x62656572
# DEBUGFS_MAGIC
dont_measure fsmagic=0x64626720
# TMPFS_MAGIC
dont_measure fsmagic=0x1021994
# DEVPTS_SUPER_MAGIC
dont_measure fsmagic=0x1cd1
# BINFMTFS_MAGIC
dont_measure fsmagic=0x42494e4d
# SECURITYFS_MAGIC
dont_measure fsmagic=0x73636673
# SELINUX_MAGIC
dont_measure fsmagic=0xf97cff8c
# SMACK_MAGIC
dont_measure fsmagic=0x43415d53
# CGROUP_SUPER_MAGIC
dont_measure fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC
dont_measure fsmagic=0x63677270
# NSFS_MAGIC
dont_measure fsmagic=0x6e736673 

# 測定対象及び測定トリガの設定
# プログラムの実行に際してMMAPされるファイルの測定
measure func=MMAP_CHECK mask=MAY_EXEC

# 実行されたバイナリプログラムの測定
measure func=BPRM_CHECK mask=MAY_EXEC

# root (uid=0) によってopenされたファイルの測定
# measure func=FILE_CHECK mask=MAY_READ uid=0

# ロードされたカーネルモジュールの測定
measure func=MODULE_CHECK

# カーネルにロードされたファームウェアの測定
measure func=FIRMWARE_CHECK

measure func=BPRM_CHECK mask=MAY_EXECがある事により、バイナリが実行された場合にそれらは全て測定されるようになる。併せて、カーネルモジュール等も測定する設定になっており、少なくとも基本的に実行に関してはトレースできるようになっている。

問題はコメントアウトしてあるmeasure func=FILE_CHECK mask=MAY_READ uid=0の部分である。実行はBPRM_CHECKで測定されるので、それ以外のファイルの読み書き追記全てを測定するとなると、この部分を以下の内容で置き換える事になる:

measure func=FILE_CHECK mask=MAY_READ
measure func=FILE_CHECK mask=MAY_WRITE
measure func=FILE_CHECK mask=MAY_APPEND

しかし、これは全ユーザの全ファイル操作を測定する事になり、膨大な量のログが発生する事になり、パフォーマンス上の懸念も生じかねない。

また、例えばWrite-Open時にRead-Openすると測定値がオール0になるという仕様もあり、単にポリシで定める以外にも運用上の懸念点は存在する。これは極論はそのような操作をし得る大元のコンテンツを入れないようにする、という事になるが、実運用上はそうとは割り切れない部分があるのも確かである。

このようなIMA設定に関する難しさはHumane-RAChain-NSのスコープからは逸脱するものであるため、あくまで上記のように設定の厳密さにグラデーションがある事を示すにここでは留める。

制約事項

前述までの説明と重複する部分も多いが改めて列挙する。

  • ファームウェア層に対応するPCR0〜7番については、ファームウェアソースからビルドしハッシュを再現した後、それと照合する機能は実装していない。Azureの場合はファームウェア層が非公開であるため、もし実装するのであれば他のクラウド環境やオンプレミス環境前提となる。

  • ルートファイルシステムに対するハッシュ測定は実施していない。必要な場合、SNPGuard等で提案されている手法と、Humane-RAChain-NSとを適切に合体させて使用する必要があり、難易度は高い。

  • Pythonの各種ライブラリや本体等に対するMeasurementの取得とRAへのバインドは実施していない。これは基本的にIMA側に依拠する事となる。

  • OSカーネルより先はIMAによって測定可能であるが、IMAポリシ自体は測定されないため変更できてしまうというIMA特有の問題がある。こちらも解決できた場合には本リポジトリに展開する予定である。

  • 証跡に同梱するIMAポリシは、ロード済みポリシ/sys/kernel/security/ima/policyまたはカスタムIMAポリシファイル/etc/ima/ima-policyからコピーしている。後者は次回CVMブート時にロードされるものであり、CVM起動後は自由に書き換え可能である。したがって前者と一致する保証はない。前者の読み取り権限はカーネル構成オプションCONFIG_IMA_READ_POLICYによって設定される。Azure NCCマシンではデフォルトでfalseに設定されているため、/etc/ima/ima-policyが使用される。

Humane-RAChain-NSを用いた応用的な開発方法

サーバ(CVM)

  • サーバ側については、Humane-RAChain-NS/server/api.pyに各種定義(追加のワークロードの実行リクエスト等)を追記する形で実行するのが最も簡単である。
    もしFastAPI/uvicornを使用したくない等の理由でサーバスクリプトをスクラッチで書く場合、まずは以下のimport文を記述する。

    from attester import do_attestation

    その後、Attestationを実施するエンドポイント関数の定義において、以下のようにHumane-RAChain-NSのサーバ側Attestation APIを呼び出す。

    result = do_attestation(
        data.ncc_nonce,
        data.tpm_nonce,
        cert_pem.decode("utf-8"),
        gpu_enabled
    )

    ただし、cert_pemはセッションごとに動的生成したTLS自己署名証明書であり、この動的生成及び使用指定についても、別個実装する必要がある。

  • Humane-RAChain-NS/server/api.pyでは、uvicorn.Config生成後にconfig.load()でSSLコンテキストを構築し、config.ssl.options |= ssl.OP_NO_TICKETでTLSセッションチケット再開を無効化している。これにより、再接続のたびに必ず完全なTLSハンドシェイクが実行され、クライアント側の証明書ピンニング(client/client.pyAttestedCertPinningAdapter)が毎回評価される。Attestation後の後続リクエストは、RAで真正性が確認された同一証明書を使用するTLSセッションのみが受理される。

クライアント

クライアント側で利用する例は、Humane-RAChain-NS/client/client.pydo_attestation()関数がそのまま必要十分なサンプルコードとなっている。詳細な実装方法についてはこの関数にコメントも記載しているため、そちらを参照の事。勿論、do_attestation()関数をそのまま流用する形でも問題ない。この関数内で記述されている各種設定の一部については、後続のセクションにおいても説明する。

  • クライアント側でHumane-RAChain-NSを用いる場合、まずは以下のimport文を記述する。

    from ra_verifier import init_verifier, send_attestation_challenge, verify_response
  • サーバURLとsnpguestのパスを指定した上で、初期化のためにinit_verifier()関数を呼び出す。

  • サーバレスポンス、NCC Attestation用nonce、TPM Quote用nonceを戻り値として構えながら、send_attestation_challenge()関数にてAttestation要求をCVMに送る。nonceは、呼び出し先関数内でクライアント側にて乱数的に生成される。

  • 上記関数による要求が正常に完了していたら、今度はverify_response()関数を呼び出す事により、Attestation証跡の検証及びRA受理判断を実行する。

  • 以下のような表示は、自己署名証明書を使用しているために表示される。前述の通り、こちらはRA-TLS的な運用のために安全を考慮した上で意図的に使用しているため、無視で良い。

    /usr/lib/python3/dist-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
    warnings.warn(
  • 検証の結果RAを受理したら、そのTLSセッションは前述の通りクライアントが切るまでほぼ永久的に維持されるので、そのままそのTLSセッションを用いて次の処理要求をCVMに対して行う。Humane-RAChain-NSのサンプルでは、GPUは使用せず単にリクエストした2つの整数を足し合わせるスクリプトを呼び出させているHumane-RAChain-NS/server/sample.pyが、勿論GPUを使用する処理の要求も可能。NCCが有効化されているので、GPU処理もTEEで保護された状態で実行される。

リポジトリ構造

ツリー図:

Humane-RAChain-NS/
├── README.md
├── sequence.pu
├── sequence.svg
├── client
│   ├── client.py
│   ├── policy
│   │   └── client_gpu_ra_policy.json
│   ├── ra_verifier.py
│   └── settings.yaml
├── server
│   ├── api.py
│   ├── attester.py
│   ├── cert_gen.py
│   ├── policy
│   │   └── server_gpu_ra_policy.json
│   ├── run-server.sh
│   └── sample.py
└── subtools
    ├── hashlist_generator.py
    ├── ima_appraise_policy_generator.py
    └── measurement_extractor.py
  • README.md: 本ファイル

  • sequence.pu: シーケンス図のソースファイル

  • sequence.svg: シーケンス図

  • client: クライアント用のスクリプトやポリシファイルを格納

    • client.py: Humane-RAChain-NSを用いてRA処理やその後のConfidential Computingを要請するスクリプト。自前のアプリケーションをHumane-RAChain-NSを用いて書く場合、このスクリプト相当の部分を実装する形になる。
    • policy
      • client_gpu_ra_policy.json: NCC AttestationのAttestationポリシファイル。クライアント側が使用するが、サーバはクライアントと同水準で検証する事が期待されるはずであるため、server_gpu_ra_policy.jsonと同一にするのが無難。
    • ra_verifier.py: クライアント側のRA処理を担当するモジュール。自前のアプリケーション開発の際には、これをimportして実装する。
    • settings.yaml: クライアントの設定ファイル。snpguestのインストールパス、NCC Attestationの有効化/無効化、PLATFORM_INFOのAppraise Policy、各PCRの再現計算・検証の有効化/無効化などを設定する。
  • server:

    • api.py: Humane-RAChain-NSを用いたRA機能付きサーバを実行するためのスクリプト。自前のアプリケーションをHumane-RAChain-NSを用いて書く場合、このスクリプト相当の部分を実装する形になる。
    • cert_gen.py: セッションごとに動的生成するTLS自己署名証明書を生成するロジックが実装されたスクリプト。
    • policy:
      • server_gpu_ra_policy.json: NCC AttestationのAttestationポリシファイル。サーバ側が使用するが、クライアントと同水準で検証する事が期待されるはずであるため、server_gpu_ra_policy.jsonと同一にするのが無難。
    • run-server.sh: サーバ側実行スクリプト。IMA関連ファイルの存在を確認した後、api.pyの呼び出しを実施する。NCC Attestationを無効にする場合は --no-gpu フラグを立てて実行する。
    • sample.py: サンプル秘密計算スクリプト。単に受け取った2つの整数を足し合わせるだけの実装である。GPUを用いた計算は行わないので、NCCの恩恵に預かりたい場合には別個用意する必要がある。
  • subtools:

    • hashlist_generator.py: PCR23番へのExtendの対象となるファイルのハッシュリストを計算するスクリプト。NCC Attestationを無効にする場合は --no-gpu フラグを立てて実行する。
    • ima_appraise_policy_generator.py: IMAログの検証ポリシを生成するスクリプト。
    • measurement_extractor.py: SEV-SNP CVMにおいてSEV-SNP Attestation Reportを取得し、Measurementを抽出するためのスクリプト。意義や使用方法は前述の通り。

ライセンス

本リポジトリに固有の部分はMITライセンスのもとで提供されます。

client/policy/client_gpu_ra_policy.json および server/policy/server_gpu_ra_policy.jsonnvtrust(Apache-2.0ライセンス)の NVGPURemotePolicyExample.json を流用しているため、これらにはApache-2.0ライセンスが適用されます。

詳細はLICENSEを参照してください。

シーケンス図

humane-rachain-ns

About

Simple and clear framework for NVIDIA CC/SEV-SNP remote attestation.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors