Skip to content

Commit 888e535

Browse files
committed
Enrollz TPM 1.2 RotateAIK() enrollment flow README
1 parent 7f6b794 commit 888e535

File tree

2 files changed

+187
-0
lines changed

2 files changed

+187
-0
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Enrollz-2: TPM 1.2 RotateAIK Flow
2+
3+
## Summary
4+
5+
This document details the RotateAIK enrollment flow for devices equipped with TPM 1.2. It describes the interaction between the EnrollZ Service and the device, the cryptographic structures involved, and the mapping to the `RotateAIKCertRequest` and `RotateAIKCertResponse` Protocol Buffers.
6+
7+
The RotateAIK flow for TPM 1.2 is used to generate an Attestation Identity Key (AIK) pair on the device, certify it using the device's Endorsement Key (EK), and install the resulting AIK Certificate. This flow requires the service to have prior knowledge of the device's public Endorsement Key (EK), which is typically retrieved from the device's Endorsement Certificate.
8+
9+
TPM 1.2 utilizes the `MakeIdentity` protocol. This process involves the device generating a `TPM_IDENTITY_REQ`, and the service responding with an encrypted credential that only the device's EK can decrypt.
10+
11+
## Procedure
12+
13+
### Protocol Buffer Definitions
14+
15+
The flow relies on the `RotateAIKCertRequest` and `RotateAIKCertResponse` messages.
16+
17+
```protobuf
18+
// The RotateAIKCertRequest handles the workflow for enrollment of TPM1.2
19+
// devices. The initial request will include the issuer_public_key to allow
20+
// the building of the AIK which will then be returned and used to generate
21+
// the AIK cert. For any updates after initial enrollment the new AIK cert
22+
// can just be returned.
23+
message RotateAIKCertRequest {
24+
message IssuerCertPayload {
25+
// Symmetric key used to encrypt the AIK Cert blob.
26+
// Note: This corresponds to the TPM_ASYM_CA_CONTENTS structure encrypted
27+
// with the EK. It contains the session key.
28+
bytes symmetric_key_blob = 1;
29+
// AIK Cert in PEM format that is encrypted with the provided symmetric
30+
// key.
31+
bytes aik_cert_blob = 2;
32+
}
33+
34+
oneof value {
35+
bytes issuer_public_key = 1;
36+
// Encrypted payload that only the targeted device should be able
37+
// to decrypt via the EK.
38+
IssuerCertPayload issuer_cert_payload = 2;
39+
// Finalize tells the server that the AIK cert is correct.
40+
bool finalize = 3;
41+
}
42+
43+
// Switch control card selected identifier.
44+
ControlCardSelection control_card_selection = 4;
45+
}
46+
47+
message RotateAIKCertResponse {
48+
oneof value {
49+
bytes application_identity_request = 1;
50+
// The decrypted cert in PEM format is returned so the caller can validate
51+
// that the device did in fact have the proper EK.
52+
string aik_cert = 2;
53+
}
54+
55+
// Vendor identity fields of the selected control card.
56+
ControlCardVendorId control_card_id = 3;
57+
}
58+
```
59+
60+
### TPM 1.2 Structures (from `tpm12_utils.go`)
61+
62+
The workflow relies on the correct formation, serialization, and parsing of several TPM 1.2 structures which are defined in the TPM 1.2 TCG specifications, including:
63+
64+
* `TPM_IDENTITY_REQ`
65+
* `TPM_IDENTITY_PROOF`
66+
* `TPM_IDENTITY_CONTENTS`
67+
* `TPM_PUBKEY`
68+
* `TPM_SYMMETRIC_KEY`
69+
* `TPM_ASYM_CA_CONTENTS`
70+
* `TPM_SYM_CA_ATTESTATION`
71+
72+
## Test Cases (enrollz-2)
73+
74+
This section validates that the device correctly implements the service-driven TPM 1.2 RotateAIK enrollment workflow.
75+
76+
| ID | Case | Expected Result |
77+
| :--- | :--- | :--- |
78+
| **enrollz-2.1** | Successful RotateAIK flow. | Device generates AIK, provides `application_identity_request`, decrypts `IssuerCertPayload`, installs AIK cert, and returns cert for verification. |
79+
| **enrollz-2.2** | Service sends `RotateAIKCertRequest` with malformed/missing `issuer_public_key`. | Device returns an error and closes the stream. |
80+
| **enrollz-2.3** | Service sends `RotateAIKCertRequest` with `issuer_cert_payload` but `symmetric_key_blob` is not decryptable (wrong EK). | Device cannot decrypt session key; returns error and closes stream. |
81+
| **enrollz-2.4** | `symmetric_key_blob` decrypts, but `TPM_ASYM_CA_CONTENTS` digest does not match the AIK. | TPM fails `TPM_ActivateIdentity`; device returns error. |
82+
| **enrollz-2.5** | `aik_cert_blob` is not decryptable with the recovered session key. | Device cannot decrypt AIK certificate; returns error. |
83+
| **enrollz-2.6** | Decrypted `aik_cert_blob` is a malformed `TPM_SYM_CA_ATTESTATION` structure. | Device fails to parse structure; returns error. |
84+
| **enrollz-2.7** | Decrypted `aik_cert_blob` contains malformed PEM certificate. | Device fails to install certificate; returns error. |
85+
| **enrollz-2.8** | Service sends `finalize = true` *before* device returns `aik_cert` (Phase 4). | Device ignores premature finalize or returns state error. |
86+
| **enrollz-2.9** | Service closes stream prematurely. | Enrollment aborted; no new AIK persisted. |
87+
| **enrollz-2.10** | Invalid `ControlCardSelection`. | Device returns invalid request error. |
88+
| **enrollz-2.11** | Device fails to generate `TPM_IDENTITY_REQ` after receiving `issuer_public_key`. | Device returns error to service. |
89+
90+
-----
91+
92+
### Workflow Steps
93+
94+
#### Phase 1: Initialization & Key Generation
95+
96+
1. **Service**: Generates an RSA 2048-bit Issuer key pair.
97+
2. **Service**: Sends the `RotateAIKCertRequest` containing the `issuer_public_key` to the device.
98+
3. **Device**: Calls `TPM_MakeIdentity` (via `Tspi_TPM_collateIdentityRequest` or similar).
99+
* This generates the new AIK key pair.
100+
* This creates a `TPM_IDENTITY_REQ` structure containing the `TPM_IDENTITY_PROOF`.
101+
* **Note**: The `TPM_IDENTITY_REQ` involves a symmetric key (`symBlob`) and an asymmetric encryption of that key (`asymBlob`) using the provided `issuer_public_key`.
102+
4. **Device**: Sends `RotateAIKCertResponse` containing the `application_identity_request` (the raw `TPM_IDENTITY_REQ` bytes).
103+
104+
#### Phase 2: Verification (Service Side)
105+
106+
Upon receiving the `application_identity_request`, the EnrollZ Service performs the following:
107+
108+
1. **Parse Request**: Parses the `TPM_IDENTITY_REQ` structure.
109+
2. **Decrypt Session Key**: Uses the Issuer Private Key to decrypt the `asymBlob`, retrieving the `TPM_SYMMETRIC_KEY`.
110+
3. **Decrypt Proof**: Uses the `TPM_SYMMETRIC_KEY` to decrypt the `symBlob`, retrieving the `TPM_IDENTITY_PROOF`.
111+
4. **Reconstruct Contents**: Constructs the `TPM_IDENTITY_CONTENTS` structure to verify the signature.
112+
* `Ver`: `0x01010000`
113+
* `Ordinal`: `0x00000079`
114+
* `labelPrivCADigest`: `SHA1(identityLabel || privacyCA)`
115+
* `identityLabel`: `"Identity"` (UTF-8: `0x4964656e74697479`)
116+
* `privacyCA`: The `issuer_public_key` (`TPM_PUBKEY`)
117+
* `identityPubKey`: The AIK Public Key extracted from the `TPM_IDENTITY_PROOF`.
118+
5. **Verify Signature**: Verifies the `identityBinding` signature (from the proof) against the hash of the reconstructed `TPM_IDENTITY_CONTENTS` using the `identityPubKey` (AIK Public Key).
119+
120+
#### Phase 3: Certification & Encryption (Service Side)
121+
122+
Once the AIK is verified:
123+
124+
1. **Generate Cert**: The Service sends the AIK Public Key (the `identityPubKey` from `TPM_IDENTITY_PROOF`) to the CA and receives the AIK Certificate (PEM).
125+
2. **Create Session Key**: Generates a new AES-256 symmetric key.
126+
3. **Encapsulate Key (`TPM_ASYM_CA_CONTENTS`)**:
127+
* Creates a `TPM_ASYM_CA_CONTENTS` structure **containing the AES-256 session key generated in Step 2**.
128+
* `Digest`: `SHA1(TPM_PUBKEY)` (Hash of the AIK Public Key).
129+
* **Encryption**: Encrypts this structure using the device's Endorsement Key (EK) public key.
130+
* `Algorithm`: RSAES-OAEP with SHA-1 and MGF1.
131+
* `OAEP Parameter`: `"TCPA"` (Required for TPM 1.2 compatibility).
132+
* **Output**: This forms the `symmetric_key_blob` field in `IssuerCertPayload`.
133+
4. **Encrypt Certificate**:
134+
* Encrypts the PEM-encoded AIK Certificate using the AES-256 session key generated in Step 2 (AES CBC).
135+
* A unique Initialization Vector (IV) must be used and is typically prepended to the ciphertext.
136+
* **Output**: This forms the `aik_cert_blob` field in `IssuerCertPayload` (e.g., `iv || ciphertext`).
137+
5. **Send**: The Service sends the `RotateAIKCertRequest` containing the `IssuerCertPayload` to the device.
138+
139+
#### Phase 4: Activation (Device Side)
140+
141+
1. **Device**: Receives the `IssuerCertPayload`.
142+
2. **Decrypt (Activate Identity)**:
143+
* The device uses its EK Private Key to decrypt the `symmetric_key_blob`. This recovers the AES-256 session key.
144+
* **Note**: In standard TSS, this maps to `TPM_ActivateIdentity`, which validates the `TPM_ASYM_CA_CONTENTS` digest against the loaded AIK.
145+
3. **Decrypt Certificate**: The device uses the recovered session key to decrypt the `aik_cert_blob`.
146+
4. **Install**: The device installs/stores the plaintext AIK Certificate.
147+
5. **Prove Possession**: The device sends a `RotateAIKCertResponse` containing the plaintext `aik_cert` back to the Service.
148+
149+
#### Phase 5: Finalization
150+
151+
1. **Service**: Compares the received `aik_cert` with the original certificate it generated.
152+
2. **Service**: If they match, sends a `RotateAIKCertRequest` with `finalize = true`.
153+
3. **Device**: Marks the enrollment as complete.
154+
155+
### Cryptographic Parameters Summary
156+
157+
| Parameter | Value |
158+
|---|---|
159+
| TPM Version | 1.2 |
160+
| Identity Label | `"Identity"` (`0x4964656e74697479`) |
161+
| Structure Version | `0x01010000` |
162+
| OAEP Parameter | `"TCPA"` |
163+
| Hash Algorithm | SHA-1 |
164+
| Symmetric Key | AES-256 (for Cert encryption) |
165+
| Issuer Key | RSA 2048 |
166+
167+
## OpenConfig Path and RPC Coverage
168+
169+
```yaml
170+
paths:
171+
rpcs:
172+
gnmi:
173+
gNMI.Subscribe:
174+
```
175+
176+
## Canonical OC
177+
178+
```json
179+
{}
180+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto
2+
# proto-message: Metadata
3+
4+
uuid: "6ea4e7c6-0a54-40e0-8d61-bd036f305ff6"
5+
plan_id: "Enrollz-2"
6+
description: "TPM 1.2 RotateAIK Flow"
7+
testbed: TESTBED_DUT_ATE_2LINKS

0 commit comments

Comments
 (0)