Merge pull request #13 from nicowilliams/master

Expand on restricted keys; describe more TPM commands
This commit is contained in:
Dimitar Tomov 2021-06-04 22:51:10 +03:00 committed by GitHub
commit 463d39f272
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 1244 additions and 178 deletions

View file

@ -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_<name>` == encryption with the named private or secret key
@ -78,6 +98,70 @@ for attestation.
- `{"key":<value>,...}` == JSON text
- `TPM2_MakeCredential(<args>)` == outputs of calling `TPM2_MakeCredential()` with `args` arguments
- `TPM2_Certify(<args>)` == outputs of calling `TPM2_Certify()` with `args` arguments
- `XK` == `<X>` key, for some `<X>` 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` == `<X>`'s public key, for some `<X>` purpose
- `EKpub` == endorsement public key
- `AKpub` == attestation public key
- `TKpub` == transport public key
- `XKname` == `<X>`'s cryptographic name, for some `<X>` 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:
```
<having previously successfully enrolled AKpub and bound it to EKpub...>
<having previously successfully enrolled>
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": "<AKCertTemplate>",
"secrets": "<secrets>",
"resetCount": "<resetCount value from last quote>"
"resetCount": "<resetCount value from last quote>",
"secrets": "<see below>"
}
```
@ -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": "<EKpub>",
"hostname": "<hostname>",
"EKcert": "<EKcert in PEM, if available>",
"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": "<resetCount value from last quote>",
"secret store and transport fields":"vvvvvvvvvvvvvvvvvv",
"secrets": ["<MakeCredential_0>", "<MakeCredential_1>", "..", "<MakeCredential_N>"]
"secrets_backup": ["<RSA_Encrypt_to_backup_key(...)", "..."],
}
```
### Use an Unrestricted Decryption Transport Key (TK) for Secret Transport (client-side)
Another option is to generate an asymmetric key-pair at device
enrollment time (we shall call this the "transport key", or `TK`), and
store:
- the `TKpub`, and
- zero, one, or more secrets encrypted in the `EKpub`.
The client has to use
[`TPM2_CreatePrimary()`](/TPM-Commands/TPM2_CreatePrimary.md) or
[`TPM2_CreateLoaded()`](/TPM-Commands/TPM2_CreateLoaded.md) in order to
deterministically create the same `TK` (without the `stClear`)
attribute, else if it uses
[`TPM2_Create()`](/TPM-Commands/TPM2_Create.md) then it must store the
key save file somewhere (possibly in the attestation server!) or make
the key object persistent.
New secrets can be added at any time without interaction with the
client.
```JSON
{
"EKpub": "<EKpub>",
"hostname": "<hostname>",
"EKcert": "<EKcert in PEM, if available>",
"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": "<AKCertTemplate>",
"resetCount": "<resetCount value from last quote>",
"secret store and transport fields":"vvvvvvvvvvvvvvvvvv",
"TKpub": "<TKpub in PEM>",
"secrets": ["<RSA_Encrypt_0>", "<RSA_Encrypt_1>", "..", "<RSA_Encrypt_N>"]
"secrets_backup": ["<RSA_Encrypt_to_backup_key(...)", "..."],
}
```
### Use an Unrestricted Decryption Transport Key (TK) for Secret Transport (server-side)
Another option is to generate an asymmetric key-pair at device
enrollment time (we shall call this the "transport key", or `TK`), and
store:
- the TK exported to the client device's TPM (i.e., the output of
`TPM2_Duplicate()` called on that private key to export it to the
client's TPM's EKpub), and
- the ciphertext resulting from encrypting long-term secrets to that
TK.
At attestation time the server can send back these two values to the
client, and then the client can `TPM2_Import()` and then `TPM2_Load()`
the duplicated (exported) TK, then use it to `TPM2_RSA_Decrypt()` the
encrypted long-term secrets.
New secrets can be added at any time without interaction with the
client.
```JSON
{
"EKpub": "<EKpub>",
"hostname": "<hostname>",
"EKcert": "<EKcert in PEM, if available>",
"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": "<AKCertTemplate>",
"resetCount": "<resetCount value from last quote>",
"secret store and transport fields":"vvvvvvvvvvvvvvvvvv",
"TKdup": "<output of TPM2_Duplicate(EKpub, TK)>",
"TKpub": "<TKpub in PEM>",
"secrets": ["<RSA_Encrypt_0>", "<RSA_Encrypt_1>", "..", "<RSA_Encrypt_N>"]
"secrets_backup": ["<RSA_Encrypt_to_backup_key(...)", "..."],
}
```
### Store a Secret PCR Extension Value for Unsealing Data Objects
The attestation server could store in plaintext a secret that it will
returned encrypted to the client's EKpub vias `TPM2_MakeCredential()`,
and which the client must use to extend a PCR (e.g., the debug PCR) to
get that PCR into the state needed to unseal a persistent data object on
the TPM.
Because the sealed data object may itself be stored in cleartext in the
TPM's NVRAM, and because an attacker might be able to decap a stolen
client device's TPM and recover the TPM's NVRAM contents and seeds, the
client might store an encrypted value in that sealed data object that
the TPM does not have the keey to decrypt. The decryption key would be
sent by the attestation server (possibly being the same secret as is
extended into that PCR).
```JSON
{
"EKpub": "<EKpub>",
"hostname": "<hostname>",
"EKcert": "<EKcert in PEM, if available>",
"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": "<AKCertTemplate>",
"resetCount": "<resetCount value from last quote>",
"secret store and transport fields":"vvvvvvvvvvvvvvvvvv",
"unseal_key": "<key>",
"secrets_backup": ["<RSA_Encrypt_to_backup_key(...)", "..."],
}
```
### Store Secrets in Plaintext, Encrypt to EKpub Using `TPM2_MakeCredential()`
As the title says, one option is to store the secrets in plaintext and
send them encrypted to the EKpub via
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md).
Because [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md)
encrypts only a small secret, it goes without saying that that secret
would be a one-time use symmetric encryption key that would be used to
encrypt the actual secrets.
This is, naturally, the least desirable option.
```JSON
{
"EKpub": "<EKpub>",
"hostname": "<hostname>",
"EKcert": "<EKcert in PEM, if available>",
"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": "<AKCertTemplate>",
"resetCount": "<resetCount value from last quote>",
"secret store and transport fields":"vvvvvvvvvvvvvvvvvv",
"secrets": ["<secret_0>", "<secret_1>", "<secret_N>"]
}
```
# Security Considerations
TBD
# References

View file

@ -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)

View file

@ -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)

139
Enrollment/README.md Normal file
View file

@ -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.})
<extra_data includes timestamp>
```
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

View file

@ -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/)
- [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).
- [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, 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).
- [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).

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

19
TPM-Commands/TPM2_Load.md Normal file
View file

@ -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)

View file

@ -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)