From f1e82ac0e47eee32fdd1f7d0555b12f30fcdf608 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 30 May 2018 10:18:31 -0700 Subject: [PATCH] Added PKCS7, CSR and TLS Client examples using the TPM. Added builtin wrapper support for `WOLF_CRYPT_DEV`, which enables wolfCrypt PK type callbacks for RSA and ECC. Moved some of the example configuration into `./examples/tpm_io.h`. TLS Client example is not complete. --- examples/bench/bench.c | 19 ++-- examples/csr/csr.c | 201 ++++++++++++++++++++++++++++++++++++++ examples/csr/csr.h | 28 ++++++ examples/csr/include.am | 14 +++ examples/include.am | 3 + examples/pkcs7/include.am | 14 +++ examples/pkcs7/pkcs7.c | 193 ++++++++++++++++++++++++++++++++++++ examples/pkcs7/pkcs7.h | 28 ++++++ examples/tls/include.am | 14 +++ examples/tls/tls_client.c | 182 ++++++++++++++++++++++++++++++++++ examples/tls/tls_client.h | 28 ++++++ examples/tpm_io.h | 10 ++ examples/wrap/wrap_test.c | 30 +++--- src/tpm2_wrap.c | 102 +++++++++++++++++++ wolftpm/tpm2_wrap.h | 19 ++++ 15 files changed, 863 insertions(+), 22 deletions(-) create mode 100644 examples/csr/csr.c create mode 100644 examples/csr/csr.h create mode 100644 examples/csr/include.am create mode 100644 examples/pkcs7/include.am create mode 100644 examples/pkcs7/pkcs7.c create mode 100644 examples/pkcs7/pkcs7.h create mode 100644 examples/tls/include.am create mode 100644 examples/tls/tls_client.c create mode 100644 examples/tls/tls_client.h diff --git a/examples/bench/bench.c b/examples/bench/bench.c index 01f8a87..3fc7774 100644 --- a/examples/bench/bench.c +++ b/examples/bench/bench.c @@ -31,7 +31,6 @@ #include /* Configuration */ -#define TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE 0x81000200 #define TPM2_BENCH_DURATION_SEC 1 @@ -90,8 +89,6 @@ int TPM2_Wrapper_Bench(void* userCtx) WOLFTPM2_BUFFER plain; TPMT_PUBLIC publicTemplate; TPM2B_ECC_POINT pubPoint; - const char storageKeyAuth[] = "ThisIsMyStorageKeyAuth"; - const char keyAuth[] = "ThisIsMyKeyAuth"; double start; int count; @@ -104,7 +101,7 @@ int TPM2_Wrapper_Bench(void* userCtx) /* See if primary storage key already exists */ rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, - TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); + TPM2_DEMO_STORAGE_KEY_HANDLE); if (rc != 0) { /* Create primary storage key */ rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, @@ -113,18 +110,18 @@ int TPM2_Wrapper_Bench(void* userCtx) TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); if (rc != 0) goto exit; rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, - &publicTemplate, (byte*)storageKeyAuth, sizeof(storageKeyAuth)-1); + &publicTemplate, (byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1); if (rc != 0) goto exit; /* Move this key into persistent storage */ rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, - TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); + TPM2_DEMO_STORAGE_KEY_HANDLE); if (rc != 0) goto exit; } else { /* specify auth password for storage key */ - storageKey.handle.auth.size = sizeof(storageKeyAuth)-1; - XMEMCPY(storageKey.handle.auth.buffer, storageKeyAuth, + storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1; + XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth, storageKey.handle.auth.size); } @@ -134,7 +131,7 @@ int TPM2_Wrapper_Bench(void* userCtx) TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, - &publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); if (rc != 0) goto exit; @@ -194,7 +191,7 @@ int TPM2_Wrapper_Bench(void* userCtx) TPM_ECC_NIST_P256, TPM_ALG_ECDSA); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, - &publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); if (rc != 0) goto exit; @@ -230,7 +227,7 @@ int TPM2_Wrapper_Bench(void* userCtx) TPM_ECC_NIST_P256, TPM_ALG_ECDH); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, - &publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); if (rc != 0) goto exit; /* Create ephemeral ECC key and generate a shared secret */ diff --git a/examples/csr/csr.c b/examples/csr/csr.c new file mode 100644 index 0000000..af1e9eb --- /dev/null +++ b/examples/csr/csr.c @@ -0,0 +1,201 @@ +/* csr.c + * + * Copyright (C) 2006-2018 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-1301, USA + */ + + +#include +#include + +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFSSL_CERT_REQ) && \ + defined(WOLF_CRYPTO_DEV) + +#include +#include +#include + +/******************************************************************************/ +/* --- BEGIN TPM2 CSR Example -- */ +/******************************************************************************/ + +int TPM2_CSR_Example(void* userCtx) +{ + int rc; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY storageKey; + WOLFTPM2_KEY rsaKey; + RsaKey wolfRsaKey; + TPMT_PUBLIC publicTemplate; + TpmCryptoDevCtx tpmCtx; + Cert req; + const CertName myCertName = { + "US", CTC_PRINTABLE, /* country */ + "Orgeon", CTC_UTF8, /* state */ + "Portland", CTC_UTF8, /* locality */ + "Test", CTC_UTF8, /* sur */ + "wolfSSL", CTC_UTF8, /* org */ + "Development", CTC_UTF8, /* unit */ + "www.wolfssl.com", CTC_UTF8, /* commonName */ + "info@wolfssl.com" /* email */ + }; + WOLFTPM2_BUFFER der; + WOLFTPM2_BUFFER output; + int tpmDevId; + + XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey)); + + printf("TPM2 CSR Example\n"); + + /* Init the TPM2 device */ + rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); + if (rc != 0) return rc; + + /* Setup the wolf crypto device callback */ + tpmCtx.rsaKey = &rsaKey; + rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); + if (rc != 0) goto exit; + + /* See if primary storage key already exists */ + rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, + TPM2_DEMO_STORAGE_KEY_HANDLE); + if (rc != 0) { + /* Create primary storage key */ + rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, + &publicTemplate, (byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1); + if (rc != 0) goto exit; + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, + TPM2_DEMO_STORAGE_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for storage key */ + storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1; + XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth, + storageKey.handle.auth.size); + } + + /* Create/Load RSA key for TLS authentication */ + rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_KEY_HANDLE); + if (rc != 0) { + rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); + if (rc != 0) goto exit; + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &rsaKey, + TPM2_DEMO_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for rsa key */ + rsaKey.handle.auth.size = sizeof(gKeyAuth)-1; + XMEMCPY(rsaKey.handle.auth.buffer, gKeyAuth, rsaKey.handle.auth.size); + } + + /* setup wolf RSA key with TPM deviceID, so crypto callbacks are used */ + rc = wc_InitRsaKey_ex(&wolfRsaKey, NULL, tpmDevId); + if (rc != 0) goto exit; + /* load public portion of key into wolf RSA Key */ + rc = wolfTPM2_RsaKey_TpmToWolf(&dev, &rsaKey, &wolfRsaKey); + if (rc != 0) goto exit; + + + /* Generate CSR (using TPM key) for certification authority */ + rc = wc_InitCert(&req); + if (rc != 0) goto exit; + + XMEMCPY(&req.subject, &myCertName, sizeof(myCertName)); + req.sigType = CTC_SHA256wRSA; + +#ifdef WOLFSSL_CERT_EXT + /* add SKID from the Public Key */ + rc = wc_SetSubjectKeyIdFromPublicKey_ex(&req, RSA_TYPE, &wolfRsaKey); + if (rc != 0) goto exit; + + /* add Extended Key Usage */ + rc = wc_SetExtKeyUsage(&req, "serverAuth,clientAuth,codeSigning," + "emailProtection,timeStamping,OCSPSigning"); + if (rc != 0) goto exit; +#endif + + rc = wc_MakeCertReq_ex(&req, der.buffer, sizeof(der.buffer), RSA_TYPE, &wolfRsaKey); + if (rc <= 0) goto exit; + der.size = rc; + + rc = wc_SignCert_ex(req.bodySz, req.sigType, der.buffer, sizeof(der.buffer), RSA_TYPE, + &wolfRsaKey, wolfTPM2_GetRng(&dev)); + if (rc <= 0) goto exit; + der.size = rc; + + /* Convert to PEM */ + rc = wc_DerToPem(der.buffer, der.size, output.buffer, sizeof(output.buffer), CERTREQ_TYPE); + if (rc <= 0) goto exit; + output.size = rc; + + printf("Generated/Signed Cert (DER %d, PEM %d)\n", der.size, output.size); + printf("%s\n", (char*)output.buffer); + + rc = 0; /* report success */ + +exit: + + if (rc != 0) { + printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); + } + + wc_FreeRsaKey(&wolfRsaKey); + wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); + + wolfTPM2_Cleanup(&dev); + + return rc; +} + +/******************************************************************************/ +/* --- END TPM2 CSR Example -- */ +/******************************************************************************/ + +#endif /* !WOLFTPM2_NO_WRAPPER && WOLFSSL_CERT_REQ && WOLF_CRYPTO_DEV */ + +#ifndef NO_MAIN_DRIVER +int main(void) +{ + int rc = -1; + +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFSSL_CERT_REQ) && \ + defined(WOLF_CRYPTO_DEV) + rc = TPM2_CSR_Example(TPM2_IoGetUserCtx()); +#else + printf("Wrapper/CertReq/CryptoDev code not compiled in\n"); +#endif + + return rc; +} +#endif /* !NO_MAIN_DRIVER */ diff --git a/examples/csr/csr.h b/examples/csr/csr.h new file mode 100644 index 0000000..6c95308 --- /dev/null +++ b/examples/csr/csr.h @@ -0,0 +1,28 @@ +/* csr.h + * + * Copyright (C) 2006-2018 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-1301, USA + */ + +#ifndef _TPM_CSR_EXAMPLE_H_ +#define _TPM_CSR_EXAMPLE_H_ + + +int TPM2_CSR_Example(void* userCtx); + +#endif /* _TPM_CSR_EXAMPLE_H_ */ diff --git a/examples/csr/include.am b/examples/csr/include.am new file mode 100644 index 0000000..22dccb4 --- /dev/null +++ b/examples/csr/include.am @@ -0,0 +1,14 @@ +# vim:ft=automake +# All paths should be given relative to the root + +if BUILD_EXAMPLES +noinst_PROGRAMS += examples/csr/csr +noinst_HEADERS += examples/csr/csr.h +examples_csr_csr_SOURCES = examples/csr/csr.c \ + examples/tpm_io.c +examples_csr_csr_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) +examples_csr_csr_DEPENDENCIES = src/libwolftpm.la +endif + +dist_example_DATA+= examples/csr/csr.c +DISTCLEANFILES+= examples/csr/.libs/csr diff --git a/examples/include.am b/examples/include.am index 9da164b..92842c7 100644 --- a/examples/include.am +++ b/examples/include.am @@ -4,6 +4,9 @@ include examples/native/include.am include examples/wrap/include.am include examples/bench/include.am +include examples/tls/include.am +include examples/csr/include.am +include examples/pkcs7/include.am dist_example_DATA+= examples/tpm_io.c \ examples/tpm_io.h diff --git a/examples/pkcs7/include.am b/examples/pkcs7/include.am new file mode 100644 index 0000000..689c7d4 --- /dev/null +++ b/examples/pkcs7/include.am @@ -0,0 +1,14 @@ +# vim:ft=automake +# All paths should be given relative to the root + +if BUILD_EXAMPLES +noinst_PROGRAMS += examples/pkcs7/pkcs7 +noinst_HEADERS += examples/pkcs7/pkcs7.h +examples_pkcs7_pkcs7_SOURCES = examples/pkcs7/pkcs7.c \ + examples/tpm_io.c +examples_pkcs7_pkcs7_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) +examples_pkcs7_pkcs7_DEPENDENCIES = src/libwolftpm.la +endif + +dist_example_DATA+= examples/pkcs7/pkcs7.c +DISTCLEANFILES+= examples/pkcs7/.libs/pkcs7 diff --git a/examples/pkcs7/pkcs7.c b/examples/pkcs7/pkcs7.c new file mode 100644 index 0000000..73746f3 --- /dev/null +++ b/examples/pkcs7/pkcs7.c @@ -0,0 +1,193 @@ +/* pkcs7.c + * + * Copyright (C) 2006-2018 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-1301, USA + */ + + +#include +#include + +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(HAVE_PKCS7) && \ + defined(WOLF_CRYPTO_DEV) + +#include +#include +#include + +/* force include test certs */ +#undef USE_CERT_BUFFERS_2048 +#define USE_CERT_BUFFERS_2048 +#include + +/******************************************************************************/ +/* --- BEGIN TPM2 PKCS7 Example -- */ +/******************************************************************************/ + +int TPM2_PKCS7_Example(void* userCtx) +{ + int rc; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY storageKey; + WOLFTPM2_KEY rsaKey; + TPMT_PUBLIC publicTemplate; + TpmCryptoDevCtx tpmCtx; + RsaKey wolfRsaKey; + PKCS7 pkcs7; + byte data[] = "My encoded DER cert."; + int tpmDevId; + WOLFTPM2_BUFFER der; + WOLFTPM2_BUFFER output; + + XMEMSET(&pkcs7, 0, sizeof(pkcs7)); + XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey)); + + printf("TPM2 PKCS7 Example\n"); + + /* Init the TPM2 device */ + rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); + if (rc != 0) return rc; + + /* Setup the wolf crypto device callback */ + tpmCtx.rsaKey = &rsaKey; + rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); + if (rc < 0) goto exit; + + /* See if primary storage key already exists */ + rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, + TPM2_DEMO_STORAGE_KEY_HANDLE); + if (rc != 0) { + /* Create primary storage key */ + rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, + &publicTemplate, (byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1); + if (rc != 0) goto exit; + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, + TPM2_DEMO_STORAGE_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for storage key */ + storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1; + XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth, + storageKey.handle.auth.size); + } + + /* Create/Load RSA key for TLS authentication */ + rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_KEY_HANDLE); + if (rc != 0) { + rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); + if (rc != 0) goto exit; + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &rsaKey, + TPM2_DEMO_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for rsa key */ + rsaKey.handle.auth.size = sizeof(gKeyAuth)-1; + XMEMCPY(rsaKey.handle.auth.buffer, gKeyAuth, rsaKey.handle.auth.size); + } + + /* setup wolf RSA key with TPM deviceID, so crypto callbacks are used */ + rc = wc_InitRsaKey_ex(&wolfRsaKey, NULL, tpmDevId); + if (rc != 0) goto exit; + /* load public portion of key into wolf RSA Key */ + rc = wolfTPM2_RsaKey_TpmToWolf(&dev, &rsaKey, &wolfRsaKey); + if (rc != 0) goto exit; + + + /* Generate and verify PKCS#7 files containing data using TPM key */ + XMEMCPY(der.buffer, client_cert_der_2048, sizeof_client_cert_der_2048); + der.size = sizeof_client_cert_der_2048; + + rc = wc_PKCS7_InitWithCert(&pkcs7, der.buffer, der.size); + if (rc != 0) goto exit; + + pkcs7.content = data; + pkcs7.contentSz = (word32)sizeof(data); + pkcs7.encryptOID = RSAk; + pkcs7.hashOID = SHA256h; + pkcs7.rng = wolfTPM2_GetRng(&dev); + pkcs7.devId = tpmDevId; + + rc = wc_PKCS7_EncodeSignedData(&pkcs7, output.buffer, sizeof(output.buffer)); + if (rc <= 0) goto exit; + wc_PKCS7_Free(&pkcs7); + output.size = rc; + + + printf("PKCS7 Signed Container %d\n", output.size); + TPM2_PrintBin(output.buffer, output.size); + + /* Test verify */ + rc = wc_PKCS7_InitWithCert(&pkcs7, NULL, 0); + if (rc != 0) goto exit; + rc = wc_PKCS7_VerifySignedData(&pkcs7, output.buffer, output.size); + if (rc != 0) goto exit; + wc_PKCS7_Free(&pkcs7); + + printf("PKCS7 Container Verified\n"); + +exit: + + if (rc != 0) { + printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); + } + + wc_FreeRsaKey(&wolfRsaKey); + wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); + + wolfTPM2_Cleanup(&dev); + + return rc; +} + +/******************************************************************************/ +/* --- END TPM2 PKCS7 Example -- */ +/******************************************************************************/ + +#endif /* !WOLFTPM2_NO_WRAPPER && HAVE_PKCS7 && WOLF_CRYPTO_DEV */ + +#ifndef NO_MAIN_DRIVER +int main(void) +{ + int rc = -1; + +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(HAVE_PKCS7) && \ + defined(WOLF_CRYPTO_DEV) + rc = TPM2_PKCS7_Example(TPM2_IoGetUserCtx()); +#else + printf("Wrapper/PKCS7/CryptoDev code not compiled in\n"); +#endif + + return rc; +} +#endif /* !NO_MAIN_DRIVER */ diff --git a/examples/pkcs7/pkcs7.h b/examples/pkcs7/pkcs7.h new file mode 100644 index 0000000..8bc84ea --- /dev/null +++ b/examples/pkcs7/pkcs7.h @@ -0,0 +1,28 @@ +/* pkcs7.h + * + * Copyright (C) 2006-2018 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-1301, USA + */ + +#ifndef _TPM_PKCS7_EXAMPLE_H_ +#define _TPM_PKCS7_EXAMPLE_H_ + + +int TPM2_PKCS7_Example(void* userCtx); + +#endif /* _TPM_PKCS7_EXAMPLE_H_ */ diff --git a/examples/tls/include.am b/examples/tls/include.am new file mode 100644 index 0000000..7b76ad7 --- /dev/null +++ b/examples/tls/include.am @@ -0,0 +1,14 @@ +# vim:ft=automake +# All paths should be given relative to the root + +if BUILD_EXAMPLES +noinst_PROGRAMS += examples/tls/tls_client +noinst_HEADERS += examples/tls/tls_client.h +examples_tls_tls_client_SOURCES = examples/tls/tls_client.c \ + examples/tpm_io.c +examples_tls_tls_client_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) +examples_tls_tls_client_DEPENDENCIES = src/libwolftpm.la +endif + +dist_example_DATA+= examples/tls/tls_client.c +DISTCLEANFILES+= examples/tls/.libs/tls_client diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c new file mode 100644 index 0000000..35fa637 --- /dev/null +++ b/examples/tls/tls_client.c @@ -0,0 +1,182 @@ +/* tls_client.c + * + * Copyright (C) 2006-2018 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-1301, USA + */ + + +#include +#include + +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) && \ + defined(HAVE_PK_CALLBACKS) + +#include +#include + +/******************************************************************************/ +/* --- BEGIN TLS Client Example -- */ +/******************************************************************************/ + +int TPM2_TLS_Client(void* userCtx) +{ + int rc; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY storageKey; + WOLFTPM2_KEY rsaKey; + WOLFTPM2_KEY eccKey; + RsaKey wolfTlsRsaKey; + WOLFTPM2_BUFFER cert; + TPMT_PUBLIC publicTemplate; + TPMS_NV_PUBLIC nvPublic; + TpmCryptoDevCtx tpmCtx; + int tpmDevId; + + XMEMSET(&wolfTlsRsaKey, 0, sizeof(wolfTlsRsaKey)); + + printf("TPM2 TLS Client Example\n"); + + /* Init the TPM2 device */ + rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); + if (rc != 0) return rc; + + /* Setup the wolf crypto device callback */ + rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); + if (rc != 0) goto exit; + + /* See if primary storage key already exists */ + rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, + TPM2_DEMO_STORAGE_KEY_HANDLE); + if (rc != 0) { + /* Create primary storage key */ + rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, + TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent | + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, + &publicTemplate, (byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1); + if (rc != 0) goto exit; + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, + TPM2_DEMO_STORAGE_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for storage key */ + storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1; + XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth, + storageKey.handle.auth.size); + } + + /* Create/Load RSA key for TLS authentication */ + rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_KEY_HANDLE); + if (rc != 0) { + rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); + if (rc != 0) goto exit; + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &rsaKey, + TPM2_DEMO_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for rsa key */ + rsaKey.handle.auth.size = sizeof(gKeyAuth)-1; + XMEMCPY(rsaKey.handle.auth.buffer, gKeyAuth, rsaKey.handle.auth.size); + } + + /* setup wolf RSA key with TPM deviceID, so crypto callbacks are used */ + rc = wc_InitRsaKey_ex(&wolfTlsRsaKey, NULL, tpmDevId); + if (rc != 0) goto exit; + /* load public portion of key into wolf RSA Key */ + rc = wolfTPM2_RsaKey_TpmToWolf(&dev, &rsaKey, &wolfTlsRsaKey); + if (rc != 0) goto exit; + + + /* Load Certificate from NV */ + rc = wolfTPM2_NVReadPublic(&dev, TPM2_DEMO_CERT_HANDLE, &nvPublic); + if (rc != 0 && rc != TPM_RC_HANDLE) goto exit; + if (rc == TPM_RC_HANDLE) { + /* need to create/load certificate */ + word32 nvAttributes = 0; + rc = wolfTPM2_GetNvAttributesTemplate(TPM_RH_OWNER, &nvAttributes); + if (rc != 0) goto exit; + rc = wolfTPM2_NVCreate(&dev, TPM_RH_OWNER, TPM2_DEMO_CERT_HANDLE, + nvAttributes, 1024, NULL, 0); + if (rc != 0 && rc != TPM_RC_NV_DEFINED) goto exit; + + cert.size = 256; /* TODO: Populate with real cert */ + XMEMSET(cert.buffer, 0x11, cert.size); + rc = wolfTPM2_NVWrite(&dev, TPM_RH_OWNER, TPM2_DEMO_CERT_HANDLE, + cert.buffer, cert.size, 0); + if (rc != 0) goto exit; + } + else { + cert.size = nvPublic.dataSize; + rc = wolfTPM2_NVRead(&dev, TPM_RH_OWNER, TPM2_DEMO_CERT_HANDLE, + cert.buffer, (word32*)&cert.size, 0); + if (rc != 0) goto exit; + } + + + /* DO TLS */ + + +exit: + + if (rc != 0) { + printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); + } + + wc_FreeRsaKey(&wolfTlsRsaKey); + wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); + wolfTPM2_UnloadHandle(&dev, &eccKey.handle); + + wolfTPM2_Cleanup(&dev); + + return rc; +} + +/******************************************************************************/ +/* --- END TLS Client Example -- */ +/******************************************************************************/ + +#endif /* !WOLFTPM2_NO_WRAPPER && WOLF_CRYPTO_DEV && HAVE_PK_CALLBACKS */ + +#ifndef NO_MAIN_DRIVER +int main(void) +{ + int rc = -1; + +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) && \ + defined(HAVE_PK_CALLBACKS) + rc = TPM2_TLS_Client(TPM2_IoGetUserCtx()); +#else + printf("Wrapper/CryptoDev/PkCb code not compiled in\n"); +#endif + + return rc; +} +#endif /* !NO_MAIN_DRIVER */ diff --git a/examples/tls/tls_client.h b/examples/tls/tls_client.h new file mode 100644 index 0000000..c071f82 --- /dev/null +++ b/examples/tls/tls_client.h @@ -0,0 +1,28 @@ +/* tls_client.h + * + * Copyright (C) 2006-2018 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-1301, USA + */ + +#ifndef _TPM_TLS_CLIENT_H_ +#define _TPM_TLS_CLIENT_H_ + + +int TPM2_TLS_Client(void* userCtx); + +#endif /* _TPM_TLS_CLIENT_H_ */ diff --git a/examples/tpm_io.h b/examples/tpm_io.h index 1454c52..6f75ed0 100644 --- a/examples/tpm_io.h +++ b/examples/tpm_io.h @@ -24,6 +24,16 @@ #include +/* Configuration */ +#define TPM2_DEMO_STORAGE_KEY_HANDLE 0x81000200 /* Persistent Storage Key Handle */ +#define TPM2_DEMO_IDX 0x20 /* offset handle to unused index */ +#define TPM2_DEMO_KEY_HANDLE (0x81000000 + TPM2_DEMO_IDX) /* Persistent Key Handle */ +#define TPM2_DEMO_CERT_HANDLE (0x01800000 + TPM2_DEMO_IDX) /* NV Handle */ + +static const char gStorageKeyAuth[] = "ThisIsMyStorageKeyAuth"; +static const char gKeyAuth[] = "ThisIsMyKeyAuth"; + +/* TPM2 IO Examples */ void* TPM2_IoGetUserCtx(void); int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, word16 xferSz, void* userCtx); diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index f42fe3d..3a602f4 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -30,7 +30,6 @@ #include /* Configuration */ -#define TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE 0x81000200 #define TPM2_DEMO_NV_TEST_INDEX 0x01800200 #define TPM2_DEMO_NV_TEST_SIZE 1024 /* max size on Infineon SLB9670 is 1664 */ //#define WOLFTPM_TEST_WITH_RESET @@ -102,9 +101,10 @@ int TPM2_Wrapper_Test(void* userCtx) WOLFTPM2_BUFFER plain; TPMT_PUBLIC publicTemplate; TPM2B_ECC_POINT pubPoint; - const char storageKeyAuth[] = "ThisIsMyStorageKeyAuth"; - const char keyAuth[] = "ThisIsMyKeyAuth"; word32 nvAttributes = 0; +#ifdef WOLF_CRYPTO_DEV + TpmCryptoDevCtx tpmCtx; +#endif int tpmDevId = INVALID_DEVID; #ifndef NO_RSA word32 idx = 0; @@ -132,6 +132,14 @@ int TPM2_Wrapper_Test(void* userCtx) rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); if (rc != 0) return rc; +#ifdef WOLF_CRYPTO_DEV + /* Setup the wolf crypto device callback */ + tpmCtx.rsaKey = &rsaKey; + tpmCtx.eccKey = &eccKey; + rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); + if (rc != 0) goto exit; +#endif + #ifdef WOLFTPM_TEST_WITH_RESET /* reset all content on TPM and reseed */ rc = wolfTPM2_Clear(&dev); @@ -156,7 +164,7 @@ int TPM2_Wrapper_Test(void* userCtx) /* See if primary storage key already exists */ rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, - TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); + TPM2_DEMO_STORAGE_KEY_HANDLE); if (rc != 0) { /* Create primary storage key */ rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, @@ -165,18 +173,18 @@ int TPM2_Wrapper_Test(void* userCtx) TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); if (rc != 0) goto exit; rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, - &publicTemplate, (byte*)storageKeyAuth, sizeof(storageKeyAuth)-1); + &publicTemplate, (byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1); if (rc != 0) goto exit; /* Move this key into persistent storage */ rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, - TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); + TPM2_DEMO_STORAGE_KEY_HANDLE); if (rc != 0) goto exit; } else { /* specify auth password for storage key */ - storageKey.handle.auth.size = sizeof(storageKeyAuth)-1; - XMEMCPY(storageKey.handle.auth.buffer, storageKeyAuth, + storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1; + XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth, storageKey.handle.auth.size); } @@ -186,7 +194,7 @@ int TPM2_Wrapper_Test(void* userCtx) TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, - &publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); if (rc != 0) goto exit; @@ -264,7 +272,7 @@ int TPM2_Wrapper_Test(void* userCtx) TPM_ECC_NIST_P256, TPM_ALG_ECDSA); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, - &publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); if (rc != 0) goto exit; /* Perform sign / verify */ @@ -292,7 +300,7 @@ int TPM2_Wrapper_Test(void* userCtx) TPM_ECC_NIST_P256, TPM_ALG_ECDH); if (rc != 0) goto exit; rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, - &publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); if (rc != 0) goto exit; /* Create ephemeral ECC key and generate a shared secret */ diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 82dd8e3..fef923d 100755 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -1388,4 +1388,106 @@ int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes) /* --- END Utility Functions -- */ /******************************************************************************/ + +#ifdef WOLF_CRYPTO_DEV +/******************************************************************************/ +/* --- BEGIN wolf Crypto Device Support -- */ +/******************************************************************************/ + +int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) +{ + int ret = NOT_COMPILED_IN; /* return this to bypass HW and use SW */ + TpmCryptoDevCtx* tlsCtx = (TpmCryptoDevCtx*)ctx; + + if (info == NULL || ctx == NULL || tlsCtx->dev == NULL) + return BAD_FUNC_ARG; + + (void)devId; + +#ifndef NO_RSA + /* RSA */ + if (info->algo_type == WC_ALGO_TYPE_PK && info->pk.type == WC_PK_TYPE_RSA) { + switch (info->pk.rsa.type) { + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: + /* public operations */ + ret = wolfTPM2_RsaEncrypt(tlsCtx->dev, tlsCtx->rsaKey, TPM_ALG_NULL, + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, (int*)info->pk.rsa.outLen); + break; + case RSA_PRIVATE_ENCRYPT: + case RSA_PRIVATE_DECRYPT: + /* private operations */ + ret = wolfTPM2_RsaDecrypt(tlsCtx->dev, tlsCtx->rsaKey, TPM_ALG_NULL, + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, (int*)info->pk.rsa.outLen); + break; + } + + /* need to return negative here for error */ + if (ret != TPM_RC_SUCCESS) + ret = RSA_BUFFER_E; + } +#endif /* !NO_RSA */ +#ifdef HAVE_ECC + if (info->algo_type == WC_ALGO_TYPE_PK && + info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + ret = wolfTPM2_SignHash(tlsCtx->dev, tlsCtx->eccKey, + info->pk.eccsign.in, info->pk.eccsign.inlen, + info->pk.eccsign.out, (int*)info->pk.eccsign.outlen); + } + else if (info->algo_type == WC_ALGO_TYPE_PK && + info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + ret = wolfTPM2_VerifyHash(tlsCtx->dev, tlsCtx->eccKey, + info->pk.eccverify.sig, info->pk.eccverify.siglen, + info->pk.eccverify.hash, info->pk.eccverify.hashlen); + } + else if (info->algo_type == WC_ALGO_TYPE_PK && + info->pk.type == WC_PK_TYPE_ECDH) { + /* TODO: */ + #if 0 + ecc_key* private_key; + ecc_key* public_key; + byte* out; + word32* outlen; + #endif + } +#endif + + return ret; +} + +int wolfTPM2_SetCryptoDevCb(WOLFTPM2_DEV* dev, CryptoDevCallbackFunc cb, + TpmCryptoDevCtx* tpmCtx, int* pDevId) +{ + int rc; + int devId = INVALID_DEVID; + + if (dev == NULL || cb == NULL || tpmCtx == NULL) { + return BAD_FUNC_ARG; + } + + /* register a crypto device callback for TPM private key */ + rc = wolfTPM2_GetTpmDevId(dev); + if (rc < 0) { + devId = rc; + tpmCtx->dev = dev; + + rc = wc_CryptoDev_RegisterDevice(devId, cb, tpmCtx); + } + + if (pDevId) { + *pDevId = devId; + } + + return rc; +} + +/******************************************************************************/ +/* --- END wolf Crypto Device Support -- */ +/******************************************************************************/ + +#endif /* WOLF_CRYPTO_DEV */ + + #endif /* !WOLFTPM2_NO_WRAPPER */ diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 6cf74c8..6967117 100755 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -156,4 +156,23 @@ WOLFTPM_API int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttr #define wolfTPM2_GetCurveSize TPM2_GetCurveSize + +#ifdef WOLF_CRYPTO_DEV +typedef struct TpmCryptoDevCtx { + WOLFTPM2_DEV* dev; +#ifndef NO_RSA + WOLFTPM2_KEY* rsaKey; /* RSA */ +#endif +#ifdef HAVE_ECC + WOLFTPM2_KEY* eccKey; /* ECDSA */ + WOLFTPM2_KEY* ecdhKey; /* ECDH */ +#endif +} TpmCryptoDevCtx; + +WOLFTPM_API int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx); +WOLFTPM_API int wolfTPM2_SetCryptoDevCb(WOLFTPM2_DEV* dev, CryptoDevCallbackFunc cb, + TpmCryptoDevCtx* tpmCtx, int* pDevId); +#endif + + #endif /* __TPM2_WRAP_H__ */