diff --git a/Attestation/README.md b/Attestation/README.md index 6937b2f..4a4d08b 100644 --- a/Attestation/README.md +++ b/Attestation/README.md @@ -64,6 +64,26 @@ Attestation is done by a client computer with a TPM interacting with an attestation service over a network. This requires a network protocol for attestation. +## Intended Audience + +Readers should have read the [TPM introduction tutorial](/Intro/README.md). + +## Enrollment + +[Enrollment](/Enrollment/README.md) is the process and protocol for +onboarding devices into a network / organization. For example, adding +an IoT to a home network, a server to a data center, a smartphone or +tablet or laptop to a persons set of personal devices, etc. + +Generally attestation protocols apply to enrolled devices. Enrollment +protocols _may_ be very similar to attestation protocols, or even +actually be sub-protocols of attestation protocols. Enrollment +protocols can also be separate from attestation altogether. + +This tutorial mostly covers only attestation of/by enrolled devices. +For more about enrollment see the tutorial specifically for +[enrollment](/Enrollment/README.md). + ## Notation - `Encrypt_` == encryption with the named private or secret key @@ -78,6 +98,70 @@ for attestation. - `{"key":,...}` == JSON text - `TPM2_MakeCredential()` == outputs of calling `TPM2_MakeCredential()` with `args` arguments - `TPM2_Certify()` == outputs of calling `TPM2_Certify()` with `args` arguments + - `XK` == `` key, for some `` purpose (the TPM-resident object and its private key) + - `EK` == endorsement key (the TPM-resident object and its private key) + - `AK` == attestation key (the TPM-resident object and its private key) + - `TK` == transport key (the TPM-resident object and its private key) + - `XKpub` == ``'s public key, for some `` purpose + - `EKpub` == endorsement public key + - `AKpub` == attestation public key + - `TKpub` == transport public key + - `XKname` == ``'s cryptographic name, for some `` purpose + - `EKname` == endorsement key's cryptographic name + - `AKname` == attestation key's cryptographic name + +## Threat Models + +Some threats that an attestation protocol and implementation may want to +address: + + - attestation client impersonation + - attestation server impersonation + - unauthorized firmware and/or OS updates + - theft or compromise of of attestation servers + - theft of client devices or their local storage (e.g., disks, JBODs) + - theft of client devices by adversaries capable of decapping and + reading the client's TPM's NVRAM + +The attestation protocols we discuss will provide at least partial +protection against impersonation of attestation clients: once a TPM's +EKpub/EKcert are bound to the device in the attestation server's +database, that TPM can only be used for that device and no others. + +All the attestation protocols we discuss will provide protection against +unauthorized firmware and/or OS updates via attestation of root of trust +measurements (RTM). + +The attestation protocols we discuss will provide protection against +impersonation of attestation servers without necessarily authenticating +the servers to the clients in traditional ways (e.g., using TLS server +certificates). The role of the attestation server will be to deliver to +clients secrets and credentials they need that can only be correct and +legitimate if the server is authentic. As well, an attestation server +may unlock network access for a client, something only an authentic +server could do. + +We will show how an attestation server can avoid storing any cleartext +secrets. + +Theft of _running_ client devices cannot be fully protected against by +an attestation protocol. The client must detect being taken from its +normal environment and shutdown in such a way that no secrets are left +in cleartext on any of its devices. Frequent attestations might be used +to detect theft of a client, but other keepalive signalling options are +possible. + +Theft of non-running client devices can be protected against by having +the client shutdown in such a way that no secrets are left in cleartext +on any of its devices. Such client devices may be configured to need +the help of an attestation server to recover the secrets it needs for +normal operation. + +Full protection against decapping of TPM chips is not possible, but +protection against off-line use of secrets stolen from TPM chips is +possible by requiring that the client be on-line and attest in order to +obtain secrets that it needs to operate. This allows for revocation of +stolen clients, which would result in attestation protocol failures. ## Proof of Possession of TPM @@ -95,10 +179,10 @@ key) encrypted to the EKpub and then the attestation client demonstrate that it was able to decrypt that with the EK. However, this is not _quite_ how attestation protocols work! Instead of plain asymmetric encryption the server will use -[`TPM2_MakeCredential()`](TPM2_MakeCredential.md), while the attestation -client will use -[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) instead of -plain asymmetric decryption. +[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md), while +the attestation client will use +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) +instead of plain asymmetric decryption. ## Trusted State Attestation @@ -114,15 +198,15 @@ Typically the attestation protocol will have the client generate a signing-only asymmetric public key pair known as the attestation key (AK) with which to sign the PCR quote and eventlog. Binding of the EKpub and AKpub will happen via -[`TPM2_MakeCredential()`](TPM2_MakeCredential.md) / -[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md). +[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) / +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md). -Note that the [`TPM2_Quote()`](TPM2_Quote.md) function produces a signed +Note that the [`TPM2_Quote()`](/TPM-Commands/TPM2_Quote.md) function produces a signed message -- signed with a TPM-resident AK named by the caller (and to which they have access), which would be the AK used in the attestation protocol. -The output of [`TPM2_Quote()`](TPM2_Quote.md) might be the only part of +The output of [`TPM2_Quote()`](/TPM-Commands/TPM2_Quote.md) might be the only part of a client's messages to the attestation service that include a signature made with the AK, but integrity protection of everything else can be implied (e.g., the eventlog and PCR values are used to reconstruct the @@ -140,14 +224,14 @@ digest of the selected PCRs. `TPM2_Quote()` signs all of: ## Binding of Other Keys to EKpub -The semantics of [`TPM2_MakeCredential()`](TPM2_MakeCredential.md) / -[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) make it +The semantics of [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) / +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) make it possible to bind a TPM-resident object to the TPM's EKpub. -[`TPM2_MakeCredential()`](TPM2_MakeCredential.md) encrypts to the EKpub +[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) encrypts to the EKpub a small secret datum and the name (digest of public part) of the TPM-resident object being bound. The counter-part to this, -[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md), will decrypt +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md), will decrypt that and return the secret to the application IFF (if and only if) the caller has access to the named object. @@ -195,14 +279,14 @@ Let's start with few observations and security considerations: timestamps. - Replay protection of server to client responses is mostly either not - needed or implicitly provided by [`TPM2_MakeCredential()`](TMP2_MakeCredential.md) + needed or implicitly provided by [`TPM2_MakeCredential()`](TPM2_MakeCredential.md) because `TPM2_MakeCredential()` generates a secret seed that randomizes its outputs even when all the inputs are the same across multiple calls to it. - Ultimately the protocol *must* make use of - [`TPM2_MakeCredential()`](TMP2_MakeCredential.md) and - [`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) in order to + [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) and + [`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) in order to authenticate a TPM-running host via its TPM's EKpub. - Privacy protection of client identifiers may be needed, in which case @@ -288,7 +372,7 @@ protocol: ![Protocol Diagram](Protocol-Two-Messages.png) (In this diagram we show the use of a TPM simulator on the server side -for implementing [`TPM2_MakeCredential()`](TPM2_MakeCredential.md).) +for implementing [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md).) The server will validate that the `timestamp` is near the current time, the EKcert (if provided, else the EKpub), the signature using the @@ -314,7 +398,7 @@ is persisted both, in the client TPM and in the attestation service's database: ``` - + CS0: timestamp, AKpub, PCRs, eventlog, TPM2_Quote(AK, PCRs, extra_data)=Signed_AK({hash-of-PCRs, misc, extra_data}) @@ -340,7 +424,7 @@ desirable anyways for monitoring and alerting purposes. ![Protocol Diagram](Protocol-Three-Messages.png) (In this diagram we show the use of a TPM simulator on the server side -for implementing [`TPM2_MakeCredential()`](TPM2_MakeCredential.md).) +for implementing [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md).) NOTE well that in this protocol, like single round trip attestation protocols using only decrypt-only EKs, it is *essential* that the AKcert @@ -505,10 +589,6 @@ PCRs are desired, then this becomes a one round trip protocol. An AKcert will be added to the Safeboot protocol soon. -### Actual Protocols: ... - -(TBD) - ## Attestation Protocol Patterns and Actual Protocols (signing-only EKs) Some TPMs come provisioned with signing-only endorsement keys in @@ -609,8 +689,8 @@ A schema for the attestation server's database entries might look like: "previous_PCRs": "<...>", "proposed_PCRs": "<...>", "ak_cert_template": "", - "secrets": "", - "resetCount": "" + "resetCount": "", + "secrets": "" } ``` @@ -660,12 +740,28 @@ then an administrator would confirm that the client just did a firmware/OS upgrade and if so replace the `previous_PCRs` with the `proposed_PCRs`, then the client could attempt attestation again. -## Dealing with Secrets +# Delivery of Secrets to Attestation Clients -An attestation server might want to return storage/filesystem decryption -key-encryption-keys to a client. But one might not want to store those -keys in the clear on the attestation server. As well, one might want a -break-glass way to recover those secrets. +An attestation server might have to return storage/filesystem decryption +key-encryption-keys (KEKs) to a client. But one might not want to store +those keys in the clear on the attestation server. As well, one might +want a break-glass way to recover those secrets. + +Possible goals: + + - store secrets that clients need on the attestation server + - do not store plaintext or plaintext-equivalent secrets on the + attestation server + - allow for adding more secrets to send to the client after enrollment + - provide a break-glass recovery mechanism + +Note that in all cases the client does get direct access to various +secrets. Using a TPM to prevent direct software access to those secrets +would not be performant if, for example, those secrets are being used to +encrypt filesystems. We must inherently trust the client to keep those +secrets safe when running. + +## Break-Glass Recovery For break-glass recovery, the simplest thing to do is to store `Encrypt_backupKey({EKpub, hostname, secrets})`, where `backupKey` is an @@ -675,53 +771,299 @@ the ciphertext to the offline system where the private backup key is kept, decrypt it, and then use the secrets manually to recover the affected system. -Here are some ideas for how to make an attestation client depend on the -attestation server giving it keys needed to continue booting after -successful attestation: +## Secret Transport Sub-Protocols - - Store `TPM2_MakeCredential(EKpub, someObjectName, key0), Encrypt_key0(secrets)`. +Here we describe several possible sub-protocols of attestation protocols +for secret transport. This list is almost certainly not exhaustive. - In this mode the server sends the client the stored data, then client - gets to recreate `someObject` (possibly by loading a saved object or - by re-creating it on the same non-NULL hierarchy from the same - primary seed using the same template and extra entropy) on its TPM so - that the corresponding call to `TPM2_ActivateCredential()` can - succeed, then the client recovers `key0` and decrypts the encrypted - secrets. Here `someObject` can be trivial and need only exist to - make the `{Make,Activate}Credential` machinery work. +### Store a `TPM2_MakeCredential()` Payload - TPM replacement and/or migration of a host from one physical system - to another can be implemented by learning the new system's TPM's - EKpub and using the offline `backupKey` to compute - `TPM2_MakeCredential(EKpub_new, someObjectName, key0)` and update the - host's entry. +[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) and +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) +are a form of limited asymmetric encryption (`TPM2_MakeCredential()`) +and asymmetric decryption (`TPM2_ActivateCredential()`) subject to the +sender's choice of authorization. The details are explained +[here](/TPM-Commands/TPM2_MakeCredential.md) and +[here](/TPM-Commands/TPM2_ActivateCredential.md). Basically, there are +two TPM key objects involved: - - Alternatively generate a non-restricted decryption private key using - a set template and extra entropy, on the same non-NULL hierarchy - (i.e., from the same seed), enroll the public key to this private key - in an attestation protocol, and have the attestation server store - secrets encrypted to that public key. + - a transport key (typically the `EK`), + - and an authorization key (typically an `AK`) - (The EK cannot be used this way because it is restricted.) +and the caller of `TPM2_MakeCredential()` must specify the public part +of the transport key and the +[name](/Intro/README.md#Cryptographic-Object-Naming) of the +authorization key, along with a small secret to transport. The caller +of `TPM2_ActivateCredential()` must then provide the handles for those +two key objects and the outputs of `TPM2_MakeCredential()` in order to +extract the small secret. Typically the small secret is an AES key for +encrypting larger secrets. - - Store a secret value that will be extended into an application PCR - that is used as a policy PCR for unsealing a persistent object stored - on the client's TPM. +So if we can store the outputs of `TPM2_MakeCredential()` long-term so +that the client can activate over multiple reboots, then we have a way +to deliver secrets to the client. - In this mode the server sends the client the secret PCR extension - value, and the client uses it to extend a PCR such that it can then - unseal the real storage / filesystem decryption keys. +We'll discuss two ways to do this: - Using a PCR and a policy on the key object allows for a clever - break-glass secret recovery mechanism by using a compound extended - authorization (EA) policy that allows either unsealing based on a - PCR, or maybe based on an password-based HMAC (with machine passwords - stored in a safe). + - use a `WK` -- a universally well-known key (thus WK, for well-known) - - A hybrid of the previous options, where the server stores a secret - PCR extension value wrapped with `TPM2_MakeCredential()`. + Since the `WK`'s private area is not used for any cryptography in + `TPM2_MakeCredential()`/`TPM2_ActivateCredential()`, it can be a key + that everyone knows. -Other ideas? + Note that the `WK`'s public area can name arbitrary an auth policy, + and `TPM2_MakeCredential()` will enforce it. + + E.g., the `WK` could be the all-zeros AES key. Its policy could be + whatever is appropriate for the organization. For example, the + policy could require that some non-resettable application PCR have + the value zero so that extending it can disable use of + `TPM2_MakeCredential()` post-boot. + + - use an `LTAK` -- a long-term `AK` + + I.e., an `AK` that lacks the `stClear` attribute, and _preferably_ + created deterministically with either + [`TPM2_CreateLoaded()`](/TPM-Commands/TPM2_CreateLoaded.md) or + [`TPM2_CreatePrimary()`](/TPM-Commands/TPM2_CreatePrimary.md). + + > Note that the `LTAK` need not be a primary. + + > If the `LTAK` were created with + > [`TPM2_Create()`](/TPM-Commands/TPM2_Create.md) then the key's saved + > context file would have to be stored somewhere so that it could be + > loaded again on next boot with + > [`TPM2_Load()`](/TPM-Commands/TPM2_Load.md). Whereas creating it + > deterministically means that it can be re-created every time it's + > needed using the same hiercarchy, template, and entropy as + > arguments to `TPM2_CreatePrimary()` or `TPM2_CreateLoaded()` + + Note that the `AK`'s public area can name arbitrary an auth policy, + and `TPM2_MakeCredential()` will enforce it. + +The best option here is to use a `WK` because using an `LTAK` would +require recording its public key in the device's enrolled attestation +state, which would complicate enrollment, whereas the `WK`, being +well-known and the same for all cases, would not need to be recorded in +server-side attestation state. + +> One might like to use the `EK` as the `activateHandle`. Sadly, this +> is not possible. +> While `TPM2_MakeCredential(EKpub, EKname, input)` works, +> `TPM2_ActivateCredential(EK, EK, credentialBlob, secret)` does not +> and cannot. +> +> The reason for this is that `TPM2_ActivateCredential()` requires +> `ADMIN` role for the `activateHandle`, and since the `EK` has +> `adminWithPolicy` attribute set and its policy doesn't have the +> `TPM_CC_ACTIVATECREDENTIAL` command permitted, the call must fail. +> +> Credit for the `WK` idea goes to [Erik > Larsson](https://developers.tpm.dev/chats/new?user_id=4336638). + +Normally during attestation we want to use an `AK` with `stClear` set so +that each boot forces the client to use a new one. However, for sending +secrets to the client via `TPM2_MakeCredential()` / +`TPM2_ActivateCredential()` we really need need the `activateHandle` +object to not have `stClear` set. + +For this approach then, the best solution is to use a `WK`. + +``` + CS0: timestamp, AKpub, PCRs, eventlog, + TPM2_Quote(AK, PCRs, extra_data)=Signed_AK({hash-of-PCRs, misc, extra_data}) + SC0: {TPM2_MakeCredential(EKpub, AKname, session_key), + Encrypt_session_key(long_term_Credential)} + + where + + long_term_Credential = TPM2_MakeCredential(EKpub, WKname, secrets) +``` + +New secrets can be added at any time without interaction with the +client if the attestation server recalls the `LTAKname`. + +The schema for storing secrets transported this way would be: + +```JSON +{ + "EKpub": "", + "hostname": "", + "EKcert": "", + "previous_firmware_profile": "FWProfile0", + "current_firmware_profiles": ["FWProfile1", "FWProfile2", "..."], + "previous_operating_system_profiles": "OSProfile0", + "current_operating_system_profiles": ["OSProfile1", "OSProfile2", "..."], + "previous_PCRs": "<...>", + "proposed_PCRs": "<...>", + "resetCount": "", + + "secret store and transport fields":"vvvvvvvvvvvvvvvvvv", + + "secrets": ["", "", "..", ""] + "secrets_backup": ["", + "hostname": "", + "EKcert": "", + "previous_firmware_profile": "FWProfile0", + "current_firmware_profiles": ["FWProfile1", "FWProfile2", "..."], + "previous_operating_system_profiles": "OSProfile0", + "current_operating_system_profiles": ["OSProfile1", "OSProfile2", "..."], + "previous_PCRs": "<...>", + "proposed_PCRs": "<...>", + "ak_cert_template": "", + "resetCount": "", + + "secret store and transport fields":"vvvvvvvvvvvvvvvvvv", + + "TKpub": "", + "secrets": ["", "", "..", ""] + "secrets_backup": ["", + "hostname": "", + "EKcert": "", + "previous_firmware_profile": "FWProfile0", + "current_firmware_profiles": ["FWProfile1", "FWProfile2", "..."], + "previous_operating_system_profiles": "OSProfile0", + "current_operating_system_profiles": ["OSProfile1", "OSProfile2", "..."], + "previous_PCRs": "<...>", + "proposed_PCRs": "<...>", + "ak_cert_template": "", + "resetCount": "", + + "secret store and transport fields":"vvvvvvvvvvvvvvvvvv", + + "TKdup": "", + "TKpub": "", + "secrets": ["", "", "..", ""] + "secrets_backup": ["", + "hostname": "", + "EKcert": "", + "previous_firmware_profile": "FWProfile0", + "current_firmware_profiles": ["FWProfile1", "FWProfile2", "..."], + "previous_operating_system_profiles": "OSProfile0", + "current_operating_system_profiles": ["OSProfile1", "OSProfile2", "..."], + "previous_PCRs": "<...>", + "proposed_PCRs": "<...>", + "ak_cert_template": "", + "resetCount": "", + + "secret store and transport fields":"vvvvvvvvvvvvvvvvvv", + + "unseal_key": "", + "secrets_backup": ["", + "hostname": "", + "EKcert": "", + "previous_firmware_profile": "FWProfile0", + "current_firmware_profiles": ["FWProfile1", "FWProfile2", "..."], + "previous_operating_system_profiles": "OSProfile0", + "current_operating_system_profiles": ["OSProfile1", "OSProfile2", "..."], + "previous_PCRs": "<...>", + "proposed_PCRs": "<...>", + "ak_cert_template": "", + "resetCount": "", + + "secret store and transport fields":"vvvvvvvvvvvvvvvvvv", + + "secrets": ["", "", ""] +} +``` + +# Security Considerations + +TBD # References diff --git a/Attestation/TPM2_ActivateCredential.md b/Attestation/TPM2_ActivateCredential.md deleted file mode 100644 index 6f4251d..0000000 --- a/Attestation/TPM2_ActivateCredential.md +++ /dev/null @@ -1,31 +0,0 @@ -# `TPM2_ActivateCredential()` - -`TPM2_ActivateCredential()` decrypts a ciphertext made by -[`TPM2_MakeCredential()`](TPM2_MakeCredential.md) and checks that the -caller has access to the object named by the caller of -[`TPM2_MakeCredential()`](TPM2_MakeCredential.md), and if so then -`TPM2_ActivateCredential()` outputs the small secret provided by the -caller of [`TPM2_MakeCredential()`](TPM2_MakeCredential.md), -otherwise `TPM2_ActivateCredential()` fails. - -Together with [`TPM2_MakeCredential()`](TPM2_MakeCredential.md), -this function can be used to implement attestation protocols. - -## Inputs - - - `TPMI_DH_OBJECT activateHandle` (e.g., handle for an AK) - - `TPMI_DH_OBJECT keyHandle` (e.g., handle for an EK corresponding to the EKpub encrypted to by `TPM2_MakeCredential()`) - - `TPM2B_ID_OBJECT credentialBlob` (output of `TPM2_MakeCredential()`) - - `TPM2B_ENCRYPTED_SECRET secret` (output of `TPM2_MakeCredential()`) - -## Outputs (success case) - - - `TPM2B_DIGEST certInfo` (not necessarily a digest, but a small [digest-sized] secret that was input to `TPM2_MakeCredential()`) - -## References - - - [TCG TPM Library part 1: Architecture, section 24](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf) - - [TCG TPM Library part 2: Structures](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf) - - [TCG TPM Library part 3: Commands, section 12](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) - - [TCG TPM Library part 3: Commands Code, section 12](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_code_pub.pdf) - diff --git a/Attestation/TPM2_MakeCredential.md b/Attestation/TPM2_MakeCredential.md deleted file mode 100644 index d279e29..0000000 --- a/Attestation/TPM2_MakeCredential.md +++ /dev/null @@ -1,31 +0,0 @@ -# `TPM2_MakeCredential()` - -`TPM2_MakeCredential()` takes an EKpub, the name of an object in a TPM -identified by that EKpub, and a small secret, and it encrypts `{name, -secret}` to the EKpub. - -Nothing terribly interesting happens here. All the interesting -semantics are on the -[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) side. - -Together with [`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md), -this function can be used to implement attestation protocols. - -## Inputs - - - `TPMI_DH_OBJECT handle` (e.g., an EKpub to encrypt to) - - `TPM2B_DIGEST credential` (not necessarily a digest, but a small [digest-sized] secret) - - `TPM2B_NAME objectName` (name of object resident on the same TPM as `handle` that `TPM2_ActivateCredential()` will check) - -## Outputs - - - `TPM2B_ID_OBJECT credentialBlob` (ciphertext of encryption of `credential` with a secret "seed" [see below]) - - `TPM2B_ENCRYPTED_SECRET secret` (ciphertext of encryption of a "seed" to `handle`) - -## References - - - [TCG TPM Library part 1: Architecture, section 24](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf) - - [TCG TPM Library part 2: Structures](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf) - - [TCG TPM Library part 3: Commands, section 13](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) - - [TCG TPM Library part 3: Commands Code, section 13](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_code_pub.pdf) - diff --git a/Enrollment/README.md b/Enrollment/README.md new file mode 100644 index 0000000..76a0027 --- /dev/null +++ b/Enrollment/README.md @@ -0,0 +1,139 @@ +# Device Enrollment + +Device Enrollment is the act of registering a device -anything from an +IoT to a server- and creating the state that will be referenced in +future [attestations](/Attestation/README.md) from that device. + +This can be as simple as sending the device's endorsement key +certificate (EKcert) to a registration server (possibly authenticating +to that server using some administrator user's credentials), to a more +complex protocol similar to [attestation](/Attestation/README.md). + +## Online Enrollment + +Online enrollment means that the device to be enrolled interacts with an +enrollment service over a network. + +## Off-line Enrollment + +Off-line enrollment means that the device to be enrolled *does not* +interact with an enrollment service. + +For example, one might scan an endorsement key (EK) public key or +certificate from a QR code on a shipment manifest and then enroll the +device using only that information. + +# Server-Side State to Create during Enrollment + + - device name <-> EKpub binding + - enrolling user/admin + - that the device has a valid TPM (i.e., the EKcert validates to a + trusted TPM vendor's trust anchor) + - initial root of trust measurement (RTM) + - backup, secret recovery keys + - encrypted secrets to send to the device + +# Client-side State to Create during Enrollment + + - encrypted filesystems? + - device credentials? (e.g., TLS server certificates, Kerberos keys ["keytabs"], etc.) + +# Secrets Transport + +Every time an enrolled device reboots, or possibly more often, it may +have to connect to an attestation server to obtain secrets from it that +the device needs in order to proceed. For example, filesystem +decryption keys, general network access, device authentication +credentials, etc. + +See [attestation](/Attestation/README.md) for details of how to +transport secrets onto an enrolled device post-enrollment. + +# Enrollment Semantics + + - online vs. off-line + + - client device trust semantics: + - bind device name and EKpub on first use ("BOFU")? + - enroll into inventory and then allow authorized users to bind a + device name to an EKpub on a first-come-first-served basis? + + - enrollment server trust semantics: + - trust on first use (TOFU) (i.e., trust the first enrollment server + found) + - pre-install a trust anchor on the client device + - use a user/admin credential on the device to establish trust on + the server (e.g., intrinsically to how user authentication works, + or having the user review and approve the server's credentials) + +# Threat Models + +Threats: + + - enrollment server impersonation + - enrollment of rogue devices + - eavesdroppers + - DoS + +A typical enrollment protocol for servers in datacenters may well not +bother protecting against all of the above. + +A typical enrollment protocol for IoTs in a home network also may well +not bother protecting against any of the above. + +Enrollment protocols for personal devices must protect against all the +listed threats except DoS attacks. + +# Enrollment Protocols + +## Trivial Enrollment Protocols + +The simplest enrollment protocols just have the client device send its +EKcert to the enrollment server. The enrollment server may have a user +associate enrolled devices with device IDs (e.g., hostnames), and the +device's enrollment is complete. + +## Enrollment Protocols with Proof of Possession and Attestation + +A more complex enrollment protocol would have the device attest to +possession of the EK whose EKpub is certified by its EKcert, and might +as well also perform attestation of other things, such as RTM. + +An enrollment protocol with proof of possession might look a lot like +the [two round trip attestation +protocol](/Attestation/README.md#two-round-trip-stateless-attestation-protocol-patterns), +with the addition of `enrollment_data` in the last message from the +client to the server (server authentication not shown): + +``` + CS0: [ID], EKpub, [EKcert], AKpub, PCRs, eventlog, timestamp, + TPM2_Quote(AK, PCRs, extra_data)=Signed_AK({hash-of-PCRs, misc, extra_data}) + SC0: {TPM2_MakeCredential(EKpub, AKpub, session_key), ticket} + CS1: {ticket, MAC_session_key(CS0), CS0, Encrypt_session_key(enrollment_data)} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + (new) + SC1: Encrypt_session_key({AKcert, filesystem_keys, etc.}) + + +``` + +where + +``` + enrollment_data = { Encrypt_TK(secrets), [TKpub], [HK_pub] } + + secrets = any secrets generated on the client side + TKpub = public part of transport key for encrypting secrets to the + client + HKpub = public part of a host key for host authentication +``` + +## Enrollment Protocols for Personal Devices + +Enrollment of personal devices in their owners' personal device groups +can be a lot like Bluetooth device pairing. Where such devices have +TPMs then perhaps there is a role for the TPM to play in enrollment. + +# Security Considerations + +TBD diff --git a/Intro/README.md b/Intro/README.md index d3efdd0..9469107 100644 --- a/Intro/README.md +++ b/Intro/README.md @@ -48,6 +48,39 @@ general, which include: > software development using TPMs will want to make use of [TCG > specifications and other resources](#Other-Resources). +## Use Cases + +Here are _some_ use cases that TPMs can be applied to + + - off-line root of trust measurement (RTM) to check that a device is + healthy + + ("off-line" meaning "no network needed") + + - encrypted storage + + - online RTM to check that a device is healthy and authorize it to have + access to a network + + ("online" meaning "demonstrate health via networked interaction with + other devices") + + - encrypted storage + + - hardware security module (HSM) + + - certification authority (CA) + - TPMs as smartcards + + - authentication and authorization of console and/or remote user logins + + - e.g., require biometrics, smartcard, admin credentials, multiple + users' authentication, time-of-day restrictions, etc. + + - entropy source (random number generator) + + - cryptographic co-processor + ## Glossary > For a glossary, see section 4 of [TCG TPM 2.0 Library part 1: @@ -291,16 +324,18 @@ necessarily yields a new name. > restricted keys. Still, it may be useful to illustrate cryptographic > object naming with one particularly important use of it. -A pair of functions, `TPM2_MakeCredential()` and -`TPM2_ActivateCredential()`, illustrate the use of cryptographic object -naming as a binding or a sort of authorization function. +A pair of functions, +[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) and +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md), +illustrate the use of cryptographic object naming as a binding or a sort +of authorization function. -`TPM2_MakeCredential()` can be used to encrypt a datum (a "credential") -to a target TPM such that the target will _only be willing to decrypt -it_ if *and only if* the application calling `TPM2_ActivateCredential()` -to decrypt that credential has access to some key named by the sender, -and that name is a cryptographic name that the sender can and must -compute for itself. +[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) can be +used to encrypt a datum (a "credential") to a target TPM such that the +target will _only be willing to decrypt it_ if *and only if* the +application calling `TPM2_ActivateCredential()` to decrypt that +credential has access to some key named by the sender, and that name is +a cryptographic name that the sender can and must compute for itself. The semantics of these two functions can be used to defeat a cut-and-paste attack in attestation protocols. @@ -312,21 +347,21 @@ keys, each with zero, one, or more children keys: ``` seed - | - | - v + /|\ + / | \ + v v v primary key (asymmetric encryption) - | - | - v + /|\ + / | \ + v v v secondary keys (of any kind) - | - | - v + /|\ + / | \ + v v v ... ``` -Note that every key has a parent or is a primary key. +Keys that have no parent are primary keys. There are four built-in hierarchies: @@ -346,10 +381,18 @@ used to authenticate the TPM's legitimacy. The EK's public key ("EKpub") can be used to uniquely identify a TPM, and possibly link to the platform's, and even the platform's user(s)' identities. -The `TPM2_CreatePrimary()` and `TPM2_CreateLoaded()` commands create key -objects deterministically from the hierarchy's seed and the "template" -used to create the key (which includes a "unique" area that provides -"entropy" to the key derivation function). +The [`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) command creates +primary key objects deterministically from the hierarchy's seed and the +"template" used to create the key (which includes a "unique" area that +provides "entropy" to the key derivation function). + +The [`TPM2_Create()`](TPM2_Create.md) command creates a ordinary +objects. + +The [`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md) command can also +create primary key objects deterministically from the hierarchy's seed +and the "template" used to create the key (which includes a "unique" +area that provides "entropy" to the key derivation function). ## Key Wrapping and Resource Management @@ -482,16 +525,36 @@ policy because the TPM knows only a digest of it. Construction of a policy consists of computing it by hash extending an initial all-zeroes value with the commands that make up the policy. +This can be done entirely in software, but the TPM supports a notion of +"trial sessions" where the application can issue policy commands to +build up a policy digest without the application having to know how to +do that in software. Trial sessions have every policy command succeed, +but they authorize nothing -- the point of a trial session is only to +compute and extract a `policyDigest` at the end of the policy. + ### Policy Evaluation Evaluation of a policy consists of issuing those same commands to the -TPM in a session, with those commands either evaluated immediately or -deferred to the time of execution of the to-be-authorized command, but -the TPM computes the same hash extension as it goes. Once all policy -commands being evaluated have succeeded, the resulting hash extension -value is compared to the policy that protects the resource(s) being used -by the to-be-authorized command, and if it matches, then the command is -allowed, otherwise it is not. +TPM in a [non-trial] session, with those commands either evaluated +either immediately or deferred to the time of execution of the +to-be-authorized command, but the TPM computes the same hash extension +as it goes. Once all policy commands issued have been evaluated and +have succeeded, the resulting hash extension value is compared to the +policy that protects the resource used by the to-be-authorized command, +and if and only if the digest matches, then the command is allowed, +otherwise it is not. + +For example, one might construct a policy like so: + +```bash +$ tpm2 flushcontext -t +$ tpm2 flushcontext -s +$ tpm2 startauthsession --session session.ctx --policy-session +$ tpm2 policysecret --session session.ctx --object-context endorsement +$ tpm2 policycommandcode -S session.ctx -L activate.ctx TPM2_CC_ActivateCredential +``` + +which saves the digest of the policy in a file named `activate.ctx`. ### Indirect Policies @@ -530,9 +593,108 @@ indexes, policies can be used to: ## Sessions A session is an object (meaning, among other things, that it can be -loaded and unloaded as needed) that represents the current policy -construction or evaluation hash extension digest (the `policyDigest`), -and the objects that have been granted access. +loaded and unloaded as needed) that represents the current state used +for authorization of actions or for encryption of traffic between the +application and the TPM. + +There are two types of sessions then: those used for authorization, and +those used for encryption of application `<->` TPM communication. + +Authorization sessions contain state such as a `policyDigest` +representing authorization policy that has been satisfied, and various +other state. TPM commands may check that an authorization session's +state satisfies the requirements for use of the argument objects passed +to the commands. + +### Authorization Session State + +Authorization sessions have a number of state attributes. Some of these +are set at the time of creation of the session. Some of these can be +set directly with `TPM2_Policy*()` commands. Others evolve in other +ways. These state attributes are: + + - `policyDigest` + + A hash extension digest of all the policy commands sent by the + application in this session thus far. Every successful + `TPM2_Policy*()` command extends this. + + Objects may have a policy digest set on them to refer to the policy + that an application must meet in order to use them. The application + has to issue the `TPM2_Policy*()` commands, in order, that produce + that digest, the commands must all succeed, and the `policyDigest` + must equal that of the object. + + - `isTrialPolicy` + + When this is set then the session will not authorize anything at all + and all policy commands will be assumed to be met and will not be + evaluated. This is useful for constructing and extracting from the + TPM the `policyDigest` of a policy to set on some future new + object(s). + + Sessions that have this set are known as "trial sessions". + + Applications can construct `policyDigest` values entirely in + software, but using the TPM with a trial session saves one the + bother. + + - `commandCode` + + Identifies a command that will be authorized by the policy referred + to by `policyDigest`. + + If a policy requires this, then it authorizes the one command + identified by the command code. + + - `cpHash` + + A hash of some command's parameters. If a policy requires this, then + it authorizes the one command whose parameters match this hash. + + - `commandLocality` + + A locality that the application must be in. + + - policy reuse / expiration state: + + - `startTime` + + The start time of the session. + + - `timeout` + + The lifetime of the session. + + - `nonceTPM` + + - Authentication requirements: + + - `isAuthValueNeeded` + + - `isPasswordNeeded` + + - `isPPRequired` + + PP == physical presence. + + - `checkNvWritten` + + - `nvWrittenState` + + - `nameHash` + + - `pcrUpdateCounter` + +### Encryption Sessions + +> Work in progress. + +Sessions can also be used for encrypting TPM command arguments and +results. This can be useful when one does not trust the path to the +TPM, such as when the TPM is remote. + +> TODO: Discuss key exchange options, etc. ## Restricted Cryptographic Keys @@ -540,21 +702,53 @@ Cryptographic keys can either be unrestricted or restricted. An unrestricted signing key can be used to sign arbitrary content. +An unrestricted decryption key can be used to decrypt arbitrary +ciphertexts encrypted to that key's public key. + +> NOTE WELL: The endorsement key (EK) is a restricted key. + +### Restricted Signing Keys + A restricted signing key can be used to sign only TPM-generated content as part of specific TPM restricted signing commands. Such content always begins with a magic byte sequence. Conversely, the TPM refuses to sign externally generated content that starts with that magic byte -sequence. +sequence. See the [`TPM2_Certify()`](/TPM-Commands/TPM2_Certify.md), +[`TPM2_Quote()`](/TPM-Commands/TPM2_Quote.md), `TPM2_CertifyCreation()`, +`TPM2_GetSessionAuditDigest()`, and `TPM2_GetCommandAuditDigest()` TPM +commands. + +There is also a notion of signing keys that can only be used to sign +PKIX certificates using `TPM2_CertifyX509()`. + +### Restricted Decryption Keys + +> NOTE WELL: The endorsement key (EK) is a restricted key. A restricted decryption key can only be used to decrypt ciphertexts whose plaintexts have a certain structure. In particular these are used -for `TPM2_MakeCredential()`/`TPM2_ActivateCredential()` to allow the -TPM-using application to get the plaintext if and only if (IFF) the -plaintext cryptographically names an object that the application has -access to. This is used to communicate secrets ("credentials") to TPMs. +for [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) / +[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) +to allow the TPM-using application to get the plaintext if and only if +(IFF) the plaintext cryptographically names an object that the +application has access to. This is used to remotely communicate secrets +("credentials") to TPMs. -There is also a notion of signing keys that can only be used to sign -PKIX certificates. +Another operation that a restricted decryption key can perform is +[`TPM2_Import()`](/TPM-Commands/TPM2_Import.md), which decrypts a key +wrapped to the given decrypt-only key and outputs a file that can be +loaded with [`TPM2_Load()`](/TPM-Commands/TPM2_Load.md). The wrapped +key payload given to [`TPM2_Import()`](/TPM-Commands/TPM2_Import.md) too +has a particular structure and is produced by a remote peer using +[`TPM2_Duplicate()`](/TPM-Commands/TPM2_Duplicate.md). + +To recap, a restricted decryption key can only be used to: + + - "activate credentials" (made with + [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md)) + + - receive wrapped keys sent by a peer (made with + [`TPM2_Duplicate()`](/TPM-Commands/TPM2_Duplicate.md)) ## Attestation @@ -577,19 +771,87 @@ many TPM concepts can be used to great effect: - authorization of devices onto a network - etc. +## Use Cases (reprise) + +### Off-line RTM / TOTP + +Use a TPM to generate a time-based one-time (TOTP) password based on +current time and a seed derived from selected PCR values, then display +this TOTP. A user can then check that the TOTP presented by the device +matches the TOTP on a separate authenticator. + +Links: + + - https://github.com/tpm2-software/tpm2-totp + - https://github.com/mjg59/tpmtotp + - https://trmm.net/Tpmtotp/ + +### Online RTM (aka Attestation) + +See [our tutorial on attestation](/Attestation/README.md). + +### Encrypted Storage + + - [Safeboot](https://safeboot.dev/) + - [Hacking with a TPM](https://c3media.vsos.ethz.ch/congress/2019/slides-pdf/36c3-10564-hacking_with_a_tpm.pdf) + +### HSM / CA / Smartcard + +Use `TPM2_Sign()` or `TPM2_CertifyX509()` to sign certificates with a +TPM-resident key that is fixedTPM and fixedParent. + +Use `TPM2_GetCommandAuditDigest()` to implement an audit trail for the +CA. + +### Authentication and Authorization of Console and/or Remote User Logins + +Use [TPM policies](#Authentication-and-Authorization). + +### Entropy Source + +See our tutorial on [TPM-based RNGs](/Random_Number_Generator/README.md). + +### Cryptographic Co-Processor + +Use cryptographic primitives provided by the TPM using unrestricted key +objects: + + - use TPM cryptographic primitives commands directly -- see + [TCG TPM 2.0 Library part 3: Commands, sections 14 and 15](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + + - use PKCS#11 with a TPM-backed token provider: + - https://github.com/tpm2-software/tpm2-pkcs11 + - https://docs.oracle.com/cd/E36784_01/html/E37121/gmsch.html + - https://incenp.org/notes/2020/tpm-based-ssh-key.html + - http://trousers.sourceforge.net/pkcs11.html + - https://www.lorier.net/docs/tpm + + - use OpenSSL with a PKCS#11 `ENGINE` (see above) + + - use OpenSSL with a TPM `ENGINE` + - https://github.com/tpm2-software/tpm2-tss-engine + # Other Resources -[A Practical Guide to TPM 2.0](https://trustedcomputinggroup.org/resource/a-practical-guide-to-tpm-2-0/) -is an excellent book that informed much of this tutorial. + - [A Practical Guide to TPM 2.0](https://trustedcomputinggroup.org/resource/a-practical-guide-to-tpm-2-0/) + is an excellent book that informed much of this tutorial. -Nokia has a [TPM course](https://github.com/nokia/TPMCourse/tree/master/docs). + - Of course, there is the [TPM.dev community](https://developers.tpm.dev/), + which has many resources, posts, a chat room, and knowledgeable + participants. -The TCG has a number of members-only tutorials, but it seems that it is -possible to be invited to be a non-fee paying member. + - Nokia has a [TPM course](https://github.com/nokia/TPMCourse/tree/master/docs). -Core TCG TPM specs: + - [Hacking with a TPM](https://c3media.vsos.ethz.ch/congress/2019/slides-pdf/36c3-10564-hacking_with_a_tpm.pdf). - - [TCG TPM 2.0 Library part 1: Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf). - - [TCG TPM 2.0 Library part 2: Structures](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf). - - [TCG TPM 2.0 Library part 3: Commands, section 12](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf). - - [TCG TPM 2.0 Library part 3: Commands Code, section 12](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_code_pub.pdf). + - [Microsoft has solid TPM resources](https://docs.microsoft.com/en-us/windows/security/information-protection/tpm/trusted-platform-module-top-node). + + - The TCG has a number of members-only tutorials, but it seems that it + is possible to be invited to be a non-fee paying member. + + - Core TCG TPM specs: + + - [TCG TPM 2.0 Library part 1: Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf). + - [TCG TPM 2.0 Library part 2: Structures](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf). + - [TCG TPM 2.0 Library part 3: Commands](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf). + - [TCG TPM 2.0 Library part 3: Commands Code](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_code_pub.pdf). diff --git a/TPM-Commands/TPM2_ActivateCredential.md b/TPM-Commands/TPM2_ActivateCredential.md new file mode 100644 index 0000000..3704fed --- /dev/null +++ b/TPM-Commands/TPM2_ActivateCredential.md @@ -0,0 +1,76 @@ +# `TPM2_ActivateCredential()` + +`TPM2_ActivateCredential()` is the flip side to +[`TPM2_MakeCredential()`](TPM2_MakeCredential.md), decrypting a small +ciphertext made by [`TPM2_MakeCredential()`](TPM2_MakeCredential.md). + +The intersting things about `TPM2_ActivateCredential()` are that + + - the decryption key used may be a restricted key (which + `TPM2_RSA_Decrypt()` would refuse to use) + - and that `TPM2_ActivateCredential()` evaluates an authorization + policy of the sender's choice. + +Together with [`TPM2_MakeCredential()`](TPM2_MakeCredential.md) an +[`TPM2_Quote()`](TPM2_Quote.md) this function can be used to implement +attestation protocols. + +Two of the input parameters of `TPM2_ActivateCredential()`, `keyHandle` +and `activateHandle`, correspond to the `handle` and `objectName` inputs +of [`TPM2_MakeCredential()`](TPM2_MakeCredential.md), respectively. The +other inputs are [`TPM2_MakeCredential()`](TPM2_MakeCredential.md)'s +outputs. The output, `certInfo` is +[`TPM2_MakeCredential()`](TPM2_MakeCredential.md)'s `credential` input. + +## Authorization + +`TPM2_ActivateCredential()` checks the authorization of the caller to +perform this operation by enforcing the `keyHandle`'s policy in the +`USER` role, and the `activateHandle`'s policy in the `ADMIN` role. See +section 19.2 of [TCG TPM Library part 1: +Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf). + +What this means specifically depends on whether the `userWithAuth` +attribute is set on the `keyHandle` and whether the `adminWithPolicy` +attribute is set on the `activateHandle`. + +In particular, if `adminWithPolicy` is set on the `activateHandle` then +the authorization session's `policyDigest` must match the +`activateHandle`'s policy _and_ the authorization session's +`commandCode` must be set to `TPM_CC_ActivateCredential`, which means +that the caller must have called `TPM2_PolicyCommandCode()` with +`TPM_CC_ActivateCredential` as the command code argument. + +Some possible authorization policies to enforce include: + + - that some non-resettable PCR has not been extended since boot + + This allows the recipient to extend that PCR immediately after + activating the credential to prevent the attestation protocol from + being used again without rebooting. + + - user authentication / attended boot + + The policy could require physical presence, authentication of a user + with biometrics and/or a smartcard and/or a password. + + - locality + +## Inputs + + - `TPMI_DH_OBJECT keyHandle` (e.g., handle for an EK corresponding to the EKpub encrypted to by `TPM2_MakeCredential()`) + - `TPMI_DH_OBJECT activateHandle` (e.g., handle for an AK) + - `TPM2B_ID_OBJECT credentialBlob` (output of `TPM2_MakeCredential()`) + - `TPM2B_ENCRYPTED_SECRET secret` (output of `TPM2_MakeCredential()`) + +## Outputs (success case) + + - `TPM2B_DIGEST certInfo` (not necessarily a digest, but a small [digest-sized] secret that was input to `TPM2_MakeCredential()`) + +## References + + - [TCG TPM Library part 1: Architecture, section 24](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf) + - [TCG TPM Library part 2: Structures](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf) + - [TCG TPM Library part 3: Commands, section 12](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + - [TCG TPM Library part 3: Commands Code, section 12](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_code_pub.pdf) + diff --git a/TPM-Commands/TPM2_Certify.md b/TPM-Commands/TPM2_Certify.md new file mode 100644 index 0000000..8140382 --- /dev/null +++ b/TPM-Commands/TPM2_Certify.md @@ -0,0 +1,21 @@ +# `TPM2_Certify()` + +`TPM2_Certify()` signs an assertion that some named object is loaded in +the TPM. + +## Inputs + + - `TPMI_DH_OBJECT objectHandle` (object to be certified) + - `TPMI_DH_OBJECT signHandle` (handle for a signing key) + - `TPM2B_DATA qualifyingData` (extra data) + - `TPMT_SIG_SCHEME inScheme` ("signing scheme to use if the schemefor signHandleis `TPM_ALG_NULL`") + +## Outputs (success case) + + - `TPM2B_ATTEST certifyInfo` (what was signed) + - `TPMT_SIGNATURE signature` (signature) + +## References + + - [TCG TPM Library part 3: Commands, section 18.2](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + diff --git a/TPM-Commands/TPM2_Create.md b/TPM-Commands/TPM2_Create.md new file mode 100644 index 0000000..6227fd1 --- /dev/null +++ b/TPM-Commands/TPM2_Create.md @@ -0,0 +1,49 @@ +# `TPM2_Create()` + +This command creates an ordinary key object. + +The created object can then be loaded with [`TPM2_Load()`](TPM2_Load.md). + +To decide whether to use [`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md), +`TPM2_Create()`, or [`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) +refer to table 28 in section 2.7 of the [TCG TPM Library part 1: +Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf). + +If you need to `TPM2_CertifyCreation()` that a TPM created some object, +you must use [`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +`TPM2_Create()`. + +If you need to seal the object to a PCR selection, you must use +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +`TPM2_Create()`. + +If you need to create a derived object, you must use +[`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md). + +If you need to create an ordinary object, use `TPM2_Create()` or +[`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md). + +If you need to create a primary object, use +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +[`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md). + +## Inputs + + - `TPMI_DH_OBJECT parentHandle` + - `TPM2B_PUBLIC inPublic` + - `TPM2B_DATA outsideInfo` + - `TPML_PCR_SELECTION creationPCR` + +## Outputs (success case) + + - `TPM_HANDLE objectHandle` + - `TPM2B_PRIVATE outPrivate` + - `TPM2B_PUBLIC outPublic` + - `TPM2B_CREATION_DATA creationData` + - `TPM2B_DIGEST creationHash` + - `TPMT_TK_CREATION creationTicket` + +## References + + - [TCG TPM Library part 3: Commands, section 12.1](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + diff --git a/TPM-Commands/TPM2_CreateLoaded.md b/TPM-Commands/TPM2_CreateLoaded.md new file mode 100644 index 0000000..3464422 --- /dev/null +++ b/TPM-Commands/TPM2_CreateLoaded.md @@ -0,0 +1,43 @@ +# `TPM2_CreateLoaded()` + +This command creates a key object and loads it. The object can be a +primary key, in which case `TPM2_CreateLoaded()` behaves just like +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md). Or the object can be +`ordinary` or `derived`. + +The created object can then be loaded with [`TPM2_Load()`](TPM2_Load.md). + +To decide whether to use `TPM2_CreateLoaded()`, +[`TPM2_Create()`](TPM2_Create.md), or +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) refer to table 28 in +section 2.7 of the [TCG TPM Library part 1: +Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf). + +If you need to `TPM2_CertifyCreation()` that a TPM created some object, +you must use [`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +[`TPM2_Create()`](TPM2_Create.md). + +If you need to seal the object to a PCR selection, you must use +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +[`TPM2_Create()`](TPM2_Create.md). + +If you need to create a derived object, you must use +`TPM2_CreateLoaded()`. + +## Inputs + + - `TPMI_DH_PARENT+ parentHandle` + - `TPM2B_SENSITIVE_CREATE inSensitive` + - `TPM2B_TEMPLATE inPublic` + +## Outputs (success case) + + - `TPM_HANDLE objectHandle` + - `TPM2B_PRIVATE outPrivate` (optional) + - `TPM2B_PUBLIC outPublic` + - `TPM2B_NAME name` + +## References + + - [TCG TPM Library part 3: Commands, section 12.9](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + diff --git a/TPM-Commands/TPM2_CreatePrimary.md b/TPM-Commands/TPM2_CreatePrimary.md new file mode 100644 index 0000000..e14d293 --- /dev/null +++ b/TPM-Commands/TPM2_CreatePrimary.md @@ -0,0 +1,41 @@ +# `TPM2_CreatePrimary()` + +This command creates a primary key object. + +The created object can then be loaded with [`TPM2_Load()`](TPM2_Load.md). + +To decide whether to use [`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md), +[`TPM2_Create()`](TPM2_Create.md), or +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) refer to table 28 in +section 2.7 of the [TCG TPM Library part 1: +Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf). + +If you need to `TPM2_CertifyCreation()` that a TPM created some object, +you must use [`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +[`TPM2_Create()`](TPM2_Create.md). + +If you need to seal the object to a PCR selection, you must use +[`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) or +[`TPM2_Create()`](TPM2_Create.md). + +If you need to create a derived object, you must use +[`TPM2_CreateLoaded()`](TPM2_CreateLoaded.md). + +## Inputs + + - `TPMI_RH_HIERARCHY+ primaryHandle` + - `TPM2B_TEMPLATE inPublic` + - `TPM2B_DATA outsideInfo` + - `TPML_PCR_SELECTION creationPCR` + +## Outputs (success case) + + - `TPM_HANDLE objectHandle` + - `TPM2B_CREATION_DATA creationData` + - `TPM2B_DIGEST creationHash` + - `TPMT_TK_CREATION creationTicket` + - `TPM2B_NAME name` + +## References + + - [TCG TPM Library part 3: Commands, section 24.1](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) diff --git a/TPM-Commands/TPM2_Duplicate.md b/TPM-Commands/TPM2_Duplicate.md new file mode 100644 index 0000000..4b11640 --- /dev/null +++ b/TPM-Commands/TPM2_Duplicate.md @@ -0,0 +1,25 @@ +# `TPM2_Duplicate()` + +`TPM2_Duplicate()` wraps a key, typically encrypting it to a public key +for a key on a remote TPM. + +I.e., this is used to export a wrapped key for some target, typically a +remote TPM. + +## Inputs + + - `TPMI_DH_OBJECT objectHandle` (handle for key to encrypt with) + - `TPMI_DH_OBJECT newParentHandle` (optional; handle for key to wrap to -- "Only the public area of newParentHandle is required to be loaded") + - `TPM2B_DATA encryptionKeyIn` (optional; symmetric key to encrypt with) + - `TPMT_SYM_DEF_OBJECT+ symmetricAlg` ("definition for the symmetric algorithm to be used for the inner wrapper") + +## Outputs (success case) + + - `TPM2B_DATA encryptionKeyOut` + - `TPM2B_PRIVATE duplicate` + - `TPM2B_ENCRYPTED_SECRET outSymSeed` + +## References + + - [TCG TPM Library part 3: Commands, section 18.4](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + diff --git a/TPM-Commands/TPM2_Import.md b/TPM-Commands/TPM2_Import.md new file mode 100644 index 0000000..8b60de9 --- /dev/null +++ b/TPM-Commands/TPM2_Import.md @@ -0,0 +1,22 @@ +# `TPM2_Import()` + +`TPM2_Import()` reads a wrapped key produced by +[`TPM2_Duplicate()`](TPM2_Duplicate.md) and outputs a blob that can be +saved and later loaded with [`TPM2_Load()`](TPM2_Load.md). + +## Inputs + + - `TPM2B_DATA encryptionKey` (optional; symmetric key to decrypt with) + - `TPM2B_PUBLIC objectPublic` + - `TPM2B_PRIVATE duplicate` + - `TPM2B_ENCRYPTED_SECRET inSymSeed` + - `TPMT_SYM_DEF_OBJECT+ symmetricAlg` + +## Outputs (success case) + + - `TPM2B_PRIVATE outPrivate` + +## References + + - [TCG TPM Library part 3: Commands, section 13.3](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + diff --git a/TPM-Commands/TPM2_Load.md b/TPM-Commands/TPM2_Load.md new file mode 100644 index 0000000..4471633 --- /dev/null +++ b/TPM-Commands/TPM2_Load.md @@ -0,0 +1,19 @@ +# `TPM2_Load()` + +`TPM2_Load()` loads a saved key. + +## Inputs + + - `TPMI_DH_OBJECT parentHandle` + - `TPM2B_PRIVATE inPrivate` + - `TPM2B_PUBLIC inPublic` + +## Outputs (success case) + + - `TPM_HANDLE objectHandle` + - `TPM2B_NAME name` + +## References + + - [TCG TPM Library part 3: Commands, section 12.2.2](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + diff --git a/TPM-Commands/TPM2_MakeCredential.md b/TPM-Commands/TPM2_MakeCredential.md new file mode 100644 index 0000000..664709d --- /dev/null +++ b/TPM-Commands/TPM2_MakeCredential.md @@ -0,0 +1,89 @@ +# `TPM2_MakeCredential()` + +`TPM2_MakeCredential()` and +[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) provide a +mechanism by which an application can send secrets to a TPM-using +application. This mechanism is asymmetric encryption/decryption with +support for an authorization policy of the sender's choice. + +`TPM2_MakeCredential()` takes an a public key (typically the endorsement +key's public key), the [cryptographic name of an +object](/Intro/README.md#Cryptographic-Object-Naming) in a TPM +identified by that the given public key, and a small secret called a +`credential`, and it encrypts `{name, credential}` to the given public +key. + +The object name input parameter, being a name, binds an optional +authorization policy that +[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) will enforce. + +`TPM2_MakeCredential()` can be implemented entirely in software, as it +uses no secret, TPM-resident key material. All the interesting +semantics are on the +[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) side. + +Together with [`TPM2_Quote()`](TPM2_Quote.md) and +[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md), this function +can be used to implement attestation protocols. + +A typical use is to encrypt an AES key to an `EKpub`, then encrypt a +large secret payload in the AES key, then sending the outputs of +`TPM2_MakeCredential()` and the encrypted large secret payload. The +peer receives these items and calls +[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) to recover the +AES key, then decrypts the large ciphertext payload to recover the large +cleartext secret. + +> NOTE: The `objectName` input names a key object that must present on +> the destination TPM, and the `objectName` is included in the plaintext +> that is encrypted to the public key identified by `handle`, _but_ none +> of the key material of `objectName` is used to key any cryptographic +> operations in `TPM2_MakeCredential()`, and therefore neither is the +> private area of `objectName` on the destination TPM used in any +> cryptographic operations in +> [`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md). +> +> This means that the key named by `objectName` can even be a +> universally-well-known key. The only part of that key that truly +> matters is the policy digest named in the public area of `objectName`. + +## Authorization + +[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) checks the +authorization of the caller to perform this operation by enforcing the +sender's policy named by the sender's `objectName`. See +[here](TPM2_ActivateCredential.md) for details. + +Some possible authorization policies to enforce include: + + - that some non-resettable PCR has not been extended since boot + + This allows the recipient to extend that PCR immediately after + activating the credential to prevent the attestation protocol from + being used again without rebooting. + + - user authentication / attended boot + + The policy could require physical presence, authentication of a user + with biometrics and/or a smartcard and/or a password. + + - locality + +## Inputs + + - `TPMI_DH_OBJECT handle` (public key to encrypt to, typically a remote TPM's EKpub) + - `TPM2B_DIGEST credential` (not necessarily a digest, but a small [digest-sized] secret) + - `TPM2B_NAME objectName` (name of object resident on the same TPM as `handle` that `TPM2_ActivateCredential()` will check) + +## Outputs + + - `TPM2B_ID_OBJECT credentialBlob` (ciphertext of encryption of `credential` with a secret "seed" [see below]) + - `TPM2B_ENCRYPTED_SECRET secret` (ciphertext of encryption of a "seed" to `handle`) + +## References + + - [TCG TPM Library part 1: Architecture, section 24](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf) + - [TCG TPM Library part 2: Structures](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf) + - [TCG TPM Library part 3: Commands, section 13](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf) + - [TCG TPM Library part 3: Commands Code, section 13](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_code_pub.pdf) + diff --git a/Attestation/TPM2_Quote.md b/TPM-Commands/TPM2_Quote.md similarity index 100% rename from Attestation/TPM2_Quote.md rename to TPM-Commands/TPM2_Quote.md