Skip to content

Commit 150e436

Browse files
authored
Merge pull request #174 from tomoveu/add-ek-attestation
Added option to create keys under the EK in keygen example
2 parents da5a1ad + 8455bea commit 150e436

19 files changed

Lines changed: 726 additions & 132 deletions

File tree

.gitignore

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ src/.deps
2626
src/.libs
2727
RemoteSystemsTempFiles
2828
*.o
29+
*.dep
2930
*.deps
3031
*.libs
32+
IDE/IAR-EWARM/settings
3133
wolftpm/options.h
3234

3335
examples/wrap/wrap_test
@@ -75,12 +77,16 @@ certs/server-*.pem
7577
certs/client-*.der
7678
certs/client-*.pem
7779
certs/serial.old
78-
*.dep
79-
IDE/IAR-EWARM/settings
80+
81+
# Test files
8082
quote.blob
8183
keyblob.bin
8284
ecc_test_blob.raw
8385
rsa_test_blob.raw
86+
ak.name
87+
cred.blob
88+
ek.pub
89+
srk.pub
8490

8591
# Generated Documentation
8692
docs/html

examples/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ More information about how to test and use PCR attestation can be found in the i
4444
`./examples/pcr/extend`
4545
`./examples/pcr/reset`
4646

47+
### Remote Attestation challenge
48+
49+
Demonstrates how to create Remote Attestation challenge using the TPM 2.0 and afterwards prepare a response.
50+
51+
Detailed information about using these examples can be found in [examples/attestation/README.md](./examples/attestation/README.md)
52+
53+
`./examples/attestation/make_credential`
54+
`./examples/attestation/activate_credential`
55+
4756
## Parameter Encryption
4857

4958
### Key generation with encrypted authorization

examples/attestation/README.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Complete list of the required examples is shown below:
1212
* `./examples/attestation/activate_credential`: Used by a client to decrypt the challenge and respond
1313
* `./examples/keygen/keygen`: Used to create a primary key(PK) and attestation key(AK)
1414

15+
Note: All of these example allow the use of the Endorsement Key and Attestation Key under the Endorsement Hierarchy. This is done by adding the `-eh` option when executing any of the three examples above. The advantage of using EK/EH is that the private key material of the EK never leaves the TPM. Anything encrypted using the public part of the EK can be encrypted only internally by the TPM owner of the EK, and EK is unique for every TPM chip. Therefore, creating challenges for Remote Attestation using the EK/EH has greater value in some scenarios. One drawback is that by using the EK the identity of the host under attestation is always known, because the EK private-public key pair identifies the TPM and in some scenarios this might rise privacy concerns. Our remote attestation examples support both AK under SRK and AK under EK. It is up to the developer to decide which one to use.
16+
1517
## Technology introduction
1618

1719
Remote Attestation is the process of a client providing an evidence to an attestation server that verifies if the client is in a known state.
@@ -41,7 +43,6 @@ Note:
4143
Using the `keygen` example we can create the necessary TPM 2.0 Attestation Key and TPM 2.0 Primary Storage Key that will be used as a Primary Attestation Key(PAK).
4244

4345
```
44-
4546
$ ./examples/keygen/keygen -rsa
4647
TPM2.0 Key generation example
4748
Key Blob: keyblob.bin
@@ -53,15 +54,13 @@ RSA AIK template
5354
Creating new RSA key...
5455
Created new key (pub 280, priv 222 bytes)
5556
Wrote 508 bytes to keyblob.bin
56-
5757
```
5858

5959
### Make Credential Example Usage
6060

6161
Using the `make_credential` example an attestation server can generate remote attestation challenge. The secret is 32 bytes of randomly generated seed that could be used for a symmetric key in some remote attestation schemes.
6262

6363
```
64-
6564
$ ./examples/attestation/make_credential
6665
Using default values
6766
Demo how to create a credential blob for remote attestation
@@ -72,7 +71,6 @@ Reading the private part of the key
7271
AK loaded at 0x80000001
7372
TPM2_MakeCredential success
7473
Wrote credential blob and secret to cred.blob, 514 bytes
75-
7674
```
7775

7876
The transfer of the PAK and AK public parts between the client and attestation server is not part of the `make_credential` example, because the exchange is implementation specific.
@@ -82,7 +80,6 @@ The transfer of the PAK and AK public parts between the client and attestation s
8280
Using the `activate_credential` example a client can decrypt the remote attestation challenge. The secret will be exposed in plain and can be exchanged with the attestation server.
8381

8482
```
85-
8683
$ ./examples/attestation/activate_credential
8784
Using default values
8885
Demo how to create a credential blob for remote attestation
@@ -97,7 +94,6 @@ TPM2_StartAuthSession: sessionHandle 0x3000000
9794
TPM2_policyCommandCode success
9895
Read credential blob and secret from cred.blob, 514 bytes
9996
TPM2_ActivateCredential success
100-
10197
```
10298

10399
The transfer of the challenge response containing the secret in plain (or used as a symmetric key seed) is not part of the `activate_credential` example, because the exchange is also implementation specific.

examples/attestation/activate_credential.c

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,19 @@
4242
static void usage(void)
4343
{
4444
printf("Expected usage:\n");
45-
printf("./examples/attestation/activate_credential [cred.blob]\n");
45+
printf("./examples/attestation/activate_credential [cred.blob] [-eh]\n");
4646
printf("* cred.blob is a input file holding the generated credential.\n");
4747
printf("Demo usage without parameters, uses \"cred.blob\" filename.\n");
4848
}
4949

5050
int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
5151
{
5252
int rc = -1;
53+
int endorseKey = 0;
5354
WOLFTPM2_DEV dev;
55+
WOLFTPM2_KEY endorse;
5456
WOLFTPM2_KEY storage;
57+
WOLFTPM2_KEY *primary = NULL;
5558
WOLFTPM2_KEYBLOB akKey;
5659
WOLFTPM2_SESSION tpmSession;
5760
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM)
@@ -63,7 +66,6 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
6366

6467
union {
6568
ActivateCredential_In activCred;
66-
PolicyCommandCode_In policyCommandCode;
6769
byte maxInput[MAX_COMMAND_SIZE];
6870
} cmdIn;
6971
union {
@@ -84,13 +86,18 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
8486
if (argv[1][0] != '-') {
8587
input = argv[1];
8688
}
89+
if (XSTRNCMP(argv[1], "-eh", 3) == 0) {
90+
printf("Use Endorsement Key\n");
91+
endorseKey = 1;
92+
}
8793
}
8894
else {
8995
printf("Incorrect arguments\n");
9096
usage();
9197
goto exit_badargs;
9298
}
9399

100+
XMEMSET(&endorse, 0, sizeof(endorse));
94101
XMEMSET(&storage, 0, sizeof(storage));
95102
XMEMSET(&akKey, 0, sizeof(akKey));
96103

@@ -104,61 +111,67 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
104111

105112
printf("Credential will be read from %s\n", input);
106113

107-
/* Load SRK, required to unwrap credential */
108-
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA);
109-
if (rc != 0) goto exit;
110-
printf("SRK loaded\n");
111-
/* Prepare the auth password for the Storage Key */
112-
storage.handle.auth.size = sizeof(gStorageKeyAuth)-1;
113-
XMEMCPY(storage.handle.auth.buffer, gStorageKeyAuth,
114-
storage.handle.auth.size);
115-
wolfTPM2_SetAuthHandle(&dev, 0, &storage.handle);
114+
/* Load key, required to unwrap credential */
115+
if (endorseKey) {
116+
rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA);
117+
if (rc != 0) goto exit;
118+
printf("EK loaded\n");
119+
/* Endorsement Key requires authorization with Policy */
120+
endorse.handle.policyAuth = 1;
121+
rc = wolfTPM2_CreateAuthSession_EkPolicy(&dev, &tpmSession);
122+
if (rc != 0) goto exit;
123+
/* Set the created Policy Session for use in next operation */
124+
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession, 0);
125+
if (rc != 0) goto exit;
126+
127+
primary = &endorse;
128+
}
129+
else {
130+
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA);
131+
if (rc != 0) goto exit;
132+
printf("SRK loaded\n");
133+
wolfTPM2_SetAuthHandle(&dev, 0, &storage.handle);
134+
135+
primary = &storage;
136+
}
116137

117138
/* Load AK, required to verify the Key Attributes in the credential */
118139
rc = readKeyBlob(keyblob, &akKey);
119140
if (rc != TPM_RC_SUCCESS) {
120141
printf("Failure to read keyblob.\n");
121142
}
122-
storage.handle.hndl = TPM2_DEMO_STORAGE_KEY_HANDLE;
123-
rc = wolfTPM2_LoadKey(&dev, &akKey, &storage.handle);
143+
rc = wolfTPM2_LoadKey(&dev, &akKey, &primary->handle);
124144
if (rc != TPM_RC_SUCCESS) {
125145
printf("Failure to load the AK and read its Name.\n");
126146
goto exit;
127147
}
128148
printf("AK loaded at 0x%x\n", (word32)akKey.handle.hndl);
149+
150+
rc = wolfTPM2_UnsetAuth(&dev, 0);
151+
152+
if (endorseKey) {
153+
/* Fresh policy session for EK auth */
154+
rc = wolfTPM2_CreateAuthSession_EkPolicy(&dev, &tpmSession);
155+
if (rc != 0) goto exit;
156+
/* Set the created Policy Session for use in next operation */
157+
rc = wolfTPM2_SetAuthSession(&dev, 1, &tpmSession, 0);
158+
if (rc != 0) goto exit;
159+
}
160+
else {
161+
wolfTPM2_SetAuthHandle(&dev, 1, &storage.handle);
162+
}
163+
129164
/* Prepare the auth password for the Attestation Key */
130165
akKey.handle.auth.size = sizeof(gAiKeyAuth)-1;
131166
XMEMCPY(akKey.handle.auth.buffer, gAiKeyAuth,
132167
akKey.handle.auth.size);
133168
wolfTPM2_SetAuthHandle(&dev, 0, &akKey.handle);
134169

135-
/* Start an authenticated session (salted / unbound) */
136-
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
137-
TPM_SE_POLICY, TPM_ALG_NULL);
138-
if (rc != 0) goto exit;
139-
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
140-
(word32)tpmSession.handle.hndl);
141-
142-
/* ADMIN role required for Activate Credential command */
143-
XMEMSET(&cmdIn.policyCommandCode, 0, sizeof(cmdIn.policyCommandCode));
144-
cmdIn.policyCommandCode.policySession = tpmSession.handle.hndl;
145-
cmdIn.policyCommandCode.code = TPM_CC_ActivateCredential;
146-
rc = TPM2_PolicyCommandCode(&cmdIn.policyCommandCode);
147-
if (rc != TPM_RC_SUCCESS) {
148-
printf("policyCommandCode failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
149-
goto exit;
150-
}
151-
printf("TPM2_policyCommandCode success\n"); /* No command response payload */
152-
153-
/* Prepare Key Auths in correct order for ActivateCredential */
154-
wolfTPM2_SetAuthHandle(&dev, 0, &akKey.handle);
155-
wolfTPM2_SetAuthHandle(&dev, 1, &storage.handle);
156-
157170
/* Prepare the Activate Credential command */
158171
XMEMSET(&cmdIn.activCred, 0, sizeof(cmdIn.activCred));
159172
XMEMSET(&cmdOut.activCred, 0, sizeof(cmdOut.activCred));
160173
cmdIn.activCred.activateHandle = akKey.handle.hndl;
161-
cmdIn.activCred.keyHandle = TPM2_DEMO_STORAGE_KEY_HANDLE;
174+
cmdIn.activCred.keyHandle = primary->handle.hndl;
162175
/* Read credential from the user file */
163176
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM)
164177
fp = XFOPEN(input, "rb");
@@ -169,7 +182,8 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
169182
sizeof(cmdIn.activCred.secret), fp);
170183
XFCLOSE(fp);
171184
}
172-
printf("Read credential blob and secret from %s, %d bytes\n", input, dataSize);
185+
printf("Read credential blob and secret from %s, %d bytes\n",
186+
input, dataSize);
173187
#else
174188
printf("Can not load credential. File support not enabled\n");
175189
goto exit;
@@ -185,7 +199,7 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
185199

186200
exit:
187201

188-
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
202+
wolfTPM2_UnloadHandle(&dev, &primary->handle);
189203
wolfTPM2_UnloadHandle(&dev, &akKey.handle);
190204
wolfTPM2_Cleanup(&dev);
191205

0 commit comments

Comments
 (0)