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.

pull/17/head
David Garske 2018-05-30 10:18:31 -07:00
parent 3784a6e818
commit f1e82ac0e4
15 changed files with 863 additions and 22 deletions

View File

@ -31,7 +31,6 @@
#include <examples/bench/bench.h> #include <examples/bench/bench.h>
/* Configuration */ /* Configuration */
#define TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE 0x81000200
#define TPM2_BENCH_DURATION_SEC 1 #define TPM2_BENCH_DURATION_SEC 1
@ -90,8 +89,6 @@ int TPM2_Wrapper_Bench(void* userCtx)
WOLFTPM2_BUFFER plain; WOLFTPM2_BUFFER plain;
TPMT_PUBLIC publicTemplate; TPMT_PUBLIC publicTemplate;
TPM2B_ECC_POINT pubPoint; TPM2B_ECC_POINT pubPoint;
const char storageKeyAuth[] = "ThisIsMyStorageKeyAuth";
const char keyAuth[] = "ThisIsMyKeyAuth";
double start; double start;
int count; int count;
@ -104,7 +101,7 @@ int TPM2_Wrapper_Bench(void* userCtx)
/* See if primary storage key already exists */ /* See if primary storage key already exists */
rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, rc = wolfTPM2_ReadPublicKey(&dev, &storageKey,
TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); TPM2_DEMO_STORAGE_KEY_HANDLE);
if (rc != 0) { if (rc != 0) {
/* Create primary storage key */ /* Create primary storage key */
rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate,
@ -113,18 +110,18 @@ int TPM2_Wrapper_Bench(void* userCtx)
TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, 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; if (rc != 0) goto exit;
/* Move this key into persistent storage */ /* Move this key into persistent storage */
rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey,
TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); TPM2_DEMO_STORAGE_KEY_HANDLE);
if (rc != 0) goto exit; if (rc != 0) goto exit;
} }
else { else {
/* specify auth password for storage key */ /* specify auth password for storage key */
storageKey.handle.auth.size = sizeof(storageKeyAuth)-1; storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1;
XMEMCPY(storageKey.handle.auth.buffer, storageKeyAuth, XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth,
storageKey.handle.auth.size); storageKey.handle.auth.size);
} }
@ -134,7 +131,7 @@ int TPM2_Wrapper_Bench(void* userCtx)
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle,
&publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit; if (rc != 0) goto exit;
@ -194,7 +191,7 @@ int TPM2_Wrapper_Bench(void* userCtx)
TPM_ECC_NIST_P256, TPM_ALG_ECDSA); TPM_ECC_NIST_P256, TPM_ALG_ECDSA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle,
&publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit; if (rc != 0) goto exit;
@ -230,7 +227,7 @@ int TPM2_Wrapper_Bench(void* userCtx)
TPM_ECC_NIST_P256, TPM_ALG_ECDH); TPM_ECC_NIST_P256, TPM_ALG_ECDH);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle,
&publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit; if (rc != 0) goto exit;
/* Create ephemeral ECC key and generate a shared secret */ /* Create ephemeral ECC key and generate a shared secret */

201
examples/csr/csr.c 100644
View File

@ -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 <wolftpm/tpm2.h>
#include <wolftpm/tpm2_wrap.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLF_CRYPTO_DEV)
#include <examples/tpm_io.h>
#include <examples/csr/csr.h>
#include <wolfssl/wolfcrypt/asn_public.h>
/******************************************************************************/
/* --- 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 */

28
examples/csr/csr.h 100644
View File

@ -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_ */

View File

@ -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

View File

@ -4,6 +4,9 @@
include examples/native/include.am include examples/native/include.am
include examples/wrap/include.am include examples/wrap/include.am
include examples/bench/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 \ dist_example_DATA+= examples/tpm_io.c \
examples/tpm_io.h examples/tpm_io.h

View File

@ -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

View File

@ -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 <wolftpm/tpm2.h>
#include <wolftpm/tpm2_wrap.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(HAVE_PKCS7) && \
defined(WOLF_CRYPTO_DEV)
#include <examples/tpm_io.h>
#include <examples/pkcs7/pkcs7.h>
#include <wolfssl/wolfcrypt/pkcs7.h>
/* force include test certs */
#undef USE_CERT_BUFFERS_2048
#define USE_CERT_BUFFERS_2048
#include <wolfssl/certs_test.h>
/******************************************************************************/
/* --- 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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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 <wolftpm/tpm2.h>
#include <wolftpm/tpm2_wrap.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) && \
defined(HAVE_PK_CALLBACKS)
#include <examples/tpm_io.h>
#include <examples/tls/tls_client.h>
/******************************************************************************/
/* --- 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 */

View File

@ -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_ */

View File

@ -24,6 +24,16 @@
#include <wolftpm/tpm2.h> #include <wolftpm/tpm2.h>
/* 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); void* TPM2_IoGetUserCtx(void);
int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx); word16 xferSz, void* userCtx);

View File

@ -30,7 +30,6 @@
#include <examples/wrap/wrap_test.h> #include <examples/wrap/wrap_test.h>
/* Configuration */ /* Configuration */
#define TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE 0x81000200
#define TPM2_DEMO_NV_TEST_INDEX 0x01800200 #define TPM2_DEMO_NV_TEST_INDEX 0x01800200
#define TPM2_DEMO_NV_TEST_SIZE 1024 /* max size on Infineon SLB9670 is 1664 */ #define TPM2_DEMO_NV_TEST_SIZE 1024 /* max size on Infineon SLB9670 is 1664 */
//#define WOLFTPM_TEST_WITH_RESET //#define WOLFTPM_TEST_WITH_RESET
@ -102,9 +101,10 @@ int TPM2_Wrapper_Test(void* userCtx)
WOLFTPM2_BUFFER plain; WOLFTPM2_BUFFER plain;
TPMT_PUBLIC publicTemplate; TPMT_PUBLIC publicTemplate;
TPM2B_ECC_POINT pubPoint; TPM2B_ECC_POINT pubPoint;
const char storageKeyAuth[] = "ThisIsMyStorageKeyAuth";
const char keyAuth[] = "ThisIsMyKeyAuth";
word32 nvAttributes = 0; word32 nvAttributes = 0;
#ifdef WOLF_CRYPTO_DEV
TpmCryptoDevCtx tpmCtx;
#endif
int tpmDevId = INVALID_DEVID; int tpmDevId = INVALID_DEVID;
#ifndef NO_RSA #ifndef NO_RSA
word32 idx = 0; word32 idx = 0;
@ -132,6 +132,14 @@ int TPM2_Wrapper_Test(void* userCtx)
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != 0) return rc; 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 #ifdef WOLFTPM_TEST_WITH_RESET
/* reset all content on TPM and reseed */ /* reset all content on TPM and reseed */
rc = wolfTPM2_Clear(&dev); rc = wolfTPM2_Clear(&dev);
@ -156,7 +164,7 @@ int TPM2_Wrapper_Test(void* userCtx)
/* See if primary storage key already exists */ /* See if primary storage key already exists */
rc = wolfTPM2_ReadPublicKey(&dev, &storageKey, rc = wolfTPM2_ReadPublicKey(&dev, &storageKey,
TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); TPM2_DEMO_STORAGE_KEY_HANDLE);
if (rc != 0) { if (rc != 0) {
/* Create primary storage key */ /* Create primary storage key */
rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate,
@ -165,18 +173,18 @@ int TPM2_Wrapper_Test(void* userCtx)
TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA); TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreatePrimaryKey(&dev, &storageKey, TPM_RH_OWNER, 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; if (rc != 0) goto exit;
/* Move this key into persistent storage */ /* Move this key into persistent storage */
rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey, rc = wolfTPM2_NVStoreKey(&dev, TPM_RH_OWNER, &storageKey,
TPM2_DEMO_PERSISTENT_STORAGE_KEY_HANDLE); TPM2_DEMO_STORAGE_KEY_HANDLE);
if (rc != 0) goto exit; if (rc != 0) goto exit;
} }
else { else {
/* specify auth password for storage key */ /* specify auth password for storage key */
storageKey.handle.auth.size = sizeof(storageKeyAuth)-1; storageKey.handle.auth.size = sizeof(gStorageKeyAuth)-1;
XMEMCPY(storageKey.handle.auth.buffer, storageKeyAuth, XMEMCPY(storageKey.handle.auth.buffer, gStorageKeyAuth,
storageKey.handle.auth.size); storageKey.handle.auth.size);
} }
@ -186,7 +194,7 @@ int TPM2_Wrapper_Test(void* userCtx)
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle, rc = wolfTPM2_CreateAndLoadKey(&dev, &rsaKey, &storageKey.handle,
&publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit; if (rc != 0) goto exit;
@ -264,7 +272,7 @@ int TPM2_Wrapper_Test(void* userCtx)
TPM_ECC_NIST_P256, TPM_ALG_ECDSA); TPM_ECC_NIST_P256, TPM_ALG_ECDSA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle,
&publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit; if (rc != 0) goto exit;
/* Perform sign / verify */ /* Perform sign / verify */
@ -292,7 +300,7 @@ int TPM2_Wrapper_Test(void* userCtx)
TPM_ECC_NIST_P256, TPM_ALG_ECDH); TPM_ECC_NIST_P256, TPM_ALG_ECDH);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle, rc = wolfTPM2_CreateAndLoadKey(&dev, &eccKey, &storageKey.handle,
&publicTemplate, (byte*)keyAuth, sizeof(keyAuth)-1); &publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
if (rc != 0) goto exit; if (rc != 0) goto exit;
/* Create ephemeral ECC key and generate a shared secret */ /* Create ephemeral ECC key and generate a shared secret */

View File

@ -1388,4 +1388,106 @@ int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes)
/* --- END Utility Functions -- */ /* --- 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 */ #endif /* !WOLFTPM2_NO_WRAPPER */

View File

@ -156,4 +156,23 @@ WOLFTPM_API int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttr
#define wolfTPM2_GetCurveSize TPM2_GetCurveSize #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__ */ #endif /* __TPM2_WRAP_H__ */