-
Notifications
You must be signed in to change notification settings - Fork 178
Full Virtual TPM for VMs and Containers #4071
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
c4e2e28
VTPM : Rename vtpm_api.proto to api.proto and rename vtpm binary to ptpm
shjala 1337847
VTPM : Move patch-tpm2-tools.diff to patch/patch-tpm2-tools.diff
shjala 378f68f
VTPM : Create swtpm and vtpm directories on boot
shjala c722c90
VTPM : Make /persist available in vtpm container
shjala 352022c
VTPM : Update apparmor profiles for swtpm and ptpm
shjala be3eb9e
VTPM : Update docs for PTPM and VTPM
shjala c161dfb
VTPM : Intorducing vtpmd service to bring fully virtualized TPM to th…
shjala b08cc66
VTPM : Restrict vtpm access to neede directories only
shjala c5298f1
VTPM : Increase swtpm launch timeout to 10 seconds
shjala File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # PTPM Server | ||
|
|
||
| *(warning! to be deprecated)* Proxy TPM (formerly VTPM), located in `pkg/vtpm/ptpm`, is a server listening on port `8877` in EVE, exposing limited functionality of the host's TPM to the clients. PTPM allows clients to execute [tpm2-tools](https://github.com/tpm2-software/tpm2-tools) binaries from a list of hardcoded options (listed below). | ||
|
|
||
| ## Packet Structure | ||
|
|
||
| PTPM server accepts `EveTPMRequest` commands and outputs `EveTPMResponse`. Both structures are defined in probuf format in a file located in `pkg/vtpm/ptpm/proto/api.proto`. | ||
|
|
||
| ## Communicating with PTPM | ||
|
|
||
| You can communicate with PTPM by consuming the probuf definitions in your own client or using external tools like `protoc` to generate raw protobuf commands to send over the network. | ||
|
|
||
| Another way is using `eve_run` client from [eve-tools](https://github.com/lf-edge/eve-tools). Using `eve_run` is easy because it already has a predefined command-file table and can map a command's required files to `EveTPMRequest`. To use this client, simply build it (or follow the [installation](https://github.com/lf-edge/eve-tools/blob/master/INSTALL.md) instructions if you prefer otherwise): | ||
|
|
||
| ```bash | ||
| sudo apt-get install -y libprotobuf-dev libprotoc-dev protobuf-compiler cmake g++ libssl-dev libcurl4-openssl-dev uuid-dev | ||
| cd ~ | ||
| git clone https://github.com/lf-edge/eve-tools.git | ||
| cd eve-tools/eve-tools | ||
| make | ||
| ``` | ||
|
|
||
| To run `eve_run` without installation make sure the `libevetools.so` is accessible: | ||
|
|
||
| ```bash | ||
| LD_LIBRARY_PATH=~/eve-tools/eve-tools | ||
| export LD_LIBRARY_PATH | ||
| ``` | ||
|
|
||
| ### Commands | ||
|
|
||
| Currently execution of the following commands are allowed: | ||
| | No |Command | | ||
| |--|--| | ||
| | 1 |tpm2_getcap | | ||
| | 2 |tpm2_readpublic | | ||
| | 3 |tpm2_startauthsession | | ||
| | 4 |tpm2_policysecret | | ||
| | 5 |tpm2_activatecredential | | ||
| | 6 |tpm2_flushcontext | | ||
| | 7 |tpm2_startauthsession | | ||
| | 8 |tpm2_policysecret | | ||
| | 9 |tpm2_import | | ||
| | 10 |tpm2_flushcontext | | ||
| | 11 |tpm2_load | | ||
| | 12 |tpm2_hmac | | ||
| | 13 |tpm2_hash | | ||
| | 14 |tpm2_sign | | ||
| | 15 |tpm2_verifysignature | | ||
|
|
||
| To get the details about each command, please consult the related [documentation](https://github.com/tpm2-software/tpm2-tools/tree/master/man). As an example, signing a message using TPM through `eve_run` goes as follows: | ||
|
|
||
| ```bash | ||
| #Using well-known AIK handle 0x81000003 (RSA cipher and RSASSA signing scheme, with SHA256) | ||
| echo "secret data" > data_to_be_signed | ||
|
|
||
| # Preparing ticket file to pass for signing | ||
| eve_run tpm2_hash -Q -C e -t ticket.bin -g sha256 -o digest.bin data_to_be_signed | ||
|
|
||
| # Performing signing... | ||
| eve_run tpm2_sign -Q -c 0x81000003 -g sha256 -s rsassa -o data.out.sign -t ticket.bin -f plain data_to_be_signed | ||
|
|
||
| # Reading public key for using it in openssl | ||
| eve_run tpm2_readpublic -Q -c 0x81000003 -o ak.pub -f pem | ||
|
|
||
| # Verifying signature using openssl | ||
| openssl dgst -verify ak.pub -keyform pem -sha256 -signature data.out.sign data_to_be_signed | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,68 +1,43 @@ | ||
| # VTPM Server | ||
| # VTPM | ||
|
|
||
| VTPM (located in `pkg/vtpm`) is a server listening on port `8877` in EVE, exposing limited functionality of the TPM to the clients. VTPM allows clients to execute [tpm2-tools](https://github.com/tpm2-software/tpm2-tools) binaries from a list of [hardcoded options](https://github.com/lf-edge/eve/blob/883547fe7978550a30e4389aac24d562d1dae105/pkg/vtpm/src/server.cpp#L58). | ||
| *(if you're looking for old VTPM documents, please refer to [PTPM](docs/PTPM.md))* | ||
|
|
||
| ## Packet Structure | ||
| Virtual TPM container integrates SWTPM with QEMU, in order to emulate a full Virtual TPM 2.0 (1.2 not supported) for running VMs and bare-metal container. It creates a SWTPM instance per VM. The SWTPM instance is configured to use a Unix Domain Socket as a communication line, by passing the socket path to the QEMU virtual TPM configuration, QEMU automatically creates a virtual TPM device for the VM which is accessible like a normal TPM under `/dev/tpm*`. | ||
|
|
||
| VTPM server accepts `EveTPMRequest` commands and outputs `EveTPMResponse`. Both structures are defined in probuf format in a file located in `pkg/vtpm/proto/vtpm_api.proto`. | ||
| VTPM configures SWTPM to saves and loads TPM state on/from the `/persist/swtpm/tpm-state-[VM-UUID]`, so at the next VM boot all the TPM keys, TPM NVRAM data, etc. are present in the virtual TPM. | ||
|
|
||
| ## Communicating with VTPM | ||
| ## VTPM Security Guarantees | ||
|
|
||
| You can communicate with VTPM by consuming the probuf definitions in your own client or using external tools like `protoc` to generate raw protobuf commands to send over the network. | ||
| VTPM offers security guarantee against the following scenarios: | ||
|
|
||
| Another way is using `eve_run` client from [eve-tools](https://github.com/lf-edge/eve-tools). Using `eve_run` is easy because it already has a predefined command-file table and can map a command's required files to `EveTPMRequest`. To use this client, simply build it (or follow the [installation](https://github.com/lf-edge/eve-tools/blob/master/INSTALL.md) instructions if you prefer otherwise): | ||
| 1. Virtual TPM data confidentiality | ||
| 2. Virtual TPM uniqueness (cloning detection) | ||
|
|
||
| ```bash | ||
| sudo apt-get install -y libprotobuf-dev libprotoc-dev protobuf-compiler cmake g++ libssl-dev libcurl4-openssl-dev uuid-dev | ||
| cd ~ | ||
| git clone https://github.com/lf-edge/eve-tools.git | ||
| cd eve-tools/eve-tools | ||
| make | ||
| ``` | ||
|
|
||
| To run `eve_run` without installation make sure the `libevetools.so` is accessible: | ||
|
|
||
| ```bash | ||
| LD_LIBRARY_PATH=~/eve-tools/eve-tools | ||
| export LD_LIBRARY_PATH | ||
| ``` | ||
|
|
||
| ### Commands | ||
| The first scenario is guaranteed by state encryption. SWTPM is configured to encrypt each VM/Container's virtual TPM state data using a 256-bit AES key, this key is stored in the HWTPM with a PCR policy and is only accessible to EVE. The access to this key is protected using the same PCR policy as the vault key (measured boot using PCR values), as result any tampering with EVE such as cloning or a persistent backdoor will result in unavailability of the VTPM encryption key. In case of tampering with the system, VTPM will not be made available to VM/Container, and VM/Container should consider such case as evidence of tampering with EVE. | ||
|
|
||
| Currently execution of the following commands are allowed: | ||
| | No |Command | | ||
| |--|--| | ||
| | 1 |tpm2_getcap | | ||
| | 2 |tpm2_readpublic | | ||
| | 3 |tpm2_startauthsession | | ||
| | 4 |tpm2_policysecret | | ||
| | 5 |tpm2_activatecredential | | ||
| | 6 |tpm2_flushcontext | | ||
| | 7 |tpm2_startauthsession | | ||
| | 8 |tpm2_policysecret | | ||
| | 9 |tpm2_import | | ||
| | 10 |tpm2_flushcontext | | ||
| | 11 |tpm2_load | | ||
| | 12 |tpm2_hmac | | ||
| | 13 |tpm2_hash | | ||
| | 14 |tpm2_sign | | ||
| | 15 |tpm2_verifysignature | | ||
| The second guarantee is secured by signing the VTPM's Endorsement Key (EK) using a signing key (HWTPM AIK) that is stored in HWTPM. EVE utilizes TPM to lay out a process that is true to our zero-trust promises and allows a remote party to establish trust in AIK and prove its security attributes (for example AIK resides inside HWTPM and is not import/exportable). This is how the chain of trust if established: | ||
|
|
||
| To get the details about each command, please consult the related [documentation](https://github.com/tpm2-software/tpm2-tools/tree/master/man). As an example, signing a message using TPM through `eve_run` goes as follows: | ||
| 1- HWTPM's Endorsement Key is a special purpose TPM-resident RSA key that is never visible outside the TPM. EK can be used for **decryption only** (EK cannot be used to produce a digital signature). EK is generated base on a **unique per TPM** seed, so it is deterministic and it's creation results in same key every single time (even after TPM is cleared). Trust in EK is established using a certificate issue by the OEM, either through a EK certificate or a Platform | ||
| certificates [ADD REF, TPM 2.0 SPEC]. EVE is TPM-OEM agnostic and it can only provide the VM/Containers with the HWTPM EK, verifying and trusting it is outside of scope of EVE and should be done by the attestor (VM/Container running on EVE or ideally a remote trusted server that wants to verify the SWTPM security guarantees). | ||
|
|
||
| ```bash | ||
| #Using well-known AIK handle 0x81000003 (RSA cipher and RSASSA signing scheme, with SHA256) | ||
| echo "secret data" > data_to_be_signed | ||
| 2- EVE generates a Attestation Identity Key (AIK) inside the HWTPM. AIK is a signing key and it is used to sign the VTPM's EK. This signature and subsequent attestation process (described below) proofs that the VTPM is running on a TPM with a specific HWTPM EK and running a cloned VTPM on a another TPM detectable. AIK comes with security attributes like FixedTPM, FixedParent and SensitiveDataOrigin (meaning the key is generated on the TPM and duplication/exporting/importing it is not possible). Attestor can make sure these values hold before trusting the AIK and verifying the VTPM's EK signature. This is done by first making sure that calculated AIK public blob's digest matches the provided digest and second the attributes hold by decoding and examining the AIK public blob. | ||
|
|
||
| # Preparing ticket file to pass for signing | ||
| eve_run tpm2_hash -Q -C e -t ticket.bin -g sha256 -o digest.bin data_to_be_signed | ||
| 3- The attestor uses the AIK's public blob digest (AKA name which contains the security attributes as mentioned above) and HTWPM EK to encrypt a credential (AKA nonce). Creating the credential links the AIK to HWTPM EK. This is done by generating a seed, encrypting it using HWTPM EK and running the AIK's digest and the seed through a KDF to create an asymmetric key. The final asymmetric key is used to encrypt the credential. Please note that this operation doesn't require a TPM, so it can happen on a trusted remote server with no TPM. | ||
|
|
||
| # Performing signing... | ||
| eve_run tpm2_sign -Q -c 0x81000003 -g sha256 -s rsassa -o data.out.sign -t ticket.bin -f plain data_to_be_signed | ||
| 4- At the final stage, the credential is passed to EVE. EVE uses HWTPM to decrypt the credentials. Per TCG TPM 2.0 specifications, this operation only succeeds if HWTPM has the private part of the matching EK and contains an AIK with matching attributes inside. After successfully decrypting the credentials, the plain text is passed to the attestor as a proof. If this operation fails, the attestor should not trust the VTPM and should halt any operation that relies on a TPM. | ||
|
|
||
| # Reading public key for using it in openssl | ||
| eve_run tpm2_readpublic -Q -c 0x81000003 -o ak.pub -f pem | ||
| ```mermaid | ||
| sequenceDiagram | ||
| EVE ->> Attestor: HWTPM EK Pub, HWTPM AIK Pub, HTWPM AIK Name | ||
| Attestor -->> Attestor: Verify HWTPM AIK security attributes | ||
| Attestor -->> Attestor: Make credentials : MC(HWTPM EK Pub, HWTPM AIK Name, Random nonce) | ||
| Attestor ->> EVE: Encrypted credential | ||
| EVE -->> EVE: Decrypt the cred using HWTPM EK and AIK : TpmDec(EK, AIK, cred) | ||
| EVE ->> Attestor: Decrypted credential | ||
| Attestor ->> EVE: Ask for VTPM EK Sig, if Random nonce == Decrypted credential | ||
| EVE ->> Attestor: Sig(HWTPM AIK Pub, VTPM EK Pub) | ||
| Attestor->> VM running on EVE: Trust VTPM, if Sig is valid | ||
|
|
||
| # Verifying signature using openssl | ||
| openssl dgst -verify ak.pub -keyform pem -sha256 -signature data.out.sign data_to_be_signed | ||
| ``` | ||
|
|
||
| For a working example of this operation, please check `/pkg/vtpm/vtpm-attest/`. Please note that if a hardware TPM is not available to EVE, these security guarantees are nulled and the virtual TPM state is stored unencrypted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Copyright (c) 2023 Zededa, Inc. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| #include <tunables/global> | ||
|
|
||
| @{exec_path} = /usr/bin/ptpm | ||
| profile ptpm @{exec_path} { | ||
| #include <abstractions/base> | ||
|
|
||
| # allow necessary access for operations | ||
| /home/{,*,**} rw, | ||
| /usr/bin/tpm2 rPx, | ||
| network inet stream, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Copyright (c) 2024 Zededa, Inc. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| #include <tunables/global> | ||
|
|
||
| @{exec_path} = /usr/bin/swtpm | ||
| profile swtpm @{exec_path} { | ||
| #include <abstractions/base> | ||
|
|
||
| # allow necessary access for operations | ||
| /usr/bin/swtpm rm, | ||
|
|
||
| # to rw socket, log, etc files. | ||
| owner /run/swtpm/{,*,**} rwk, | ||
|
|
||
| # to save/load tpm state for vms. | ||
| owner /persist/swtpm/{,*,**} rwk, | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,26 @@ | ||
| # Copyright (c) 2023 Zededa, Inc. | ||
| # Copyright (c) 2024 Zededa, Inc. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| #include <tunables/global> | ||
|
|
||
| @{exec_path} = /usr/bin/vtpm_server | ||
| @{exec_path} = /usr/bin/vtpm | ||
| profile vtpm @{exec_path} { | ||
| #include <abstractions/base> | ||
|
|
||
| # allow necessary access for operations | ||
| /jail/{,*,**} rw, | ||
| /usr/bin/tpm2 rPx, | ||
| network inet stream, | ||
| owner /usr/bin/vtpm rm, | ||
| owner /home/{,*,**} rw, | ||
|
|
||
| # writes temporary tpm-state encryption key here. | ||
| owner /run/swtpm/{,*,**} rw, | ||
|
|
||
| # crates the per-vm tpm-state dir here. | ||
| owner /persist/swtpm/{,*,**} rw, | ||
|
|
||
| # access to host tpm to unseal the encryption key. | ||
| /dev/tpm0 rw, | ||
| /dev/tpmrm0 rw, | ||
|
|
||
| # allow executing swtpm | ||
| /usr/bin/swtpm Px, | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.