Skip to content

Commit

Permalink
Support for getting TPM EK Certificates. Fix TLS example build issues…
Browse files Browse the repository at this point in the history
… with wolfSSL not having crypto callback or PK callback enabled.
  • Loading branch information
dgarske committed Jul 5, 2024
1 parent fb7e321 commit ee67f17
Show file tree
Hide file tree
Showing 11 changed files with 344 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ examples/boot/secret_seal
examples/boot/secret_unseal
examples/firmware/ifx_fw_extract
examples/firmware/ifx_fw_update
examples/endorsement/get_ek_certs

# Generated Cert Files
certs/ca-*.pem
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Portable TPM 2.0 project designed for embedded use.
* Parameter encryption support using AES-CFB or XOR.
* Support for salted unbound authenticated sessions.
* Support for HMAC Sessions.
* Support for reading Endorsement certificates (EK Credential Profile).

Note: See [examples/README.md](examples/README.md) for details on using the examples.

Expand Down Expand Up @@ -168,7 +169,7 @@ make install
# then for some other library such as wolfTPM:

# cd /your-wolftpm-repo
./configure --enable-swtpm --with-wolfcrypt=~/workspace/my_wolfssl_bin
./configure --enable-swtpm --with-wolfcrypt=~/workspace/my_wolfssl_bin
```

### Build options and defines
Expand Down Expand Up @@ -825,7 +826,6 @@ Connection: close

## Todo

* Add support for Endorsement certificates (EK Credential Profile).
* Update to v1.59 of specification (adding CertifyX509).
* Inner wrap support for SensitiveToPrivate.
* Add support for IRQ (interrupt line)
Expand Down
35 changes: 35 additions & 0 deletions examples/endorsement/endorsement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* endorsement.h
*
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

#ifndef _WOLFTPM_ENDORSEMENT_H_
#define _WOLFTPM_ENDORSEMENT_H_

#ifdef __cplusplus
extern "C" {
#endif

int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[]);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* _WOLFTPM_ENDORSEMENT_H_ */
238 changes: 238 additions & 0 deletions examples/endorsement/get_ek_certs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/* get_ek_certs.c
*
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

/* This example shows how to decrypt a credential for Remote Attestation
* and extract the secret for challenge response to an attestation server
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <wolftpm/tpm2_wrap.h>

#include <stdio.h>

#ifndef WOLFTPM2_NO_WRAPPER

#include <examples/endorsement/endorsement.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>


/******************************************************************************/
/* --- BEGIN TPM2.0 Endorsement certificate tool -- */
/******************************************************************************/

#ifndef MAX_CERT_SZ
#define MAX_CERT_SZ 2048
#endif

static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/endorsement/get_ek_certs\n");
}

int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
{
int rc = -1, i;
WOLFTPM2_DEV dev;
TPML_HANDLE handles;
TPMS_NV_PUBLIC nvPublic;
WOLFTPM2_NV nv;
WOLFTPM2_KEY endorse;
uint8_t certBuf[MAX_CERT_SZ];
uint32_t certSz;
uint32_t keyBits;
TPM_ECC_CURVE curveID;
TPM_ALG_ID alg;
TPMT_PUBLIC publicTemplate;

XMEMSET(&endorse, 0, sizeof(endorse));
XMEMSET(&handles, 0, sizeof(handles));
XMEMSET(&nvPublic, 0, sizeof(nvPublic));

if (argc >= 2) {
if (XSTRCMP(argv[1], "-?") == 0 ||
XSTRCMP(argv[1], "-h") == 0 ||
XSTRCMP(argv[1], "--help") == 0) {
usage();
return 0;
}
}

printf("Get Endorsement Certificate(s)\n");

rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}

/* List TCG stored handles */
rc = wolfTPM2_GetHandles(TPM_20_TCG_NV_SPACE, &handles);
if (rc < 0) {
goto exit;
}
rc = 0;
printf("Found %d TCG handles\n", handles.count);

for (i=0; i<(int)handles.count; i++) {
word32 nvIndex = handles.handle[i];
printf("TCG Handle 0x%x\n", nvIndex);

/* Read Public portion of NV */
rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic);
if (rc != 0) {
printf("Failed to read public for NV Index 0x%08x\n", nvIndex);
continue;
}

/* Determine algorithm based on index */
switch (nvIndex) {
case TPM2_NV_RSA_EK_CERT: /* EK (Low Range): RSA 2048 */
case TPM2_NV_EK_RSA2048: /* EK (High Range) */
alg = TPM_ALG_RSA;
keyBits = 2048;
break;
case TPM2_NV_EK_RSA3072:
alg = TPM_ALG_RSA;
keyBits = 3072;
break;
case TPM2_NV_EK_RSA4096:
alg = TPM_ALG_RSA;
keyBits = 4096;
break;
case TPM2_NV_ECC_EK_CERT: /* EK (Low Range): ECC P256 */
case TPM2_NV_EK_ECC_P256: /* EK (High Range) */
alg = TPM_ALG_ECC;
curveID = TPM_ECC_NIST_P256;
keyBits = 256;
break;
case TPM2_NV_EK_ECC_P384:
alg = TPM_ALG_ECC;
curveID = TPM_ECC_NIST_P384;
keyBits = 384;
break;
case TPM2_NV_EK_ECC_P521:
alg = TPM_ALG_ECC;
curveID = TPM_ECC_NIST_P521;
keyBits = 521;
break;
case TPM2_NV_EK_ECC_SM2:
alg = TPM_ALG_SM2;
curveID = TPM_ECC_SM2_P256;
keyBits = 256;
break;
default:
alg = TPM_ALG_NULL;
keyBits = 0;
break;
}
printf("EK Algorithm: %s-%d\n", TPM2_GetAlgName(alg), keyBits);

/* Read certificate */
XMEMSET(&nv, 0, sizeof(nv)); /* Must reset the NV for each read */
XMEMSET(certBuf, 0, sizeof(certBuf));
certSz = (uint32_t)sizeof(certBuf);
if (certSz > nvPublic.dataSize) {
certSz = nvPublic.dataSize;
}
rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, certBuf, &certSz, 0);
if (rc == 0) {
#ifdef DEBUG_WOLFTPM
printf("EK Certificate: %d\n", certSz);
TPM2_PrintBin(certBuf, certSz);
#endif
}

#ifndef WOLFTPM2_NO_WOLFCRYPT
/* Attempt to parse certificate */

#endif

XMEMSET(&publicTemplate, 0, sizeof(publicTemplate));
if (alg == TPM_ALG_RSA) {
rc = wolfTPM2_GetKeyTemplate_RSA_EK(&publicTemplate);
if (rc == 0) {
/* Adjust for RSA key size */
publicTemplate.unique.rsa.size = keyBits / 8;
publicTemplate.parameters.rsaDetail.keyBits = keyBits;
}
}
else if (alg == TPM_ALG_ECC) {
rc = wolfTPM2_GetKeyTemplate_ECC_EK(&publicTemplate);
if (rc == 0) {
/* Adjust for curve */
publicTemplate.unique.ecc.x.size = keyBits / 8;
publicTemplate.unique.ecc.y.size = keyBits / 8;
publicTemplate.parameters.eccDetail.curveID = curveID;
}
}
else {
rc = BAD_FUNC_ARG;
}
if (rc == 0) {
/* Create Endorsement Key using EK auth policy */
printf("Creating Endorsement Key\n");
rc = wolfTPM2_CreatePrimaryKey(&dev, &endorse, TPM_RH_ENDORSEMENT,
&publicTemplate, NULL, 0);
if (rc != 0) goto exit;
printf("Endorsement key loaded at handle 0x%08x\n",
endorse.handle.hndl);
#ifdef DEBUG_WOLFTPM
TPM2_PrintPublicArea(&endorse.pub);
#endif

wolfTPM2_UnloadHandle(&dev, &endorse.handle);
}
}

exit:

wolfTPM2_UnloadHandle(&dev, &endorse.handle);
wolfTPM2_Cleanup(&dev);

return rc;
}

/******************************************************************************/
/* --- END TPM2.0 Endorsement certificate tool -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER */

#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = -1;

#ifndef WOLFTPM2_NO_WRAPPER
rc = TPM2_EndorsementCert_Example(NULL, argc, argv);
#else
printf("Wrapper code not compiled in\n");
(void)argc;
(void)argv;
#endif /* !WOLFTPM2_NO_WRAPPER */

return rc;
}
#endif
17 changes: 17 additions & 0 deletions examples/endorsement/include.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# vim:ft=automake
# All paths should be given relative to the root

if BUILD_EXAMPLES
noinst_HEADERS += examples/endorsement/endorsement.h

noinst_PROGRAMS += examples/endorsement/get_ek_certs
examples_endorsement_get_ek_certs_SOURCES = examples/endorsement/get_ek_certs.c
examples_endorsement_get_ek_certs_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_endorsement_get_ek_certs_DEPENDENCIES = src/libwolftpm.la
endif

example_endorsementdir = $(exampledir)/endorsement
dist_example_endorsement_DATA = \
examples/endorsement/get_ek_certs.c

DISTCLEANFILES+= examples/endorsement/.libs/get_ek_certs
1 change: 1 addition & 0 deletions examples/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ include examples/gpio/include.am
include examples/seal/include.am
include examples/attestation/include.am
include examples/firmware/include.am
include examples/endorsement/include.am

if BUILD_EXAMPLES
EXTRA_DIST += examples/run_examples.sh
Expand Down
Loading

0 comments on commit ee67f17

Please sign in to comment.