From f1e82ac0e47eee32fdd1f7d0555b12f30fcdf608 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 30 May 2018 10:18:31 -0700 Subject: [PATCH 01/11] 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 01f8a87e..3fc7774c 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 00000000..af1e9ebf --- /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 00000000..6c95308e --- /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 00000000..22dccb44 --- /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 9da164be..92842c7f 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 00000000..689c7d49 --- /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 00000000..73746f37 --- /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 00000000..8bc84ea0 --- /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 00000000..7b76ad7a --- /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 00000000..35fa6379 --- /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 00000000..c071f82e --- /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 1454c525..6f75ed0b 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 f42fe3df..3a602f4d 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 82dd8e32..fef923d1 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 6cf74c88..69671178 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__ */ From d489452d53273662d692383fdb6c7fdb84f5ca8a Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 30 May 2018 10:24:20 -0700 Subject: [PATCH 02/11] Updates to TPM based TLS Client example. Added CSR generation of an ECC Certificate. Added scripts to help with making certificates from the CSR. TLS still has some outstanding work for ECDHE. --- Makefile.am | 1 + certs/ca-ecc.cnf | 109 ++++++++++ certs/ca-rsa.cnf | 109 ++++++++++ certs/certreq.sh | 61 ++++++ certs/include.am | 9 + certs/wolfssl-website-ca.pem | 70 ++++++ examples/csr/csr.c | 184 ++++++++++++---- examples/pkcs7/pkcs7.c | 5 +- examples/tls/tls_client.c | 406 +++++++++++++++++++++++++++++++---- examples/tpm_io.h | 11 +- src/tpm2_wrap.c | 133 +++++++----- wolftpm/tpm2.h | 3 + 12 files changed, 964 insertions(+), 137 deletions(-) create mode 100644 certs/ca-ecc.cnf create mode 100644 certs/ca-rsa.cnf create mode 100755 certs/certreq.sh create mode 100644 certs/include.am create mode 100644 certs/wolfssl-website-ca.pem diff --git a/Makefile.am b/Makefile.am index c10df315..1bfe3960 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,7 @@ include src/include.am include wolftpm/include.am include examples/include.am include IDE/include.am +include certs/include.am EXTRA_DIST+= README.md EXTRA_DIST+= LICENSE diff --git a/certs/ca-ecc.cnf b/certs/ca-ecc.cnf new file mode 100644 index 00000000..dfa12620 --- /dev/null +++ b/certs/ca-ecc.cnf @@ -0,0 +1,109 @@ +[ ca ] +# `man ca` +default_ca = CA_default + +[ CA_default ] +# Directory and file locations. +dir = . +certs = $dir/certs +new_certs_dir = $dir/certs +database = $dir/certs/index.txt +serial = $dir/certs/serial +RANDFILE = $dir/private/.rand + +# The root key and root certificate. +private_key = $dir/certs/ca-ecc-key.pem +certificate = $dir/certs/ca-ecc-cert.pem + +# For certificate revocation lists. +crlnumber = $dir/certs/crlnumber +crl_extensions = crl_ext +default_crl_days = 1000 + +# SHA-1 is deprecated, so use SHA-2 instead. +default_md = sha256 + +name_opt = ca_default +cert_opt = ca_default +default_days = 3650 +preserve = no +policy = policy_loose + + +[ policy_strict ] +# The root CA should only sign intermediate certificates that match. +# See the POLICY FORMAT section of `man ca`. +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_loose ] +# Allow the intermediate CA to sign a more diverse range of certificates. +# See the POLICY FORMAT section of the `ca` man page. +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +# Options for the `req` tool (`man req`). +default_bits = 2048 +distinguished_name = req_distinguished_name +string_mask = utf8only + +# SHA-1 is deprecated, so use SHA-2 instead. +default_md = sha256 + +# Extension to add when the -x509 option is used. +x509_extensions = v3_ca + +[ req_distinguished_name ] +countryName = US +stateOrProvinceName = Washington +localityName = Seattle +0.organizationName = wolfSSL +organizationalUnitName = Development +commonName = www.wolfssl.com +emailAddress = info@wolfssl.com + +[ v3_ca ] +# Extensions for a typical CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ usr_cert ] +# Extensions for client certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = client, email +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, emailProtection + +[ server_cert ] +# Extensions for server certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = server +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment, keyAgreement +extendedKeyUsage = serverAuth + +[ crl_ext ] +# Extension for CRLs (`man x509v3_config`). +authorityKeyIdentifier=keyid:always diff --git a/certs/ca-rsa.cnf b/certs/ca-rsa.cnf new file mode 100644 index 00000000..2c7cea4e --- /dev/null +++ b/certs/ca-rsa.cnf @@ -0,0 +1,109 @@ +[ ca ] +# `man ca` +default_ca = CA_default + +[ CA_default ] +# Directory and file locations. +dir = . +certs = $dir/certs +new_certs_dir = $dir/certs +database = $dir/certs/index.txt +serial = $dir/certs/serial +RANDFILE = $dir/private/.rand + +# The root key and root certificate. +private_key = $dir/certs/ca-rsa-key.pem +certificate = $dir/certs/ca-rsa-cert.pem + +# For certificate revocation lists. +crlnumber = $dir/certs/crlnumber +crl_extensions = crl_ext +default_crl_days = 1000 + +# SHA-1 is deprecated, so use SHA-2 instead. +default_md = sha256 + +name_opt = ca_default +cert_opt = ca_default +default_days = 3650 +preserve = no +policy = policy_loose + + +[ policy_strict ] +# The root CA should only sign intermediate certificates that match. +# See the POLICY FORMAT section of `man ca`. +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_loose ] +# Allow the intermediate CA to sign a more diverse range of certificates. +# See the POLICY FORMAT section of the `ca` man page. +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +# Options for the `req` tool (`man req`). +default_bits = 2048 +distinguished_name = req_distinguished_name +string_mask = utf8only + +# SHA-1 is deprecated, so use SHA-2 instead. +default_md = sha256 + +# Extension to add when the -x509 option is used. +x509_extensions = v3_ca + +[ req_distinguished_name ] +countryName = US +stateOrProvinceName = Washington +localityName = Seattle +0.organizationName = wolfSSL +organizationalUnitName = Development +commonName = www.wolfssl.com +emailAddress = info@wolfssl.com + +[ v3_ca ] +# Extensions for a typical CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ usr_cert ] +# Extensions for client certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = client, email +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, emailProtection + +[ server_cert ] +# Extensions for server certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = server +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment, keyAgreement +extendedKeyUsage = serverAuth + +[ crl_ext ] +# Extension for CRLs (`man x509v3_config`). +authorityKeyIdentifier=keyid:always diff --git a/certs/certreq.sh b/certs/certreq.sh new file mode 100755 index 00000000..9f267e5f --- /dev/null +++ b/certs/certreq.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +echo Run from wolftpm root +echo Run ./examples/crl/crl first to generate the CSR + + +# Make sure required CA files exist and are populated +rm ./certs/index.txt +touch ./certs/index.txt +if [ ! -f ./certs/serial ]; then + echo 1000 > ./certs/serial +fi +if [ ! -f ./certs/crlnumber ]; then + echo 2000 > ./certs/crlnumber +fi + + +# Generate RSA 2048-bit CA +if [ ! -f ./certs/ca-rsa-key.pem ]; then + openssl req -new -newkey rsa:2048 -keyout ./certs/ca-rsa-key.pem -nodes -out ./certs/ca-rsa-cert.csr -subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com" + openssl x509 -req -in ./certs/ca-rsa-cert.csr -days 1000 -extfile ./certs/ca-rsa.cnf -extensions v3_ca -signkey ./certs/ca-rsa-key.pem -out ./certs/ca-rsa-cert.pem + rm ./certs/ca-rsa-cert.csr + + openssl x509 -in ./certs/ca-rsa-cert.pem -inform PEM -out ./certs/ca-rsa-cert.der -outform DER + openssl rsa -in ./certs/ca-rsa-key.pem -inform PEM -out ./certs/ca-rsa-key.der -outform DER + + # generate CRL + openssl ca -config ./certs/ca-rsa.cnf -gencrl -crldays 1000 -out ./certs/ca-rsa.crl -keyfile ./certs/ca-rsa-key.pem -cert ./certs/ca-rsa-cert.pem +fi + +# Sign RSA certificate +if [ -f ./certs/client-rsa-cert.csr ]; then + openssl ca -config ./certs/ca-rsa.cnf -extensions usr_cert -days 3650 -notext -md sha256 -in ./certs/client-rsa-cert.csr -out ./certs/client-rsa-cert.pem + openssl x509 -in ./certs/client-rsa-cert.pem -outform der -out ./certs/client-rsa-cert.der +fi + + +# Generate ECC 256-bit CA +if [ ! -f ./certs/ca-rsa-key.pem ]; then + openssl ecparam -out ./certs/ca-ecc-key.par -name prime256v1 + openssl req -config ./certs/ca-ecc.cnf -extensions v3_ca -x509 -nodes -newkey ec:./certs/ca-ecc-key.par -keyout ./certs/ca-ecc-key.pem -out ./certs/ca-ecc-cert.pem -sha256 -days 7300 -batch -subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com" + rm ./certs/ca-ecc-key.par + + openssl x509 -in ./certs/ca-ecc-cert.pem -inform PEM -out ./certs/ca-ecc-cert.der -outform DER + openssl ec -in ./certs/ca-ecc-key.pem -inform PEM -out ./certs/ca-ecc-key.der -outform DER + + # generate CRL + openssl ca -config ./certs/ca-ecc.cnf -gencrl -crldays 1000 -out ./certs/ca-ecc.crl -keyfile ./certs/ca-ecc-key.pem -cert ./certs/ca-ecc-cert.pem +fi + + +# Sign ECC Certificate +if [ -f ./certs/client-ecc-cert.csr ]; then + # NOT APPLICABLE BECAUSE PRIVATE KEY IS IN TPM + #openssl ecparam -out ./certs/client-ecc-key.par -name prime256v1 + #openssl req -config ./certs/ca-ecc.cnf -sha256 -new -newkey ec:./certs/client-ecc-key.par -keyout ./certs/client-ecc-key.pem -out ./certs/client-ecc-cert.csr -subj "/C=US/ST=Washington/L=Seattle/O=Eliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=info@wolfssl.com/" + #rm ./certs/client-ecc-key.par + + openssl ca -config ./certs/ca-ecc.cnf -extensions usr_cert -days 3650 -notext -md sha256 -in ./certs/client-ecc-cert.csr -out ./certs/client-ecc-cert.pem + openssl x509 -in ./certs/client-ecc-cert.pem -outform der -out ./certs/client-ecc-cert.der +fi diff --git a/certs/include.am b/certs/include.am new file mode 100644 index 00000000..67500d7e --- /dev/null +++ b/certs/include.am @@ -0,0 +1,9 @@ +# vim:ft=automake +# All paths should be given relative to the root +# + +EXTRA_DIST += \ + certs/certreq.sh \ + certs/ca-rsa.cnf \ + certs/ca-ecc.cnf \ + certs/wolfssl-website-ca.pem diff --git a/certs/wolfssl-website-ca.pem b/certs/wolfssl-website-ca.pem new file mode 100644 index 00000000..80763702 --- /dev/null +++ b/certs/wolfssl-website-ca.pem @@ -0,0 +1,70 @@ +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- diff --git a/examples/csr/csr.c b/examples/csr/csr.c index af1e9ebf..f3005a72 100644 --- a/examples/csr/csr.c +++ b/examples/csr/csr.c @@ -30,19 +30,17 @@ #include #include +static const char gClientCertRsaFile[] = "./certs/client-rsa-cert.csr"; +static const char gClientCertEccFile[] = "./certs/client-ecc-cert.csr"; + /******************************************************************************/ /* --- BEGIN TPM2 CSR Example -- */ /******************************************************************************/ -int TPM2_CSR_Example(void* userCtx) -{ + static int TPM2_CSR_Generate(WOLFTPM2_DEV* dev, int key_type, void* wolfKey, + const char* outputPemFile) + { 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 */ @@ -54,11 +52,90 @@ int TPM2_CSR_Example(void* userCtx) "www.wolfssl.com", CTC_UTF8, /* commonName */ "info@wolfssl.com" /* email */ }; + const char* myKeyUsage = "serverAuth,clientAuth,codeSigning," + "emailProtection,timeStamping,OCSPSigning"; WOLFTPM2_BUFFER der; WOLFTPM2_BUFFER output; - int tpmDevId; - XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey)); + /* Generate CSR (using TPM key) for certification authority */ + rc = wc_InitCert(&req); + if (rc != 0) goto exit; + + XMEMCPY(&req.subject, &myCertName, sizeof(myCertName)); + + if (key_type == RSA_TYPE) + req.sigType = CTC_SHA256wRSA; + else if (key_type == ECC_TYPE) + req.sigType = CTC_SHA256wECDSA; + +#ifdef WOLFSSL_CERT_EXT + /* add SKID from the Public Key */ + rc = wc_SetSubjectKeyIdFromPublicKey_ex(&req, key_type, wolfKey); + if (rc != 0) goto exit; + + /* add Extended Key Usage */ + rc = wc_SetExtKeyUsage(&req, myKeyUsage); + if (rc != 0) goto exit; +#endif + + rc = wc_MakeCertReq_ex(&req, der.buffer, sizeof(der.buffer), key_type, + wolfKey); + if (rc <= 0) goto exit; + der.size = rc; + + rc = wc_SignCert_ex(req.bodySz, req.sigType, der.buffer, sizeof(der.buffer), + key_type, wolfKey, wolfTPM2_GetRng(dev)); + if (rc <= 0) goto exit; + der.size = rc; + +#ifdef WOLFSSL_DER_TO_PEM + /* Convert to PEM */ + XMEMSET(output.buffer, 0, sizeof(output.buffer)); + 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); + +#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) + { + FILE* pemFile = fopen(outputPemFile, "wb"); + if (pemFile) { + rc = (int)fwrite(output.buffer, 1, output.size, pemFile); + if (rc != output.size) { + rc = -1; goto exit; + } + fclose(pemFile); + } + } +#endif +#endif /* WOLFSSL_DER_TO_PEM */ + (void)outputPemFile; + + rc = 0; /* success */ + +exit: + return rc; + } + +int TPM2_CSR_Example(void* userCtx) +{ + int rc; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY storageKey; +#ifndef NO_RSA + WOLFTPM2_KEY rsaKey; + RsaKey wolfRsaKey; +#endif +#ifdef HAVE_ECC + WOLFTPM2_KEY eccKey; + ecc_key wolfEccKey; +#endif + TPMT_PUBLIC publicTemplate; + TpmCryptoDevCtx tpmCtx; + int tpmDevId; printf("TPM2 CSR Example\n"); @@ -67,7 +144,14 @@ int TPM2_CSR_Example(void* userCtx) if (rc != 0) return rc; /* Setup the wolf crypto device callback */ +#ifndef NO_RSA + XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey)); tpmCtx.rsaKey = &rsaKey; +#endif +#ifdef HAVE_ECC + XMEMSET(&wolfEccKey, 0, sizeof(wolfEccKey)); + tpmCtx.eccKey = &eccKey; +#endif rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); if (rc != 0) goto exit; @@ -97,8 +181,9 @@ int TPM2_CSR_Example(void* userCtx) storageKey.handle.auth.size); } - /* Create/Load RSA key for TLS authentication */ - rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_KEY_HANDLE); +#ifndef NO_RSA + /* Create/Load RSA key for CSR */ + rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) { rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | @@ -110,11 +195,11 @@ int TPM2_CSR_Example(void* userCtx) /* Move this key into persistent storage */ rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &rsaKey, - TPM2_DEMO_KEY_HANDLE); + TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) goto exit; } else { - /* specify auth password for rsa key */ + /* specify auth password for RSA key */ rsaKey.handle.auth.size = sizeof(gKeyAuth)-1; XMEMCPY(rsaKey.handle.auth.buffer, gKeyAuth, rsaKey.handle.auth.size); } @@ -126,43 +211,45 @@ int TPM2_CSR_Example(void* userCtx) 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); + rc = TPM2_CSR_Generate(&dev, RSA_TYPE, &wolfRsaKey, gClientCertRsaFile); if (rc != 0) goto exit; +#endif /* !NO_RSA */ - /* 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; +#ifdef HAVE_ECC + /* Create/Load ECC key for CSR */ + rc = wolfTPM2_ReadPublicKey(&dev, &eccKey, TPM2_DEMO_ECC_KEY_HANDLE); + if (rc != 0) { + rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate, + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_sign | TPMA_OBJECT_noDA, + TPM_ECC_NIST_P256, TPM_ALG_ECDSA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); + if (rc != 0) goto exit; - /* 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; + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &eccKey, + TPM2_DEMO_ECC_KEY_HANDLE); + if (rc != 0) goto exit; + } + else { + /* specify auth password for ECC key */ + eccKey.handle.auth.size = sizeof(gKeyAuth)-1; + XMEMCPY(eccKey.handle.auth.buffer, gKeyAuth, eccKey.handle.auth.size); + } - printf("Generated/Signed Cert (DER %d, PEM %d)\n", der.size, output.size); - printf("%s\n", (char*)output.buffer); + /* setup wolf ECC key with TPM deviceID, so crypto callbacks are used */ + rc = wc_ecc_init_ex(&wolfEccKey, NULL, tpmDevId); + if (rc != 0) goto exit; + /* load public portion of key into wolf ECC Key */ + rc = wolfTPM2_EccKey_TpmToWolf(&dev, &eccKey, &wolfEccKey); + if (rc != 0) goto exit; - rc = 0; /* report success */ + rc = TPM2_CSR_Generate(&dev, ECC_TYPE, &wolfEccKey, gClientCertEccFile); + if (rc != 0) goto exit; +#endif /* HAVE_ECC */ exit: @@ -170,8 +257,14 @@ int TPM2_CSR_Example(void* userCtx) printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); } +#ifndef NO_RSA wc_FreeRsaKey(&wolfRsaKey); wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); +#endif +#ifdef HAVE_ECC + wc_ecc_free(&wolfEccKey); + wolfTPM2_UnloadHandle(&dev, &eccKey.handle); +#endif wolfTPM2_Cleanup(&dev); @@ -194,6 +287,7 @@ int main(void) rc = TPM2_CSR_Example(TPM2_IoGetUserCtx()); #else printf("Wrapper/CertReq/CryptoDev code not compiled in\n"); + printf("Build wolfssl with ./configure --enable-certgen --enable-certreq --enable-certext --enable-cryptodev\n"); #endif return rc; diff --git a/examples/pkcs7/pkcs7.c b/examples/pkcs7/pkcs7.c index 73746f37..90eeda17 100644 --- a/examples/pkcs7/pkcs7.c +++ b/examples/pkcs7/pkcs7.c @@ -95,7 +95,7 @@ int TPM2_PKCS7_Example(void* userCtx) } /* Create/Load RSA key for TLS authentication */ - rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_KEY_HANDLE); + rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) { rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | @@ -107,7 +107,7 @@ int TPM2_PKCS7_Example(void* userCtx) /* Move this key into persistent storage */ rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &rsaKey, - TPM2_DEMO_KEY_HANDLE); + TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) goto exit; } else { @@ -186,6 +186,7 @@ int main(void) rc = TPM2_PKCS7_Example(TPM2_IoGetUserCtx()); #else printf("Wrapper/PKCS7/CryptoDev code not compiled in\n"); + printf("Build wolfssl with ./configure --enable-pkcs7 --enable-cryptodev\n"); #endif return rc; diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c index 35fa6379..6ecea953 100644 --- a/examples/tls/tls_client.c +++ b/examples/tls/tls_client.c @@ -23,31 +23,225 @@ #include #include -#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) && \ - defined(HAVE_PK_CALLBACKS) +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) #include #include +#include + +#define TLS_HOST "www.wolfssl.com" +#define TLS_PORT 443 + +/* + * Generating the Client Certificate + * + * Run example for ./examples/csr/csr + * Result is: ./certs/client-rsa-cert.csr and ./certs/client-ecc-cert.csr + * + * Run ./certs/certsign.sh + * Result is: ./certs/client-rsa-cert.pem and ./certs/client-ecc-cert.pem + */ + + /******************************************************************************/ -/* --- BEGIN TLS Client Example -- */ +/* --- BEGIN Socket IO Callbacks --- */ +/******************************************************************************/ + +/* socket includes */ +#include +#include +#include +#include + +typedef struct SockIoCbCtx { + int fd; +} SockIoCbCtx; + +static int SockIORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx) +{ + SockIoCbCtx* sockCtx = (SockIoCbCtx*)ctx; + int recvd; + + (void)ssl; + + /* Receive message from socket */ + if ((recvd = recv(sockCtx->fd, buff, sz, 0)) == -1) { + /* error encountered. Be responsible and report it in wolfSSL terms */ + + fprintf(stderr, "IO RECEIVE ERROR: "); + switch (errno) { + #if EAGAIN != EWOULDBLOCK + case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */ + #endif + case EWOULDBLOCK: + if (wolfSSL_get_using_nonblock(ssl)) { + fprintf(stderr, "would block\n"); + return WOLFSSL_CBIO_ERR_WANT_READ; + } + else { + fprintf(stderr, "socket timeout\n"); + return WOLFSSL_CBIO_ERR_TIMEOUT; + } + case ECONNRESET: + fprintf(stderr, "connection reset\n"); + return WOLFSSL_CBIO_ERR_CONN_RST; + case EINTR: + fprintf(stderr, "socket interrupted\n"); + return WOLFSSL_CBIO_ERR_ISR; + case ECONNREFUSED: + fprintf(stderr, "connection refused\n"); + return WOLFSSL_CBIO_ERR_WANT_READ; + case ECONNABORTED: + fprintf(stderr, "connection aborted\n"); + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + default: + fprintf(stderr, "general error\n"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + else if (recvd == 0) { + printf("Connection closed\n"); + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + } + +#ifdef DEBUG_WOLFTPM + /* successful receive */ + printf("SockIORecv: received %d bytes from %d\n", sz, sockCtx->fd); +#endif + + return recvd; +} + +static int SockIOSend(WOLFSSL* ssl, char* buff, int sz, void* ctx) +{ + SockIoCbCtx* sockCtx = (SockIoCbCtx*)ctx; + int sent; + + (void)ssl; + + /* Receive message from socket */ + if ((sent = send(sockCtx->fd, buff, sz, 0)) == -1) { + /* error encountered. Be responsible and report it in wolfSSL terms */ + + fprintf(stderr, "IO SEND ERROR: "); + switch (errno) { + #if EAGAIN != EWOULDBLOCK + case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */ + #endif + case EWOULDBLOCK: + fprintf(stderr, "would block\n"); + return WOLFSSL_CBIO_ERR_WANT_READ; + case ECONNRESET: + fprintf(stderr, "connection reset\n"); + return WOLFSSL_CBIO_ERR_CONN_RST; + case EINTR: + fprintf(stderr, "socket interrupted\n"); + return WOLFSSL_CBIO_ERR_ISR; + case EPIPE: + fprintf(stderr, "socket EPIPE\n"); + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + default: + fprintf(stderr, "general error\n"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + else if (sent == 0) { + printf("Connection closed\n"); + return 0; + } + +#ifdef DEBUG_WOLFTPM + /* successful send */ + printf("SockIOSend: sent %d bytes to %d\n", sz, sockCtx->fd); +#endif + + return sent; +} + +static int SetupSocketAndConnect(SockIoCbCtx* sockIoCtx, const char* host, + word32 port) +{ + struct sockaddr_in servAddr; + struct hostent* entry; + + /* Setup server address */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(port); + + /* Resolve host */ + entry = gethostbyname(host); + if (entry) { + XMEMCPY(&servAddr.sin_addr.s_addr, entry->h_addr_list[0], + entry->h_length); + } + else { + servAddr.sin_addr.s_addr = inet_addr(host); + } + + /* Create a socket that uses an Internet IPv4 address, + * Sets the socket to be stream based (TCP), + * 0 means choose the default protocol. */ + if ((sockIoCtx->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + fprintf(stderr, "ERROR: failed to create the socket\n"); + return -1; + } + + /* Connect to the server */ + if (connect(sockIoCtx->fd, (struct sockaddr*)&servAddr, + sizeof(servAddr)) == -1) { + fprintf(stderr, "ERROR: failed to connect\n"); + return -1; + } + + return 0; +} + +static void CloseAndCleanupSocket(SockIoCbCtx* sockIoCtx) +{ + if (sockIoCtx->fd != -1) { + close(sockIoCtx->fd); + sockIoCtx->fd = -1; + } +} + +/******************************************************************************/ +/* --- END Socket IO Callbacks --- */ /******************************************************************************/ + + +/******************************************************************************/ +/* --- BEGIN TLS Client Example -- */ +/******************************************************************************/ +#define MAX_REPLY_SZ 1024 int TPM2_TLS_Client(void* userCtx) { int rc; WOLFTPM2_DEV dev; WOLFTPM2_KEY storageKey; +#ifndef NO_RSA WOLFTPM2_KEY rsaKey; + RsaKey wolfRsaKey; +#endif +#ifdef HAVE_ECC WOLFTPM2_KEY eccKey; - RsaKey wolfTlsRsaKey; - WOLFTPM2_BUFFER cert; + ecc_key wolfEccKey; +#endif TPMT_PUBLIC publicTemplate; - TPMS_NV_PUBLIC nvPublic; TpmCryptoDevCtx tpmCtx; + SockIoCbCtx sockIoCtx; int tpmDevId; + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + char msg[] = "GET /index.html HTTP/1.0\r\n\r\n"; + char reply[MAX_REPLY_SZ]; + int msgSz, replySz; - XMEMSET(&wolfTlsRsaKey, 0, sizeof(wolfTlsRsaKey)); + /* initialize variables */ + XMEMSET(&sockIoCtx, 0, sizeof(sockIoCtx)); + sockIoCtx.fd = -1; printf("TPM2 TLS Client Example\n"); @@ -56,6 +250,14 @@ int TPM2_TLS_Client(void* userCtx) if (rc != 0) return rc; /* Setup the wolf crypto device callback */ +#ifndef NO_RSA + XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey)); + tpmCtx.rsaKey = &rsaKey; +#endif +#ifdef HAVE_ECC + XMEMSET(&wolfEccKey, 0, sizeof(wolfEccKey)); + tpmCtx.eccKey = &eccKey; +#endif rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); if (rc != 0) goto exit; @@ -85,8 +287,9 @@ int TPM2_TLS_Client(void* userCtx) storageKey.handle.auth.size); } +#ifndef NO_RSA /* Create/Load RSA key for TLS authentication */ - rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_KEY_HANDLE); + rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) { rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | @@ -98,7 +301,7 @@ int TPM2_TLS_Client(void* userCtx) /* Move this key into persistent storage */ rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &rsaKey, - TPM2_DEMO_KEY_HANDLE); + TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) goto exit; } else { @@ -108,40 +311,159 @@ int TPM2_TLS_Client(void* userCtx) } /* setup wolf RSA key with TPM deviceID, so crypto callbacks are used */ - rc = wc_InitRsaKey_ex(&wolfTlsRsaKey, NULL, tpmDevId); + 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, &wolfTlsRsaKey); + rc = wolfTPM2_RsaKey_TpmToWolf(&dev, &rsaKey, &wolfRsaKey); if (rc != 0) goto exit; +#endif /* !NO_RSA */ - - /* 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); +#ifdef HAVE_ECC + /* Create/Load ECC key for TLS authentication */ + rc = wolfTPM2_ReadPublicKey(&dev, &eccKey, TPM2_DEMO_ECC_KEY_HANDLE); + if (rc != 0) { + rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate, + TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_sign | TPMA_OBJECT_noDA, + TPM_ECC_NIST_P256, TPM_ALG_ECDSA); + if (rc != 0) goto exit; + rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, + &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1); 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); + + /* Move this key into persistent storage */ + rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &eccKey, + TPM2_DEMO_ECC_KEY_HANDLE); 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; + /* specify auth password for ECC key */ + eccKey.handle.auth.size = sizeof(gKeyAuth)-1; + XMEMCPY(eccKey.handle.auth.buffer, gKeyAuth, eccKey.handle.auth.size); + } + + /* setup wolf ECC key with TPM deviceID, so crypto callbacks are used */ + rc = wc_ecc_init_ex(&wolfEccKey, NULL, tpmDevId); + if (rc != 0) goto exit; + /* load public portion of key into wolf ECC Key */ + rc = wolfTPM2_EccKey_TpmToWolf(&dev, &eccKey, &wolfEccKey); + if (rc != 0) goto exit; +#endif /* HAVE_ECC */ + + + /* Setup the WOLFSSL context (factory) */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) { + rc = MEMORY_E; goto exit; } + /* Setup IO Callbacks */ + wolfSSL_CTX_SetIORecv(ctx, SockIORecv); + wolfSSL_CTX_SetIOSend(ctx, SockIOSend); - /* DO TLS */ + /* Server certificate validation */ +#if 0 + /* skip server cert validation for this test */ + wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); +#else +#ifdef NO_FILESYSTEM + /* example loading from buffer */ + #if 0 + if (wolfSSL_CTX_load_verify(ctx, ca.buffer, (long)ca.size, + WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) } + goto exit; + } + #endif +#else + /* Load CA Certificate */ + if (wolfSSL_CTX_load_verify_locations(ctx, "./certs/wolfssl-website-ca.pem", + 0) != WOLFSSL_SUCCESS) { + goto exit; + } +#endif /* !NO_FILESYSTEM */ +#endif + +#ifdef NO_FILESYSTEM + /* example loading from buffer */ + #if 0 + if (wolfSSL_CTX_use_certificate_buffer(ctx, cert.buffer, (long)cert.size, + WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { + goto exit; + } + #endif +#else + /* Client certificate (mutual auth) */ +#ifndef NO_RSA + if ((rc = wolfSSL_CTX_use_certificate_file(ctx, "./certs/client-rsa-cert.pem", + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + goto exit; + } +#elif defined(HAVE_ECC) + if ((rc = wolfSSL_CTX_use_certificate_file(ctx, "./certs/client-ecc-cert.pem", + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + goto exit; + } +#endif +#endif /* !NO_FILESYSTEM */ + + /* No need to load private key, since its on TPM and crypto dev callbacks are used */ + +#if 0 + /* Optionally choose the cipher suite */ + rc = wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-GCM-SHA256"); + if (rc != WOLFSSL_SUCCESS) { + goto exit; + } +#endif + + /* Create wolfSSL object/session */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + rc = wolfSSL_get_error(ssl, 0); + goto exit; + } + + /* Setup DevID */ + wolfSSL_SetDevId(ssl, tpmDevId); + + /* Setup socket and connection */ + rc = SetupSocketAndConnect(&sockIoCtx, TLS_HOST, TLS_PORT); + if (rc != 0) goto exit; + + /* Setup read/write callback contexts */ + wolfSSL_SetIOReadCtx(ssl, &sockIoCtx); + wolfSSL_SetIOWriteCtx(ssl, &sockIoCtx); + + /* perform connect */ + do { + rc = wolfSSL_connect(ssl); + if (rc != WOLFSSL_SUCCESS) { + rc = wolfSSL_get_error(ssl, 0); + } + } while (rc == WOLFSSL_ERROR_WANT_READ || rc == WOLFSSL_ERROR_WANT_WRITE); + + /* perform write */ + msgSz = sizeof(msg); + printf("Write (%d): %s\n", msgSz, msg); + do { + rc = wolfSSL_write(ssl, msg, msgSz); + if (rc != msgSz) { + rc = wolfSSL_get_error(ssl, 0); + } + } while (rc == WOLFSSL_ERROR_WANT_WRITE); + + /* perform read */ + do { + rc = wolfSSL_read(ssl, reply, sizeof(reply) - 1); + if (rc < 0) { + rc = wolfSSL_get_error(ssl, 0); + } + else { + /* null terminate */ + reply[rc] = '\0'; + replySz = rc; + rc = 0; + } + } while (rc == WOLFSSL_ERROR_WANT_READ); + printf("Read (%d): %s\n", replySz, reply); exit: @@ -150,9 +472,19 @@ int TPM2_TLS_Client(void* userCtx) printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); } - wc_FreeRsaKey(&wolfTlsRsaKey); + CloseAndCleanupSocket(&sockIoCtx); + wolfSSL_shutdown(ssl); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + +#ifndef NO_RSA + wc_FreeRsaKey(&wolfRsaKey); wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); +#endif +#ifdef HAVE_ECC + wc_ecc_free(&wolfEccKey); wolfTPM2_UnloadHandle(&dev, &eccKey.handle); +#endif wolfTPM2_Cleanup(&dev); @@ -163,18 +495,18 @@ int TPM2_TLS_Client(void* userCtx) /* --- END TLS Client Example -- */ /******************************************************************************/ -#endif /* !WOLFTPM2_NO_WRAPPER && WOLF_CRYPTO_DEV && HAVE_PK_CALLBACKS */ +#endif /* !WOLFTPM2_NO_WRAPPER && WOLF_CRYPTO_DEV */ #ifndef NO_MAIN_DRIVER int main(void) { int rc = -1; -#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) && \ - defined(HAVE_PK_CALLBACKS) +#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) rc = TPM2_TLS_Client(TPM2_IoGetUserCtx()); #else - printf("Wrapper/CryptoDev/PkCb code not compiled in\n"); + printf("Wrapper/CryptoDev code not compiled in\n"); + printf("Build wolfssl with ./configure --enable-cryptodev\n"); #endif return rc; diff --git a/examples/tpm_io.h b/examples/tpm_io.h index 6f75ed0b..38be3e2b 100644 --- a/examples/tpm_io.h +++ b/examples/tpm_io.h @@ -26,9 +26,14 @@ /* 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 */ + +#define TPM2_DEMO_RSA_IDX 0x20 /* offset handle to unused index */ +#define TPM2_DEMO_RSA_KEY_HANDLE (0x81000000 + TPM2_DEMO_RSA_IDX) /* Persistent Key Handle */ +#define TPM2_DEMO_RSA_CERT_HANDLE (0x01800000 + TPM2_DEMO_RSA_IDX) /* NV Handle */ + +#define TPM2_DEMO_ECC_IDX 0x21 /* offset handle to unused index */ +#define TPM2_DEMO_ECC_KEY_HANDLE (0x81000000 + TPM2_DEMO_ECC_IDX) /* Persistent Key Handle */ +#define TPM2_DEMO_ECC_CERT_HANDLE (0x01800000 + TPM2_DEMO_ECC_IDX) /* NV Handle */ static const char gStorageKeyAuth[] = "ThisIsMyStorageKeyAuth"; static const char gKeyAuth[] = "ThisIsMyKeyAuth"; diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index fef923d1..e72d4f77 100755 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -1396,7 +1396,7 @@ int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes) int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) { - int ret = NOT_COMPILED_IN; /* return this to bypass HW and use SW */ + int rc = NOT_COMPILED_IN; /* return this to bypass HW and use SW */ TpmCryptoDevCtx* tlsCtx = (TpmCryptoDevCtx*)ctx; if (info == NULL || ctx == NULL || tlsCtx->dev == NULL) @@ -1404,57 +1404,90 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) (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; - } + if (info->algo_type == WC_ALGO_TYPE_PK) { + #ifdef DEBUG_WOLFTPM + printf("CryptoDevCb Pk: Type %d\n", info->pk.type); + #endif - /* 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 + #ifndef NO_RSA + /* RSA */ + if (info->pk.type == WC_PK_TYPE_RSA) { + switch (info->pk.rsa.type) { + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: + { + WOLFTPM2_KEY rsaPub; + + /* load public key into TPM */ + rc = wolfTPM2_RsaKey_WolfToTpm(tlsCtx->dev, + info->pk.rsa.key, &rsaPub); + if (rc != 0) { + /* A failure of TPM_RC_KEY can happen due to unsupported + RSA exponents. In those cases return NOT_COMPILED_IN + and use software */ + rc = NOT_COMPILED_IN; + break; + } + + /* public operations */ + rc = wolfTPM2_RsaEncrypt(tlsCtx->dev, &rsaPub, + TPM_ALG_NULL, /* no padding */ + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, (int*)info->pk.rsa.outLen); + + wolfTPM2_UnloadHandle(tlsCtx->dev, &rsaPub.handle); + break; + } + case RSA_PRIVATE_ENCRYPT: + case RSA_PRIVATE_DECRYPT: + { + /* private operations */ + rc = wolfTPM2_RsaDecrypt(tlsCtx->dev, tlsCtx->rsaKey, + TPM_ALG_NULL, /* no padding */ + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, (int*)info->pk.rsa.outLen); + break; + } + } + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + rc = 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->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + WOLFTPM2_KEY eccPub; + + /* load public key into TPM */ + rc = wolfTPM2_EccKey_WolfToTpm(tlsCtx->dev, info->pk.eccverify.key, + &eccPub); + if (rc == 0) { + rc = wolfTPM2_VerifyHash(tlsCtx->dev, &eccPub, + info->pk.eccverify.sig, info->pk.eccverify.siglen, + info->pk.eccverify.hash, info->pk.eccverify.hashlen); + + wolfTPM2_UnloadHandle(tlsCtx->dev, &eccPub.handle); + } + } + else if (info->pk.type == WC_PK_TYPE_ECDH) { + /* TODO: */ + #if 0 + ecc_key* private_key; + ecc_key* public_key; + byte* out; + word32* outlen; + #endif + } + #endif } -#endif - return ret; + /* need to return negative here for error */ + if (rc != TPM_RC_SUCCESS && rc != NOT_COMPILED_IN) + rc = RSA_BUFFER_E; + + return rc; } int wolfTPM2_SetCryptoDevCb(WOLFTPM2_DEV* dev, CryptoDevCallbackFunc cb, @@ -1469,7 +1502,7 @@ int wolfTPM2_SetCryptoDevCb(WOLFTPM2_DEV* dev, CryptoDevCallbackFunc cb, /* register a crypto device callback for TPM private key */ rc = wolfTPM2_GetTpmDevId(dev); - if (rc < 0) { + if (rc >= 0) { devId = rc; tpmCtx->dev = dev; diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 34a7a6b2..f9b9802d 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -40,6 +40,9 @@ #include #include #include +#ifdef WOLF_CRYPTO_DEV + #include +#endif /* Reconfigurable Elements */ From 2e624e9cbc01443f01b7d34fe091d265903c7736 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 4 Jun 2018 14:49:17 -0700 Subject: [PATCH 03/11] Fix for `wolfTPM2_LoadRsaPublicKey`, so loaded keys are allowed to do a public decrypt. Fixes for PKCS7 to use the signed CSR for the PKCS7 certificate, so the cert and key are the same. Cleanup of the PKCS7 example. --- examples/csr/csr.c | 2 +- examples/pkcs7/pkcs7.c | 45 ++++++++++++++++++++++++++---------------- src/tpm2_tis.c | 3 +-- src/tpm2_wrap.c | 2 +- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/examples/csr/csr.c b/examples/csr/csr.c index f3005a72..f4aec4b3 100644 --- a/examples/csr/csr.c +++ b/examples/csr/csr.c @@ -104,10 +104,10 @@ static const char gClientCertEccFile[] = "./certs/client-ecc-cert.csr"; FILE* pemFile = fopen(outputPemFile, "wb"); if (pemFile) { rc = (int)fwrite(output.buffer, 1, output.size, pemFile); + fclose(pemFile); if (rc != output.size) { rc = -1; goto exit; } - fclose(pemFile); } } #endif diff --git a/examples/pkcs7/pkcs7.c b/examples/pkcs7/pkcs7.c index 90eeda17..ec6c7f6d 100644 --- a/examples/pkcs7/pkcs7.c +++ b/examples/pkcs7/pkcs7.c @@ -30,10 +30,13 @@ #include #include -/* force include test certs */ -#undef USE_CERT_BUFFERS_2048 -#define USE_CERT_BUFFERS_2048 -#include +/* Sign PKCS7 using TPM based key: + * Must Run: + * 1. `./examples/csr/csr` + * 2. `./certs/certreq.sh` + * 3. Results in `./certs/client-rsa-cert.der` + */ + /******************************************************************************/ /* --- BEGIN TPM2 PKCS7 Example -- */ @@ -47,7 +50,6 @@ int TPM2_PKCS7_Example(void* userCtx) WOLFTPM2_KEY rsaKey; TPMT_PUBLIC publicTemplate; TpmCryptoDevCtx tpmCtx; - RsaKey wolfRsaKey; PKCS7 pkcs7; byte data[] = "My encoded DER cert."; int tpmDevId; @@ -55,7 +57,6 @@ int TPM2_PKCS7_Example(void* userCtx) WOLFTPM2_BUFFER output; XMEMSET(&pkcs7, 0, sizeof(pkcs7)); - XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey)); printf("TPM2 PKCS7 Example\n"); @@ -116,18 +117,28 @@ int TPM2_PKCS7_Example(void* userCtx) 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; + /* load DER certificate for TPM key (obtained by running + `./examples/csr/csr` and `./certs/certreq.sh`) */ +#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) + { + FILE* derFile = fopen("./certs/client-rsa-cert.der", "rb"); + if (derFile) { + fseek(derFile, 0, SEEK_END); + der.size = (int)ftell(derFile); + rewind(derFile); + rc = (int)fread(der.buffer, 1, der.size, derFile); + fclose(derFile); + if (rc != der.size) { + rc = -1; goto exit; + } + } + } +#endif /* 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_Init(&pkcs7, NULL, tpmDevId); + if (rc != 0) goto exit; rc = wc_PKCS7_InitWithCert(&pkcs7, der.buffer, der.size); if (rc != 0) goto exit; @@ -136,7 +147,6 @@ int TPM2_PKCS7_Example(void* userCtx) 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; @@ -148,6 +158,8 @@ int TPM2_PKCS7_Example(void* userCtx) TPM2_PrintBin(output.buffer, output.size); /* Test verify */ + rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId); + if (rc != 0) goto exit; rc = wc_PKCS7_InitWithCert(&pkcs7, NULL, 0); if (rc != 0) goto exit; rc = wc_PKCS7_VerifySignedData(&pkcs7, output.buffer, output.size); @@ -162,7 +174,6 @@ int TPM2_PKCS7_Example(void* userCtx) printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); } - wc_FreeRsaKey(&wolfRsaKey); wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); wolfTPM2_Cleanup(&dev); diff --git a/src/tpm2_tis.c b/src/tpm2_tis.c index 370c49f4..87e02769 100755 --- a/src/tpm2_tis.c +++ b/src/tpm2_tis.c @@ -1,4 +1,3 @@ - /* tpm2_tis.c * * Copyright (C) 2006-2018 wolfSSL Inc. @@ -61,7 +60,7 @@ enum tpm_tis_int_flags { TPM_INTF_DATA_AVAIL_INT = 0x001, }; -#define TPM_BASE_ADDRESS (0xd40000u) +#define TPM_BASE_ADDRESS (0xD40000u) #define TPM_ACCESS(l) (TPM_BASE_ADDRESS | 0x0000u | ((l) << 12u)) #define TPM_INT_ENABLE(l) (TPM_BASE_ADDRESS | 0x0008u | ((l) << 12u)) diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index e72d4f77..0705a766 100755 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -341,7 +341,7 @@ int wolfTPM2_LoadRsaPublicKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, XMEMSET(&pub, 0, sizeof(pub)); pub.publicArea.type = TPM_ALG_RSA; pub.publicArea.nameAlg = TPM_ALG_NULL; - pub.publicArea.objectAttributes = 0; + pub.publicArea.objectAttributes = TPMA_OBJECT_decrypt; pub.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL; pub.publicArea.parameters.rsaDetail.keyBits = rsaPubSz * 8; pub.publicArea.parameters.rsaDetail.exponent = exponent; From f3559d11716921b3cc1b96665afe98b4a665d7ee Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 4 Jun 2018 15:34:05 -0700 Subject: [PATCH 04/11] Added save of the PKCS7 example generated data to file `./examples/pkcs7/pkcs7tpmsigned.p7s`. Added some items to the .gitignore. --- .gitignore | 17 ++++++++++++++++- examples/pkcs7/pkcs7.c | 14 +++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 348d66eb..f0a75ef8 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,21 @@ RemoteSystemsTempFiles *.o *.deps *.libs +wolftpm/options.h + examples/wrap/wrap_test examples/native/native_test -wolftpm/options.h +examples/bench/bench +examples/csr/csr + +examples/pkcs7/pkcs7 +pkcs7tpmsigned.p7s + +# Generated Cert Files +certs/ca-*.pem +certs/ca-*.der +certs/ca-*.crl +certs/*.par +certs/crlnumber* +certs/serial +certs/index* diff --git a/examples/pkcs7/pkcs7.c b/examples/pkcs7/pkcs7.c index ec6c7f6d..56dc7460 100644 --- a/examples/pkcs7/pkcs7.c +++ b/examples/pkcs7/pkcs7.c @@ -153,10 +153,22 @@ int TPM2_PKCS7_Example(void* userCtx) wc_PKCS7_Free(&pkcs7); output.size = rc; - printf("PKCS7 Signed Container %d\n", output.size); TPM2_PrintBin(output.buffer, output.size); +#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) + { + FILE* pemFile = fopen("./examples/pkcs7/pkcs7tpmsigned.p7s", "wb"); + if (pemFile) { + rc = (int)fwrite(output.buffer, 1, output.size, pemFile); + fclose(pemFile); + if (rc != output.size) { + rc = -1; goto exit; + } + } + } +#endif + /* Test verify */ rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId); if (rc != 0) goto exit; From e367d63dad083466600b3e62aad4e8d3ba073188 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 4 Jun 2018 21:10:26 -0700 Subject: [PATCH 05/11] Fix for ECC sign/verify (fixes ECC crypto dev callback to handle ECC ASN1 encoding/decoding). Fix for CSR to have different CN's. Fix typo in `./certs/certreq.sh`. --- certs/certreq.sh | 2 +- examples/csr/csr.c | 9 +++++++-- src/tpm2_wrap.c | 36 +++++++++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/certs/certreq.sh b/certs/certreq.sh index 9f267e5f..f03c2b9c 100755 --- a/certs/certreq.sh +++ b/certs/certreq.sh @@ -36,7 +36,7 @@ fi # Generate ECC 256-bit CA -if [ ! -f ./certs/ca-rsa-key.pem ]; then +if [ ! -f ./certs/ca-ecc-key.pem ]; then openssl ecparam -out ./certs/ca-ecc-key.par -name prime256v1 openssl req -config ./certs/ca-ecc.cnf -extensions v3_ca -x509 -nodes -newkey ec:./certs/ca-ecc-key.par -keyout ./certs/ca-ecc-key.pem -out ./certs/ca-ecc-cert.pem -sha256 -days 7300 -batch -subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com" rm ./certs/ca-ecc-key.par diff --git a/examples/csr/csr.c b/examples/csr/csr.c index f4aec4b3..0b2936b2 100644 --- a/examples/csr/csr.c +++ b/examples/csr/csr.c @@ -63,10 +63,15 @@ static const char gClientCertEccFile[] = "./certs/client-ecc-cert.csr"; XMEMCPY(&req.subject, &myCertName, sizeof(myCertName)); - if (key_type == RSA_TYPE) + /* make sure each common name is unique */ + if (key_type == RSA_TYPE) { req.sigType = CTC_SHA256wRSA; - else if (key_type == ECC_TYPE) + XSTRNCPY(req.subject.unit, "RSA", sizeof(req.subject.unit)); + } + else if (key_type == ECC_TYPE) { req.sigType = CTC_SHA256wECDSA; + XSTRNCPY(req.subject.unit, "ECC", sizeof(req.subject.unit)); + } #ifdef WOLFSSL_CERT_EXT /* add SKID from the Public Key */ diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 0705a766..c44c634b 100755 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -1453,22 +1453,40 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) #endif /* !NO_RSA */ #ifdef HAVE_ECC if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + byte sigRS[MAX_ECC_BYTES*2]; + byte *r = sigRS, *s; + word32 rsLen = sizeof(sigRS), rLen, sLen; + rc = wolfTPM2_SignHash(tlsCtx->dev, tlsCtx->eccKey, info->pk.eccsign.in, info->pk.eccsign.inlen, - info->pk.eccsign.out, (int*)info->pk.eccsign.outlen); + sigRS, (int*)&rsLen); + if (rc == 0) { + rLen = sLen = rsLen / 2; + s = &sigRS[rLen]; + rc = wc_ecc_rs_raw_to_sig(r, rLen, s, sLen, + info->pk.eccsign.out, info->pk.eccsign.outlen); + } } else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { WOLFTPM2_KEY eccPub; + byte sigRS[MAX_ECC_BYTES*2]; + byte *r = sigRS, *s = &sigRS[MAX_ECC_BYTES]; + word32 rLen = MAX_ECC_BYTES, sLen = MAX_ECC_BYTES; - /* load public key into TPM */ - rc = wolfTPM2_EccKey_WolfToTpm(tlsCtx->dev, info->pk.eccverify.key, - &eccPub); + /* Decode ECDSA Header */ + rc = wc_ecc_sig_to_rs(info->pk.eccverify.sig, + info->pk.eccverify.siglen, r, &rLen, s, &sLen); if (rc == 0) { - rc = wolfTPM2_VerifyHash(tlsCtx->dev, &eccPub, - info->pk.eccverify.sig, info->pk.eccverify.siglen, - info->pk.eccverify.hash, info->pk.eccverify.hashlen); - - wolfTPM2_UnloadHandle(tlsCtx->dev, &eccPub.handle); + /* load public key into TPM */ + rc = wolfTPM2_EccKey_WolfToTpm(tlsCtx->dev, + info->pk.eccverify.key, &eccPub); + if (rc == 0) { + rc = wolfTPM2_VerifyHash(tlsCtx->dev, &eccPub, + info->pk.eccverify.sig, info->pk.eccverify.siglen, + info->pk.eccverify.hash, info->pk.eccverify.hashlen); + + wolfTPM2_UnloadHandle(tlsCtx->dev, &eccPub.handle); + } } } else if (info->pk.type == WC_PK_TYPE_ECDH) { From 7ef0863264bd02808658b44b96e1147fdcafe565 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 5 Jun 2018 12:42:21 -0700 Subject: [PATCH 06/11] Added software only PKCS7 verify for the example. --- examples/pkcs7/pkcs7.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/pkcs7/pkcs7.c b/examples/pkcs7/pkcs7.c index 56dc7460..3c53ab90 100644 --- a/examples/pkcs7/pkcs7.c +++ b/examples/pkcs7/pkcs7.c @@ -95,7 +95,7 @@ int TPM2_PKCS7_Example(void* userCtx) storageKey.handle.auth.size); } - /* Create/Load RSA key for TLS authentication */ + /* Create/Load RSA key for PKCS7 signing */ rc = wolfTPM2_ReadPublicKey(&dev, &rsaKey, TPM2_DEMO_RSA_KEY_HANDLE); if (rc != 0) { rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, @@ -169,7 +169,7 @@ int TPM2_PKCS7_Example(void* userCtx) } #endif - /* Test verify */ + /* Test verify with TPM */ rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId); if (rc != 0) goto exit; rc = wc_PKCS7_InitWithCert(&pkcs7, NULL, 0); @@ -178,7 +178,18 @@ int TPM2_PKCS7_Example(void* userCtx) if (rc != 0) goto exit; wc_PKCS7_Free(&pkcs7); - printf("PKCS7 Container Verified\n"); + printf("PKCS7 Container Verified (using TPM)\n"); + + /* Test verify with software */ + rc = wc_PKCS7_Init(&pkcs7, NULL, INVALID_DEVID); + if (rc != 0) goto exit; + 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 (using software)\n"); exit: From 0aad134b4bb6aa1f1499e611f059a841168a7605 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 7 Jun 2018 11:53:44 -0700 Subject: [PATCH 07/11] Minor fix for warning when building without debug enabled. --- examples/tls/tls_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c index 6ecea953..266b167b 100644 --- a/examples/tls/tls_client.c +++ b/examples/tls/tls_client.c @@ -237,7 +237,7 @@ int TPM2_TLS_Client(void* userCtx) WOLFSSL* ssl = NULL; char msg[] = "GET /index.html HTTP/1.0\r\n\r\n"; char reply[MAX_REPLY_SZ]; - int msgSz, replySz; + int msgSz, replySz = 0; /* initialize variables */ XMEMSET(&sockIoCtx, 0, sizeof(sockIoCtx)); From a143679b961e258ffb5e71678fdf0dea4e20bc75 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 6 Jul 2018 16:35:42 -0700 Subject: [PATCH 08/11] Fix for minor build warning with `TPM2_SetSessionAuth`. Updated the OpenSTM32 project. --- IDE/OPENSTM32/.cproject | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/IDE/OPENSTM32/.cproject b/IDE/OPENSTM32/.cproject index 4d783a73..587cd556 100644 --- a/IDE/OPENSTM32/.cproject +++ b/IDE/OPENSTM32/.cproject @@ -135,10 +135,9 @@ - + - - + From 6ae32daa52a35b91d8af109e72ab72de8255368f Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 18 Jul 2018 16:28:26 -0700 Subject: [PATCH 09/11] Fix TLS client example to properly shutdown before closing socket. Added additional logging and fixed comment about certreq.sh script. Improved the cert signing script to not prompt. Also supports option `./certs/certreq.sh clean` to do a clean sign. Added way to do a TPM clean/reset using `TPM2_Wrapper_SetReset`. --- certs/certreq.sh | 10 ++++++++-- examples/tls/tls_client.c | 8 ++++++-- examples/wrap/wrap_test.c | 22 +++++++++++++--------- examples/wrap/wrap_test.h | 1 + 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/certs/certreq.sh b/certs/certreq.sh index f03c2b9c..346cf17f 100755 --- a/certs/certreq.sh +++ b/certs/certreq.sh @@ -14,6 +14,12 @@ if [ ! -f ./certs/crlnumber ]; then echo 2000 > ./certs/crlnumber fi +if [ $1 == clean ]; then + rm ./certs/*.pem + rm ./certs/*.der + rm ./certs/*.old +fi + # Generate RSA 2048-bit CA if [ ! -f ./certs/ca-rsa-key.pem ]; then @@ -30,7 +36,7 @@ fi # Sign RSA certificate if [ -f ./certs/client-rsa-cert.csr ]; then - openssl ca -config ./certs/ca-rsa.cnf -extensions usr_cert -days 3650 -notext -md sha256 -in ./certs/client-rsa-cert.csr -out ./certs/client-rsa-cert.pem + openssl ca -config ./certs/ca-rsa.cnf -extensions usr_cert -days 3650 -notext -md sha256 -in ./certs/client-rsa-cert.csr -out ./certs/client-rsa-cert.pem -batch openssl x509 -in ./certs/client-rsa-cert.pem -outform der -out ./certs/client-rsa-cert.der fi @@ -56,6 +62,6 @@ if [ -f ./certs/client-ecc-cert.csr ]; then #openssl req -config ./certs/ca-ecc.cnf -sha256 -new -newkey ec:./certs/client-ecc-key.par -keyout ./certs/client-ecc-key.pem -out ./certs/client-ecc-cert.csr -subj "/C=US/ST=Washington/L=Seattle/O=Eliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=info@wolfssl.com/" #rm ./certs/client-ecc-key.par - openssl ca -config ./certs/ca-ecc.cnf -extensions usr_cert -days 3650 -notext -md sha256 -in ./certs/client-ecc-cert.csr -out ./certs/client-ecc-cert.pem + openssl ca -config ./certs/ca-ecc.cnf -extensions usr_cert -days 3650 -notext -md sha256 -in ./certs/client-ecc-cert.csr -out ./certs/client-ecc-cert.pem -batch openssl x509 -in ./certs/client-ecc-cert.pem -outform der -out ./certs/client-ecc-cert.der fi diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c index 266b167b..b05793a3 100644 --- a/examples/tls/tls_client.c +++ b/examples/tls/tls_client.c @@ -39,7 +39,7 @@ * Run example for ./examples/csr/csr * Result is: ./certs/client-rsa-cert.csr and ./certs/client-ecc-cert.csr * - * Run ./certs/certsign.sh + * Run ./certs/certreq.sh * Result is: ./certs/client-rsa-cert.pem and ./certs/client-ecc-cert.pem */ @@ -377,6 +377,7 @@ int TPM2_TLS_Client(void* userCtx) /* Load CA Certificate */ if (wolfSSL_CTX_load_verify_locations(ctx, "./certs/wolfssl-website-ca.pem", 0) != WOLFSSL_SUCCESS) { + printf("Error loading wolfSSL website certs\n"); goto exit; } #endif /* !NO_FILESYSTEM */ @@ -395,11 +396,13 @@ int TPM2_TLS_Client(void* userCtx) #ifndef NO_RSA if ((rc = wolfSSL_CTX_use_certificate_file(ctx, "./certs/client-rsa-cert.pem", WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + printf("Error loading RSA client cert\n"); goto exit; } #elif defined(HAVE_ECC) if ((rc = wolfSSL_CTX_use_certificate_file(ctx, "./certs/client-ecc-cert.pem", WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + printf("Error loading ECC client cert\n"); goto exit; } #endif @@ -472,8 +475,9 @@ int TPM2_TLS_Client(void* userCtx) printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); } - CloseAndCleanupSocket(&sockIoCtx); wolfSSL_shutdown(ssl); + + CloseAndCleanupSocket(&sockIoCtx); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index 3a602f4d..c5e6bfe5 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -32,7 +32,6 @@ /* Configuration */ #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 /* from wolfSSL ./certs/client-keyPub.der */ static const byte kRsaPubKeyRaw[] = { @@ -87,6 +86,13 @@ static const byte kEccPubKeyYRaw[] = { /* --- BEGIN Wrapper API Tests -- */ /******************************************************************************/ +static int resetTPM = 0; + +void TPM2_Wrapper_SetReset(int reset) +{ + resetTPM = reset; +} + int TPM2_Wrapper_Test(void* userCtx) { int rc; @@ -140,11 +146,11 @@ int TPM2_Wrapper_Test(void* userCtx) if (rc != 0) goto exit; #endif -#ifdef WOLFTPM_TEST_WITH_RESET - /* reset all content on TPM and reseed */ - rc = wolfTPM2_Clear(&dev); - if (rc != 0) return rc; -#endif + if (resetTPM) { + /* reset all content on TPM and reseed */ + rc = wolfTPM2_Clear(&dev); + if (rc != 0) return rc; + } /* Get the RSA endorsement key (EK) */ rc = wolfTPM2_GetKeyTemplate_RSA_EK(&publicTemplate); @@ -394,9 +400,7 @@ int TPM2_Wrapper_Test(void* userCtx) wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); wolfTPM2_UnloadHandle(&dev, &eccKey.handle); wolfTPM2_UnloadHandle(&dev, &ekKey.handle); -#ifdef WOLFTPM_TEST_WITH_RESET - wolfTPM2_NVDeleteKey(&dev, TPM_RH_OWNER, &storageKey); -#endif + wolfTPM2_Cleanup(&dev); return rc; diff --git a/examples/wrap/wrap_test.h b/examples/wrap/wrap_test.h index c766c692..28ba80ac 100644 --- a/examples/wrap/wrap_test.h +++ b/examples/wrap/wrap_test.h @@ -23,6 +23,7 @@ #define _WRAP_TEST_H_ +void TPM2_Wrapper_SetReset(int reset); int TPM2_Wrapper_Test(void* userCtx); #endif /* _WRAP_TEST_H_ */ From cc6a28d026a457fab8621e235502c5521389e735 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 19 Jul 2018 08:20:38 -0700 Subject: [PATCH 10/11] Added ability to clear/reset TPM using wrapper example with arg such as './examples/wrap/wrap_test 1`. --- examples/wrap/wrap_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index c5e6bfe5..15047c5e 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -413,10 +413,15 @@ int TPM2_Wrapper_Test(void* userCtx) #endif /* !WOLFTPM2_NO_WRAPPER */ #ifndef NO_MAIN_DRIVER -int main(void) +int main(int argc, char *argv[]) { int rc = -1; + if (argc > 1) { + TPM2_Wrapper_SetReset(1); + } + (void)argv; + #ifndef WOLFTPM2_NO_WRAPPER rc = TPM2_Wrapper_Test(TPM2_IoGetUserCtx()); #else From 8d74a1b5adf12c03c78d4882632058a39cad0b1d Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 19 Jul 2018 12:17:47 -0700 Subject: [PATCH 11/11] Fix to handle a TLS connect failure in the example. Fix to return better erorr code for timeout talking to HW. --- examples/tls/tls_client.c | 3 +++ src/tpm2_tis.c | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c index b05793a3..253015bb 100644 --- a/examples/tls/tls_client.c +++ b/examples/tls/tls_client.c @@ -442,6 +442,9 @@ int TPM2_TLS_Client(void* userCtx) rc = wolfSSL_get_error(ssl, 0); } } while (rc == WOLFSSL_ERROR_WANT_READ || rc == WOLFSSL_ERROR_WANT_WRITE); + if (rc != 0) { + goto exit; + } /* perform write */ msgSz = sizeof(msg); diff --git a/src/tpm2_tis.c b/src/tpm2_tis.c index 87e02769..a210bd7c 100755 --- a/src/tpm2_tis.c +++ b/src/tpm2_tis.c @@ -129,7 +129,8 @@ int TPM2_TIS_StartupWait(TPM2_CTX* ctx, int timeout) if (access & TPM_ACCESS_VALID) return 0; } while (rc == TPM_RC_SUCCESS && --timeout > 0); - return -1; + + return TPM_RC_INITIALIZE; } int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality) @@ -144,7 +145,8 @@ int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality) ctx->locality = locality; return locality; } - return -1; + + return TPM_RC_INITIALIZE; } int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout) @@ -167,7 +169,7 @@ int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout) } while (--timeout > 0); } - return -1; + return TPM_RC_INITIALIZE; } int TPM2_TIS_GetInfo(TPM2_CTX* ctx) @@ -230,7 +232,7 @@ int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx) rc = TPM2_TIS_SpiRead(ctx, TPM_STS(ctx->locality) + 1, (byte*)&burstCount, sizeof(burstCount)); if (rc != TPM_RC_SUCCESS) - return -1; + return TPM_RC_INITIALIZE; } while (burstCount == 0); if (burstCount > MAX_SPI_FRAMESIZE)