Skip to content

Commit 65d0e6a

Browse files
committed
Documentation and minor fixes. Tested with older SLB9670 and ST33TPH.
1 parent 57f12df commit 65d0e6a

4 files changed

Lines changed: 338 additions & 31 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,13 @@ Connection: close
824824
```
825825

826826

827+
### TPM Endorsement Key Certificates
828+
829+
The TCG EK Credential Profile defines how manfactures provision endorsement certificates in the TCG NV index range (see TPM_20_TCG_NV_SPACE).
830+
The `get_ek_certs` example show how to retrieve those EK cerificates, validate them and create a primary EK handle for signing key.
831+
See `./examples/endorsement/get_ek_certs`.
832+
833+
827834
## Todo
828835

829836
* Update to v1.59 of specification (adding CertifyX509).

examples/endorsement/README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
# TPM Endorsement Certificates
22

3-
The `get_ek_certs` example will enumerate and validate the Endorsement Key Certificates stored in the NV TCG region.
4-
53
TPM manufactures provision Endorsement Certificates based on a TPM key. This certificate can be used for signing/endorsement.
64

5+
The `get_ek_certs` example will enumerate and validate the Endorsement Key Certificates stored in the NV TCG region.
6+
77
We have loaded some of the root and intermediate CA's into the trusted_certs.h file.
88

9-
## Infineon SLB9672 EK Certificate Chain
9+
## Example Detail
10+
11+
1) Get handles in the TCG NV range using `wolfTPM2_GetHandles` with `TPM_20_TCG_NV_SPACE`.
12+
2) Get size of the certificate by reading the public NV information using `wolfTPM2_NVReadPublic`.
13+
3) Read the NV data (certificate DER/ASN.1) from the NV index using `wolfTPM2_NVReadAuth`.
14+
4) Get the EK public template using the NV index by calling `wolfTPM2_GetKeyTemplate_EKIndex` or `wolfTPM2_GetKeyTemplate_EK`.
15+
5) Create the primary endorsement key with public template and TPM_RH_ENDORSEMENT hierarchy using `wolfTPM2_CreatePrimaryKey`.
16+
6) Parse the ASN.1/DER certificate using `wc_ParseCert` to extract issuer, serial number, etc...
17+
7) The URI for the CA issuer certificate can be obtained in `extAuthInfoCaIssuer`.
18+
8) Import the certificate public key and compare it against the primary EK public unique area.
19+
9) Use the wolfSSL Certificate Manager to validate the EK certificate. Trusted certificates are loaded using `wolfSSL_CertManagerLoadCABuffer` and the EK certificate is validated using `wolfSSL_CertManagerVerifyBuffer`.
20+
10) Optionally covert to PEM and export using `wc_DerToPem`.
21+
22+
## Example certificate chains
23+
24+
### Infineon SLB9672
1025

1126
Infineon certificates for TPM 2.0 can be downloaded from the following URLs (replace xxx with 3-digit CA number):
1227

@@ -21,7 +36,7 @@ Examples:
2136
- Infineon OPTIGA(TM) ECC Root CA 2
2237
- Infineon OPTIGA(TM) TPM 2.0 ECC CA 059
2338

24-
## STMicro ST33KTPM EK Certificate Chain
39+
### STMicro ST33KTPM
2540

2641
Example:
2742

examples/endorsement/get_ek_certs.c

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -223,39 +223,40 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
223223
for (nvIdx=0; nvIdx<(int)handles.count; nvIdx++) {
224224
nvIndex = handles.handle[nvIdx];
225225

226+
XMEMSET(&nv, 0, sizeof(nv)); /* Must reset the NV for each read */
227+
XMEMSET(certBuf, 0, sizeof(certBuf));
228+
226229
printf("TCG Handle 0x%x\n", nvIndex);
227230

228-
/* Read Public portion of NV */
231+
/* Get Endorsement Public Key template using NV index */
232+
rc = wolfTPM2_GetKeyTemplate_EKIndex(nvIndex, &publicTemplate);
233+
if (rc != 0) {
234+
printf("EK Index 0x%08x not valid\n", nvIndex);
235+
continue;
236+
}
237+
238+
/* Read Public portion of NV to get actual size */
229239
rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic);
230240
if (rc != 0) {
231241
printf("Failed to read public for NV Index 0x%08x\n", nvIndex);
232-
continue;
233242
}
234243

235244
/* Read data */
236-
XMEMSET(&nv, 0, sizeof(nv)); /* Must reset the NV for each read */
237-
XMEMSET(certBuf, 0, sizeof(certBuf));
238-
certSz = (uint32_t)sizeof(certBuf);
239-
if (certSz > nvPublic.dataSize) {
240-
certSz = nvPublic.dataSize;
241-
}
242-
rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, certBuf, &certSz, 0);
243245
if (rc == 0) {
244-
#ifdef DEBUG_WOLFTPM
245-
printf("EK Data: %d\n", certSz);
246-
TPM2_PrintBin(certBuf, certSz);
247-
#endif
246+
certSz = (uint32_t)sizeof(certBuf);
247+
if (certSz > nvPublic.dataSize) {
248+
certSz = nvPublic.dataSize;
249+
}
250+
rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, certBuf, &certSz, 0);
251+
if (rc == 0) {
252+
#ifdef DEBUG_WOLFTPM
253+
printf("EK Data: %d\n", certSz);
254+
TPM2_PrintBin(certBuf, certSz);
255+
#endif
256+
}
248257
}
249258

250259
/* Create Endorsement Key */
251-
if (rc == 0) {
252-
/* Get Endorsement Public Key template using NV index */
253-
rc = wolfTPM2_GetKeyTemplate_EKIndex(nvIndex, &publicTemplate);
254-
if (rc != 0) {
255-
printf("EK Index 0x%08x not valid\n", nvIndex);
256-
rc = BAD_FUNC_ARG;
257-
}
258-
}
259260
if (rc == 0) {
260261
/* Create Endorsement Key using EK auth policy */
261262
printf("Creating Endorsement Key\n");
@@ -324,12 +325,14 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
324325
}
325326
}
326327
else {
327-
printf("Error importing certificates public key! %d\n", rc);
328+
printf("Error importing certificates public key! %s (%d)\n",
329+
TPM2_GetRCString(rc), rc);
330+
rc = 0; /* ignore error */
328331
}
329332
}
330333
else {
331-
printf("Error parsing certificate 0x%x: %s\n",
332-
rc, TPM2_GetRCString(rc));
334+
printf("Error parsing certificate! %s (%d)\n",
335+
TPM2_GetRCString(rc), rc);
333336
}
334337
wc_FreeDecodedCert(&cert);
335338

@@ -345,8 +348,8 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
345348

346349
#ifdef WOLFSSL_DER_TO_PEM
347350
/* Convert certificate to PEM and display */
348-
rc = wc_DerToPemEx(certBuf, certSz, NULL, 0, NULL, CERT_TYPE);
349-
if (rc > 0) {
351+
rc = wc_DerToPem(certBuf, certSz, NULL, 0, CERT_TYPE);
352+
if (rc > 0) { /* returns actual PEM size */
350353
pemSz = (word32)rc;
351354
rc = 0;
352355

@@ -359,7 +362,8 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
359362
if (rc == 0) {
360363
XMEMSET(pem, 0, pemSz);
361364
rc = wc_DerToPem(certBuf, certSz, (byte*)pem, pemSz, CERT_TYPE);
362-
if (rc > 0) {
365+
if (rc > 0) { /* returns actual PEM size */
366+
pemSz = (word32)rc;
363367
rc = 0;
364368
}
365369
}

0 commit comments

Comments
 (0)