mirror of
https://github.com/tpm2dev/tpm.dev.tutorials.git
synced 2024-11-21 13:32:10 +00:00
Merge pull request #13 from nicowilliams/master
Expand on restricted keys; describe more TPM commands
This commit is contained in:
commit
463d39f272
15 changed files with 1244 additions and 178 deletions
|
@ -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
|
attestation service over a network. This requires a network protocol
|
||||||
for attestation.
|
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
|
## Notation
|
||||||
|
|
||||||
- `Encrypt_<name>` == encryption with the named private or secret key
|
- `Encrypt_<name>` == encryption with the named private or secret key
|
||||||
|
@ -78,6 +98,70 @@ for attestation.
|
||||||
- `{"key":<value>,...}` == JSON text
|
- `{"key":<value>,...}` == JSON text
|
||||||
- `TPM2_MakeCredential(<args>)` == outputs of calling `TPM2_MakeCredential()` with `args` arguments
|
- `TPM2_MakeCredential(<args>)` == outputs of calling `TPM2_MakeCredential()` with `args` arguments
|
||||||
- `TPM2_Certify(<args>)` == outputs of calling `TPM2_Certify()` 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
|
## 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
|
that it was able to decrypt that with the EK. However, this is not
|
||||||
_quite_ how attestation protocols work! Instead of plain asymmetric
|
_quite_ how attestation protocols work! Instead of plain asymmetric
|
||||||
encryption the server will use
|
encryption the server will use
|
||||||
[`TPM2_MakeCredential()`](TPM2_MakeCredential.md), while the attestation
|
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md), while
|
||||||
client will use
|
the attestation client will use
|
||||||
[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) instead of
|
[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md)
|
||||||
plain asymmetric decryption.
|
instead of plain asymmetric decryption.
|
||||||
|
|
||||||
## Trusted State Attestation
|
## 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
|
signing-only asymmetric public key pair known as the attestation key
|
||||||
(AK) with which to sign the PCR quote and eventlog. Binding of the
|
(AK) with which to sign the PCR quote and eventlog. Binding of the
|
||||||
EKpub and AKpub will happen via
|
EKpub and AKpub will happen via
|
||||||
[`TPM2_MakeCredential()`](TPM2_MakeCredential.md) /
|
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) /
|
||||||
[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.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
|
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
|
which they have access), which would be the AK used in the attestation
|
||||||
protocol.
|
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
|
a client's messages to the attestation service that include a signature
|
||||||
made with the AK, but integrity protection of everything else can be
|
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
|
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
|
## Binding of Other Keys to EKpub
|
||||||
|
|
||||||
The semantics of [`TPM2_MakeCredential()`](TPM2_MakeCredential.md) /
|
The semantics of [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) /
|
||||||
[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) make it
|
[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) make it
|
||||||
possible to bind a TPM-resident object to the TPM's EKpub.
|
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
|
a small secret datum and the name (digest of public part) of the
|
||||||
TPM-resident object being bound. The counter-part to this,
|
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
|
that and return the secret to the application IFF (if and only if) the
|
||||||
caller has access to the named object.
|
caller has access to the named object.
|
||||||
|
|
||||||
|
@ -195,14 +279,14 @@ Let's start with few observations and security considerations:
|
||||||
timestamps.
|
timestamps.
|
||||||
|
|
||||||
- Replay protection of server to client responses is mostly either not
|
- 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
|
because `TPM2_MakeCredential()` generates a secret seed that
|
||||||
randomizes its outputs even when all the inputs are the same across
|
randomizes its outputs even when all the inputs are the same across
|
||||||
multiple calls to it.
|
multiple calls to it.
|
||||||
|
|
||||||
- Ultimately the protocol *must* make use of
|
- Ultimately the protocol *must* make use of
|
||||||
[`TPM2_MakeCredential()`](TMP2_MakeCredential.md) and
|
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) and
|
||||||
[`TPM2_ActivateCredential()`](TPM2_ActivateCredential.md) in order to
|
[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md) in order to
|
||||||
authenticate a TPM-running host via its TPM's EKpub.
|
authenticate a TPM-running host via its TPM's EKpub.
|
||||||
|
|
||||||
- Privacy protection of client identifiers may be needed, in which case
|
- Privacy protection of client identifiers may be needed, in which case
|
||||||
|
@ -288,7 +372,7 @@ protocol:
|
||||||
![Protocol Diagram](Protocol-Two-Messages.png)
|
![Protocol Diagram](Protocol-Two-Messages.png)
|
||||||
|
|
||||||
(In this diagram we show the use of a TPM simulator on the server side
|
(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 server will validate that the `timestamp` is near the current time,
|
||||||
the EKcert (if provided, else the EKpub), the signature using the
|
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:
|
database:
|
||||||
|
|
||||||
```
|
```
|
||||||
<having previously successfully enrolled AKpub and bound it to EKpub...>
|
<having previously successfully enrolled>
|
||||||
|
|
||||||
CS0: timestamp, AKpub, PCRs, eventlog,
|
CS0: timestamp, AKpub, PCRs, eventlog,
|
||||||
TPM2_Quote(AK, PCRs, extra_data)=Signed_AK({hash-of-PCRs, misc, extra_data})
|
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)
|
![Protocol Diagram](Protocol-Three-Messages.png)
|
||||||
|
|
||||||
(In this diagram we show the use of a TPM simulator on the server side
|
(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
|
NOTE well that in this protocol, like single round trip attestation
|
||||||
protocols using only decrypt-only EKs, it is *essential* that the AKcert
|
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.
|
An AKcert will be added to the Safeboot protocol soon.
|
||||||
|
|
||||||
### Actual Protocols: ...
|
|
||||||
|
|
||||||
(TBD)
|
|
||||||
|
|
||||||
## Attestation Protocol Patterns and Actual Protocols (signing-only EKs)
|
## Attestation Protocol Patterns and Actual Protocols (signing-only EKs)
|
||||||
|
|
||||||
Some TPMs come provisioned with signing-only endorsement keys in
|
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": "<...>",
|
"previous_PCRs": "<...>",
|
||||||
"proposed_PCRs": "<...>",
|
"proposed_PCRs": "<...>",
|
||||||
"ak_cert_template": "<AKCertTemplate>",
|
"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
|
firmware/OS upgrade and if so replace the `previous_PCRs` with the
|
||||||
`proposed_PCRs`, then the client could attempt attestation again.
|
`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
|
An attestation server might have to return storage/filesystem decryption
|
||||||
key-encryption-keys to a client. But one might not want to store those
|
key-encryption-keys (KEKs) to a client. But one might not want to store
|
||||||
keys in the clear on the attestation server. As well, one might want a
|
those keys in the clear on the attestation server. As well, one might
|
||||||
break-glass way to recover those secrets.
|
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
|
For break-glass recovery, the simplest thing to do is to store
|
||||||
`Encrypt_backupKey({EKpub, hostname, secrets})`, where `backupKey` is an
|
`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
|
kept, decrypt it, and then use the secrets manually to recover the
|
||||||
affected system.
|
affected system.
|
||||||
|
|
||||||
Here are some ideas for how to make an attestation client depend on the
|
## Secret Transport Sub-Protocols
|
||||||
attestation server giving it keys needed to continue booting after
|
|
||||||
successful attestation:
|
|
||||||
|
|
||||||
- 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
|
### Store a `TPM2_MakeCredential()` Payload
|
||||||
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.
|
|
||||||
|
|
||||||
TPM replacement and/or migration of a host from one physical system
|
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) and
|
||||||
to another can be implemented by learning the new system's TPM's
|
[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md)
|
||||||
EKpub and using the offline `backupKey` to compute
|
are a form of limited asymmetric encryption (`TPM2_MakeCredential()`)
|
||||||
`TPM2_MakeCredential(EKpub_new, someObjectName, key0)` and update the
|
and asymmetric decryption (`TPM2_ActivateCredential()`) subject to the
|
||||||
host's entry.
|
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 transport key (typically the `EK`),
|
||||||
a set template and extra entropy, on the same non-NULL hierarchy
|
- and an authorization key (typically an `AK`)
|
||||||
(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.
|
|
||||||
|
|
||||||
(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
|
So if we can store the outputs of `TPM2_MakeCredential()` long-term so
|
||||||
that is used as a policy PCR for unsealing a persistent object stored
|
that the client can activate over multiple reboots, then we have a way
|
||||||
on the client's TPM.
|
to deliver secrets to the client.
|
||||||
|
|
||||||
In this mode the server sends the client the secret PCR extension
|
We'll discuss two ways to do this:
|
||||||
value, and the client uses it to extend a PCR such that it can then
|
|
||||||
unseal the real storage / filesystem decryption keys.
|
|
||||||
|
|
||||||
Using a PCR and a policy on the key object allows for a clever
|
- use a `WK` -- a universally well-known key (thus WK, for well-known)
|
||||||
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).
|
|
||||||
|
|
||||||
- A hybrid of the previous options, where the server stores a secret
|
Since the `WK`'s private area is not used for any cryptography in
|
||||||
PCR extension value wrapped with `TPM2_MakeCredential()`.
|
`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
|
# References
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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
139
Enrollment/README.md
Normal 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
|
362
Intro/README.md
362
Intro/README.md
|
@ -48,6 +48,39 @@ general, which include:
|
||||||
> software development using TPMs will want to make use of [TCG
|
> software development using TPMs will want to make use of [TCG
|
||||||
> specifications and other resources](#Other-Resources).
|
> 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
|
## Glossary
|
||||||
|
|
||||||
> For a glossary, see section 4 of [TCG TPM 2.0 Library part 1:
|
> 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
|
> restricted keys. Still, it may be useful to illustrate cryptographic
|
||||||
> object naming with one particularly important use of it.
|
> object naming with one particularly important use of it.
|
||||||
|
|
||||||
A pair of functions, `TPM2_MakeCredential()` and
|
A pair of functions,
|
||||||
`TPM2_ActivateCredential()`, illustrate the use of cryptographic object
|
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) and
|
||||||
naming as a binding or a sort of authorization function.
|
[`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")
|
[`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) can be
|
||||||
to a target TPM such that the target will _only be willing to decrypt
|
used to encrypt a datum (a "credential") to a target TPM such that the
|
||||||
it_ if *and only if* the application calling `TPM2_ActivateCredential()`
|
target will _only be willing to decrypt it_ if *and only if* the
|
||||||
to decrypt that credential has access to some key named by the sender,
|
application calling `TPM2_ActivateCredential()` to decrypt that
|
||||||
and that name is a cryptographic name that the sender can and must
|
credential has access to some key named by the sender, and that name is
|
||||||
compute for itself.
|
a cryptographic name that the sender can and must compute for itself.
|
||||||
|
|
||||||
The semantics of these two functions can be used to defeat a
|
The semantics of these two functions can be used to defeat a
|
||||||
cut-and-paste attack in attestation protocols.
|
cut-and-paste attack in attestation protocols.
|
||||||
|
@ -312,21 +347,21 @@ keys, each with zero, one, or more children keys:
|
||||||
|
|
||||||
```
|
```
|
||||||
seed
|
seed
|
||||||
|
|
/|\
|
||||||
|
|
/ | \
|
||||||
v
|
v v v
|
||||||
primary key (asymmetric encryption)
|
primary key (asymmetric encryption)
|
||||||
|
|
/|\
|
||||||
|
|
/ | \
|
||||||
v
|
v v v
|
||||||
secondary keys (of any kind)
|
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:
|
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
|
("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 platform's, and even the platform's user(s)' identities.
|
||||||
|
|
||||||
The `TPM2_CreatePrimary()` and `TPM2_CreateLoaded()` commands create key
|
The [`TPM2_CreatePrimary()`](TPM2_CreatePrimary.md) command creates
|
||||||
objects deterministically from the hierarchy's seed and the "template"
|
primary key objects deterministically from the hierarchy's seed and the
|
||||||
used to create the key (which includes a "unique" area that provides
|
"template" used to create the key (which includes a "unique" area that
|
||||||
"entropy" to the key derivation function).
|
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
|
## 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
|
Construction of a policy consists of computing it by hash extending an
|
||||||
initial all-zeroes value with the commands that make up the policy.
|
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
|
### Policy Evaluation
|
||||||
|
|
||||||
Evaluation of a policy consists of issuing those same commands to the
|
Evaluation of a policy consists of issuing those same commands to the
|
||||||
TPM in a session, with those commands either evaluated immediately or
|
TPM in a [non-trial] session, with those commands either evaluated
|
||||||
deferred to the time of execution of the to-be-authorized command, but
|
either immediately or deferred to the time of execution of the
|
||||||
the TPM computes the same hash extension as it goes. Once all policy
|
to-be-authorized command, but the TPM computes the same hash extension
|
||||||
commands being evaluated have succeeded, the resulting hash extension
|
as it goes. Once all policy commands issued have been evaluated and
|
||||||
value is compared to the policy that protects the resource(s) being used
|
have succeeded, the resulting hash extension value is compared to the
|
||||||
by the to-be-authorized command, and if it matches, then the command is
|
policy that protects the resource used by the to-be-authorized command,
|
||||||
allowed, otherwise it is not.
|
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
|
### Indirect Policies
|
||||||
|
|
||||||
|
@ -530,9 +593,108 @@ indexes, policies can be used to:
|
||||||
## Sessions
|
## Sessions
|
||||||
|
|
||||||
A session is an object (meaning, among other things, that it can be
|
A session is an object (meaning, among other things, that it can be
|
||||||
loaded and unloaded as needed) that represents the current policy
|
loaded and unloaded as needed) that represents the current state used
|
||||||
construction or evaluation hash extension digest (the `policyDigest`),
|
for authorization of actions or for encryption of traffic between the
|
||||||
and the objects that have been granted access.
|
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
|
## 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 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
|
A restricted signing key can be used to sign only TPM-generated content
|
||||||
as part of specific TPM restricted signing commands. Such content
|
as part of specific TPM restricted signing commands. Such content
|
||||||
always begins with a magic byte sequence. Conversely, the TPM refuses
|
always begins with a magic byte sequence. Conversely, the TPM refuses
|
||||||
to sign externally generated content that starts with that magic byte
|
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
|
A restricted decryption key can only be used to decrypt ciphertexts
|
||||||
whose plaintexts have a certain structure. In particular these are used
|
whose plaintexts have a certain structure. In particular these are used
|
||||||
for `TPM2_MakeCredential()`/`TPM2_ActivateCredential()` to allow the
|
for [`TPM2_MakeCredential()`](/TPM-Commands/TPM2_MakeCredential.md) /
|
||||||
TPM-using application to get the plaintext if and only if (IFF) the
|
[`TPM2_ActivateCredential()`](/TPM-Commands/TPM2_ActivateCredential.md)
|
||||||
plaintext cryptographically names an object that the application has
|
to allow the TPM-using application to get the plaintext if and only if
|
||||||
access to. This is used to communicate secrets ("credentials") to TPMs.
|
(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
|
Another operation that a restricted decryption key can perform is
|
||||||
PKIX certificates.
|
[`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
|
## Attestation
|
||||||
|
|
||||||
|
@ -577,19 +771,87 @@ many TPM concepts can be used to great effect:
|
||||||
- authorization of devices onto a network
|
- authorization of devices onto a network
|
||||||
- etc.
|
- 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
|
# 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.
|
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
|
- Nokia has a [TPM course](https://github.com/nokia/TPMCourse/tree/master/docs).
|
||||||
possible to be invited to be a non-fee paying member.
|
|
||||||
|
|
||||||
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).
|
- [Microsoft has solid TPM resources](https://docs.microsoft.com/en-us/windows/security/information-protection/tpm/trusted-platform-module-top-node).
|
||||||
- [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).
|
- The TCG has a number of members-only tutorials, but it seems that it
|
||||||
- [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).
|
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).
|
||||||
|
|
76
TPM-Commands/TPM2_ActivateCredential.md
Normal file
76
TPM-Commands/TPM2_ActivateCredential.md
Normal 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)
|
||||||
|
|
21
TPM-Commands/TPM2_Certify.md
Normal file
21
TPM-Commands/TPM2_Certify.md
Normal 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)
|
||||||
|
|
49
TPM-Commands/TPM2_Create.md
Normal file
49
TPM-Commands/TPM2_Create.md
Normal 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)
|
||||||
|
|
43
TPM-Commands/TPM2_CreateLoaded.md
Normal file
43
TPM-Commands/TPM2_CreateLoaded.md
Normal 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)
|
||||||
|
|
41
TPM-Commands/TPM2_CreatePrimary.md
Normal file
41
TPM-Commands/TPM2_CreatePrimary.md
Normal 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)
|
25
TPM-Commands/TPM2_Duplicate.md
Normal file
25
TPM-Commands/TPM2_Duplicate.md
Normal 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)
|
||||||
|
|
22
TPM-Commands/TPM2_Import.md
Normal file
22
TPM-Commands/TPM2_Import.md
Normal 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
19
TPM-Commands/TPM2_Load.md
Normal 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)
|
||||||
|
|
89
TPM-Commands/TPM2_MakeCredential.md
Normal file
89
TPM-Commands/TPM2_MakeCredential.md
Normal 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)
|
||||||
|
|
Loading…
Reference in a new issue