mirror of https://github.com/wolfSSL/wolfTPM.git
* Added advanced IO callback support (enabled using `--enable-advio` or `#define WOLFTPM_ADV_IO`).
* Added ST33 TPM 2.0 support (`--enable-st33` or `#define WOLFTPM_ST33`). Only SPI version is tested and verified. * Experimental TIS I2C support (`--enable-i2c` or `#define WOLFTPM_I2C`). * Cleanup of the IO callback examples. * Added support for Atmel ASF SPI.pull/25/head
parent
d393f461ca
commit
6fe075911a
53
configure.ac
53
configure.ac
|
|
@ -71,7 +71,7 @@ DEBUG_CFLAGS="-g -O0 -DDEBUG_WOLFTPM"
|
|||
OPTIMIZE_CFLAGS="-O2"
|
||||
|
||||
AX_DEBUG
|
||||
AS_IF([test "x$ax_enable_debug" = "xyes"],
|
||||
AS_IF([test "x$ax_enable_debug" != "xno"],
|
||||
[AM_CFLAGS="$DEBUG_CFLAGS $AM_CFLAGS -DDEBUG"],
|
||||
[AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_CFLAGS -DNDEBUG"])
|
||||
|
||||
|
|
@ -93,6 +93,12 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
# Verbose Logging
|
||||
if test "x$ax_enable_debug" = "xverbose"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_DEBUG_VERBOSE"
|
||||
fi
|
||||
|
||||
|
||||
# Examples
|
||||
AC_ARG_ENABLE([examples],
|
||||
|
|
@ -135,6 +141,47 @@ fi
|
|||
AM_CONDITIONAL([HAVE_LIBWOLFSSL], [test "x$ENABLED_WOLFCRYPT" = "xyes"])
|
||||
|
||||
|
||||
# Advanced IO
|
||||
AC_ARG_ENABLE([advio],
|
||||
[AS_HELP_STRING([--enable-advio],[Enable Advanced IO (default: disabled)])],
|
||||
[ ENABLED_ADVIO=$enableval ],
|
||||
[ ENABLED_ADVIO=no ]
|
||||
)
|
||||
|
||||
if test "x$ENABLED_ADVIO" = "xyes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_ADV_IO"
|
||||
fi
|
||||
AM_CONDITIONAL([BUILD_ADVIO], [test "x$ENABLED_ADVIO" = "xyes"])
|
||||
|
||||
|
||||
# ST33 Support
|
||||
AC_ARG_ENABLE([st33],
|
||||
[AS_HELP_STRING([--enable-st33],[Enable ST33 TPM Support (default: disabled)])],
|
||||
[ ENABLED_ST33=$enableval ],
|
||||
[ ENABLED_ST33=no ]
|
||||
)
|
||||
|
||||
if test "x$ENABLED_ST33" = "xyes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_ST33"
|
||||
fi
|
||||
AM_CONDITIONAL([BUILD_ST33], [test "x$ENABLED_ST33" = "xyes"])
|
||||
|
||||
|
||||
# I2C Support
|
||||
AC_ARG_ENABLE([i2c],
|
||||
[AS_HELP_STRING([--enable-i2c],[Enable I2C TPM Support (default: disabled)])],
|
||||
[ ENABLED_I2C=$enableval ],
|
||||
[ ENABLED_I2C=no ]
|
||||
)
|
||||
|
||||
if test "x$ENABLED_I2C" = "xyes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_I2C"
|
||||
fi
|
||||
AM_CONDITIONAL([BUILD_I2C], [test "x$ENABLED_I2C" = "xyes"])
|
||||
|
||||
|
||||
|
||||
# HARDEN FLAGS
|
||||
|
|
@ -251,3 +298,7 @@ echo " * LIB Flags: $LIB"
|
|||
|
||||
echo " * Wrappers: $ENABLED_WRAPPER"
|
||||
echo " * Examples: $ENABLED_EXAMPLES"
|
||||
echo " * wolfCrypt: $ENABLED_WOLFCRYPT"
|
||||
echo " * Advanced IO: $ENABLED_ADVIO"
|
||||
echo " * ST33: $ENABLED_ST33"
|
||||
echo " * I2C: $ENABLED_I2C"
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ int main(void)
|
|||
int rc = -1;
|
||||
|
||||
#ifndef WOLFTPM2_NO_WRAPPER
|
||||
rc = TPM2_Wrapper_Bench(TPM2_IoGetUserCtx());
|
||||
rc = TPM2_Wrapper_Bench(NULL);
|
||||
#else
|
||||
printf("Wrapper code not compiled in\n");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@ static const char gClientCertEccFile[] = "./certs/client-ecc-cert.csr";
|
|||
"wolfSSL", CTC_UTF8, /* org */
|
||||
"Development", CTC_UTF8, /* unit */
|
||||
"www.wolfssl.com", CTC_UTF8, /* commonName */
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
"", CTC_UTF8, /* busCat */
|
||||
"", CTC_UTF8, /* joiC */
|
||||
"", CTC_UTF8, /* joiSt */
|
||||
#endif
|
||||
"info@wolfssl.com" /* email */
|
||||
};
|
||||
const char* myKeyUsage = "serverAuth,clientAuth,codeSigning,"
|
||||
|
|
@ -291,7 +296,7 @@ int main(void)
|
|||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFSSL_CERT_REQ) && \
|
||||
defined(WOLF_CRYPTO_DEV) && !defined(WOLFTPM2_NO_WOLFCRYPT)
|
||||
rc = TPM2_CSR_Example(TPM2_IoGetUserCtx());
|
||||
rc = TPM2_CSR_Example(NULL);
|
||||
#else
|
||||
printf("Wrapper/CertReq/CryptoDev code not compiled in\n");
|
||||
printf("Build wolfssl with ./configure --enable-certgen --enable-certreq --enable-certext --enable-cryptodev\n");
|
||||
|
|
|
|||
|
|
@ -1156,7 +1156,7 @@ int main(void)
|
|||
{
|
||||
int rc;
|
||||
|
||||
rc = TPM2_Native_Test(TPM2_IoGetUserCtx());
|
||||
rc = TPM2_Native_Test(NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ int main(void)
|
|||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(HAVE_PKCS7) && \
|
||||
defined(WOLF_CRYPTO_DEV)
|
||||
rc = TPM2_PKCS7_Example(TPM2_IoGetUserCtx());
|
||||
rc = TPM2_PKCS7_Example(NULL);
|
||||
#else
|
||||
printf("Wrapper/PKCS7/CryptoDev code not compiled in\n");
|
||||
printf("Build wolfssl with ./configure --enable-pkcs7 --enable-cryptodev\n");
|
||||
|
|
|
|||
|
|
@ -512,7 +512,7 @@ int main(void)
|
|||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLF_CRYPTO_DEV) && \
|
||||
!defined(WOLFTPM2_NO_WOLFCRYPT)
|
||||
rc = TPM2_TLS_Client(TPM2_IoGetUserCtx());
|
||||
rc = TPM2_TLS_Client(NULL);
|
||||
#else
|
||||
printf("Wrapper/CryptoDev code not compiled in\n");
|
||||
printf("Build wolfssl with ./configure --enable-cryptodev\n");
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
|
||||
#include <wolftpm/tpm2.h>
|
||||
#include <wolftpm/tpm2_tis.h>
|
||||
#include <examples/tpm_io.h>
|
||||
|
||||
|
||||
|
|
@ -31,102 +32,473 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* Configuration for the SPI interface */
|
||||
#ifdef WOLFSSL_STM32_CUBEMX
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
#define TPM2_USER_CTX &hspi1
|
||||
#elif defined(__linux__)
|
||||
/* SPI Requirement: Mode 0 (CPOL=0, CPHA=0), Speed up to 50Mhz */
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#ifdef WOLFTPM_I2C
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <linux/spi/spidev.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef WOLFTPM_ST33
|
||||
/* ST33HTPH SPI uses CE0 */
|
||||
#define TPM2_SPI_DEV "/dev/spidev0.0"
|
||||
#ifdef WOLFTPM_I2C
|
||||
#define TPM2_I2C_ADDR 0x2e
|
||||
#define TPM2_I2C_DEV "/dev/i2c-1"
|
||||
#else
|
||||
/* ST33HTPH SPI uses CE0 */
|
||||
#define TPM2_SPI_DEV "/dev/spidev0.0"
|
||||
|
||||
/* ST33 requires wait state support */
|
||||
#ifndef WOLFTPM_CHECK_WAIT_STATE
|
||||
#define WOLFTPM_CHECK_WAIT_STATE
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
/* OPTIGA SLB9670 and LetsTrust TPM use CE1 */
|
||||
#define TPM2_SPI_DEV "/dev/spidev0.1"
|
||||
#endif
|
||||
|
||||
static int gSpiDev = -1;
|
||||
#define TPM2_USER_CTX &gSpiDev
|
||||
|
||||
#elif defined(WOLFSSL_STM32_CUBEMX)
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
|
||||
#elif defined(WOLFSSL_ATMEL)
|
||||
#include "asf.h"
|
||||
|
||||
#else
|
||||
/* TODO: Add your platform here for HW interface */
|
||||
#define TPM2_USER_CTX NULL
|
||||
|
||||
#endif
|
||||
|
||||
void* TPM2_IoGetUserCtx(void)
|
||||
{
|
||||
return TPM2_USER_CTX;
|
||||
}
|
||||
|
||||
/* IO Callback */
|
||||
int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
#ifdef WOLFSSL_STM32_CUBEMX
|
||||
/* STM32 CubeMX Hal */
|
||||
SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*)userCtx;
|
||||
HAL_StatusTypeDef status;
|
||||
#if defined(__linux__)
|
||||
#if defined(WOLFTPM_I2C)
|
||||
static int i2c_read(int fd, word32 reg, byte* data, int len)
|
||||
{
|
||||
int rc;
|
||||
struct i2c_rdwr_ioctl_data rdwr;
|
||||
struct i2c_msg msgs[2];
|
||||
unsigned char buf[2];
|
||||
|
||||
__HAL_SPI_ENABLE(hspi);
|
||||
#ifndef USE_HW_SPI_CS
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); /* active low */
|
||||
#endif
|
||||
rdwr.msgs = msgs;
|
||||
rdwr.nmsgs = 2;
|
||||
buf[0] = reg & 0xFF; /* address */
|
||||
|
||||
status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf, xferSz, 250);
|
||||
#ifndef USE_HW_SPI_CS
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
|
||||
#endif
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].buf = buf;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].addr = TPM2_I2C_ADDR;
|
||||
|
||||
if (status == HAL_OK)
|
||||
ret = TPM_RC_SUCCESS;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].buf = (unsigned char*)data;
|
||||
msgs[1].len = len;
|
||||
msgs[1].addr = TPM2_I2C_ADDR;
|
||||
|
||||
#elif defined(__linux__)
|
||||
rc = ioctl(fd, I2C_RDWR, &rdwr);
|
||||
|
||||
return (rc == -1) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
static int i2c_write(int fd, word32 reg, byte* data, int len)
|
||||
{
|
||||
int rc;
|
||||
struct i2c_rdwr_ioctl_data rdwr;
|
||||
struct i2c_msg msgs[1];
|
||||
byte buf[MAX_SPI_FRAMESIZE+1];
|
||||
|
||||
rdwr.msgs = msgs;
|
||||
rdwr.nmsgs = 1;
|
||||
buf[0] = reg & 0xFF; /* address */
|
||||
XMEMCPY(buf + 1, data, len);
|
||||
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].buf = buf;
|
||||
msgs[0].len = len + 1;
|
||||
msgs[0].addr = TPM2_I2C_ADDR;
|
||||
|
||||
rc = ioctl(fd, I2C_RDWR, &rdwr);
|
||||
|
||||
return (rc == -1) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Use Linux I2C */
|
||||
static int TPM2_IoCb_Linux_I2C(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf,
|
||||
word16 size, void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
int i2cDev = open(TPM2_I2C_DEV, O_RDWR);
|
||||
if (i2cDev >= 0) {
|
||||
if (isRead)
|
||||
ret = i2c_read(i2cDev, addr, buf, size);
|
||||
else
|
||||
ret = i2c_write(i2cDev, addr, buf, size);
|
||||
|
||||
close(i2cDev);
|
||||
}
|
||||
|
||||
(void)ctx;
|
||||
(void)userCtx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Use Linux SPI synchronous access */
|
||||
int* spiDev = (int*)userCtx;
|
||||
static int TPM2_IoCb_Linux_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
int spiDev;
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
int timeout = TPM_SPI_WAIT_RETRY;
|
||||
#endif
|
||||
|
||||
if (*spiDev == -1) {
|
||||
/* 10Mhz - PI has issue with 5-10Mhz on packets sized over 130 */
|
||||
/* 1Mhz - PI has issue with 5-10Mhz on packets sized over 130 */
|
||||
unsigned int maxSpeed = 1000000;
|
||||
int mode = 0; /* mode 0 */
|
||||
int bits_per_word = 8; /* 8-bits */
|
||||
|
||||
*spiDev = open(TPM2_SPI_DEV, O_RDWR);
|
||||
if (*spiDev >= 0) {
|
||||
ioctl(*spiDev, SPI_IOC_WR_MODE, &mode);
|
||||
ioctl(*spiDev, SPI_IOC_WR_MAX_SPEED_HZ, &maxSpeed);
|
||||
ioctl(*spiDev, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);
|
||||
spiDev = open(TPM2_SPI_DEV, O_RDWR);
|
||||
if (spiDev >= 0) {
|
||||
struct spi_ioc_transfer spi;
|
||||
size_t size;
|
||||
|
||||
ioctl(spiDev, SPI_IOC_WR_MODE, &mode);
|
||||
ioctl(spiDev, SPI_IOC_WR_MAX_SPEED_HZ, &maxSpeed);
|
||||
ioctl(spiDev, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);
|
||||
|
||||
XMEMSET(&spi, 0, sizeof(spi));
|
||||
spi.cs_change= 1; /* strobe CS between transfers */
|
||||
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
/* Send Header */
|
||||
spi.tx_buf = (unsigned long)txBuf;
|
||||
spi.rx_buf = (unsigned long)rxBuf;
|
||||
spi.len = TPM_TIS_HEADER_SZ;
|
||||
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
|
||||
if (size != TPM_TIS_HEADER_SZ) {
|
||||
close(spiDev);
|
||||
return TPM_RC_FAILURE;
|
||||
}
|
||||
|
||||
/* Handle SPI wait states (ST33 typical wait is 2 bytes) */
|
||||
if ((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0) {
|
||||
do {
|
||||
/* Check for SPI ready */
|
||||
spi.len = 1;
|
||||
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
|
||||
if (rxBuf[0] & TPM_TIS_READY_MASK)
|
||||
break;
|
||||
} while (size == 1 && --timeout > 0);
|
||||
if (size != 1 || timeout <= 0) {
|
||||
close(spiDev);
|
||||
return TPM_RC_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remainder of message */
|
||||
spi.tx_buf = (unsigned long)&txBuf[TPM_TIS_HEADER_SZ];
|
||||
spi.rx_buf = (unsigned long)&rxBuf[TPM_TIS_HEADER_SZ];
|
||||
spi.len = xferSz - TPM_TIS_HEADER_SZ;
|
||||
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
|
||||
|
||||
if (size == (size_t)xferSz - TPM_TIS_HEADER_SZ)
|
||||
ret = TPM_RC_SUCCESS;
|
||||
#else
|
||||
/* Send Entire Message - no wait states */
|
||||
spi.tx_buf = (unsigned long)txBuf;
|
||||
spi.rx_buf = (unsigned long)rxBuf;
|
||||
spi.len = xferSz;
|
||||
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
|
||||
if (size == (size_t)xferSz)
|
||||
ret = TPM_RC_SUCCESS;
|
||||
#endif /* WOLFTPM_CHECK_WAIT_STATE */
|
||||
|
||||
close(spiDev);
|
||||
}
|
||||
(void)ctx;
|
||||
(void)userCtx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFTPM_I2C */
|
||||
|
||||
if (*spiDev >= 0) {
|
||||
struct spi_ioc_transfer spi;
|
||||
size_t size;
|
||||
#elif defined(WOLFSSL_STM32_CUBEMX)
|
||||
/* STM32 CubeMX Hal */
|
||||
#define STM32_CUBEMX_SPI_TIMEOUT 250
|
||||
static int TPM2_IoCb_STCubeMX_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*)&hspi1;
|
||||
HAL_StatusTypeDef status;
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
int timeout = TPM_SPI_WAIT_RETRY;
|
||||
#endif
|
||||
|
||||
XMEMSET(&spi, 0, sizeof(spi));
|
||||
spi.tx_buf = (unsigned long)txBuf;
|
||||
spi.rx_buf = (unsigned long)rxBuf;
|
||||
spi.len = xferSz;
|
||||
spi.cs_change= 1; /* strobe CS between transfers */
|
||||
__HAL_SPI_ENABLE(hspi);
|
||||
#ifndef USE_HW_SPI_CS
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); /* active low */
|
||||
#endif
|
||||
|
||||
size = ioctl(*spiDev, SPI_IOC_MESSAGE(1), &spi);
|
||||
if (size == xferSz)
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
/* Send Header */
|
||||
status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf,
|
||||
TPM_TIS_HEADER_SZ, STM32_CUBEMX_SPI_TIMEOUT);
|
||||
if (status == HAL_OK) {
|
||||
#ifndef USE_HW_SPI_CS
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
|
||||
#endif
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
return TPM_RC_FAILURE;
|
||||
}
|
||||
|
||||
/* Check for wait states */
|
||||
if ((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0) {
|
||||
do {
|
||||
/* Check for SPI ready */
|
||||
status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf, 1,
|
||||
STM32_CUBEMX_SPI_TIMEOUT);
|
||||
if (rxBuf[0] & TPM_TIS_READY_MASK)
|
||||
break;
|
||||
} while (status == HAL_OK && --timeout > 0);
|
||||
}
|
||||
|
||||
/* Send remainder of payload */
|
||||
status = HAL_SPI_TransmitReceive(hspi,
|
||||
(byte*)&txBuf[TPM_TIS_HEADER_SZ],
|
||||
&rxBuf[TPM_TIS_HEADER_SZ],
|
||||
xferSz - TPM_TIS_HEADER_SZ, STM32_CUBEMX_SPI_TIMEOUT);
|
||||
#else
|
||||
/* Send Entire Message - no wait states */
|
||||
status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf, xferSz,
|
||||
STM32_CUBEMX_SPI_TIMEOUT);
|
||||
#endif /* WOLFTPM_CHECK_WAIT_STATE */
|
||||
|
||||
#ifndef USE_HW_SPI_CS
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
|
||||
#endif
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
|
||||
if (status == HAL_OK)
|
||||
ret = TPM_RC_SUCCESS;
|
||||
|
||||
(void)ctx;
|
||||
(void)userCtx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_ATMEL)
|
||||
/* Atmel ASF */
|
||||
#define SPI_BAUD_RATE_4M 21
|
||||
#define CS_SPI_TPM 2
|
||||
|
||||
/* Atmel ATSAM3X8EA Chip Selects */
|
||||
static const byte Spi_CS[] = { 0, 1, 2, 3 };
|
||||
static const byte Spi_PCS[] = { 0x0E, 0x0D, 0x0B, 0x07 };
|
||||
|
||||
static inline byte GetSPI_PCS(byte pcs)
|
||||
{
|
||||
if (pcs < sizeof(Spi_PCS))
|
||||
return Spi_PCS[pcs];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline byte GetSPI_CS(byte cs)
|
||||
{
|
||||
if (cs < sizeof(Spi_CS))
|
||||
return Spi_CS[cs];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static byte InitSPI_TPM(byte cs, byte baudRate, byte delay1, byte delay2)
|
||||
{
|
||||
byte csIdx, pcs;
|
||||
|
||||
/* Get CS/PCS */
|
||||
csIdx = GetSPI_CS(cs);
|
||||
pcs = GetSPI_PCS(cs);
|
||||
|
||||
SPI0->SPI_CR = SPI_CR_SPIDIS;
|
||||
|
||||
SPI0->SPI_CSR[csIdx] = SPI_CSR_DLYBCT(delay2) | SPI_CSR_DLYBS(delay1) |
|
||||
SPI_CSR_BITS_8_BIT | SPI_CSR_SCBR(baudRate) | SPI_CSR_CSAAT |
|
||||
SPI_CSR_NCPHA;
|
||||
SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCS(pcs);
|
||||
SPI0->SPI_CR = SPI_CR_SPIEN;
|
||||
|
||||
return pcs;
|
||||
}
|
||||
|
||||
static int XferSPI_TPM(byte pcs, const byte* pSendBuf, byte* pReadBuf, word16 wLen)
|
||||
{
|
||||
int ret = TPM_RC_SUCCESS;
|
||||
word16 i;
|
||||
|
||||
for (i = 0; i < wLen; i++) {
|
||||
while ((SPI0->SPI_SR & SPI_SR_TXEMPTY) == 0);
|
||||
SPI0->SPI_TDR = (word16)pSendBuf[i] | (pcs << 16);
|
||||
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
||||
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
||||
pReadBuf[i] = SPI0->SPI_RDR & 0x00FF;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int TPM2_IoCb_Atmel_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
int ret;
|
||||
byte pcs;
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
int timeout = TPM_SPI_WAIT_RETRY;
|
||||
#endif
|
||||
|
||||
/* Setup SPI */
|
||||
pcs = InitSPI_TPM(CS_SPI_TPM, SPI_BAUD_RATE_4M, 0x02, 0x02);
|
||||
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
/* Send Header */
|
||||
ret = XferSPI_TPM(pcs, txBuf, rxBuf, TPM_TIS_HEADER_SZ);
|
||||
if (ret != TPM_RC_SUCCESS) {
|
||||
SPI0->SPI_CR = SPI_CR_SPIDIS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check for wait states */
|
||||
if ((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0) {
|
||||
do {
|
||||
/* Check for SPI ready */
|
||||
ret = XferSPI_TPM(pcs, txBuf, rxBuf, 1);
|
||||
if (rxBuf[0] & TPM_TIS_READY_MASK)
|
||||
break;
|
||||
} while (ret == TPM_RC_SUCCESS && --timeout > 0);
|
||||
}
|
||||
|
||||
/* Send remainder of payload */
|
||||
ret = XferSPI_TPM(pcs,
|
||||
&txBuf[TPM_TIS_HEADER_SZ],
|
||||
&rxBuf[TPM_TIS_HEADER_SZ],
|
||||
xferSz - TPM_TIS_HEADER_SZ);
|
||||
#else
|
||||
/* Send Entire Message - no wait states */
|
||||
ret = XferSPI_TPM(pcs, txBuf, rxBuf, xferSz);
|
||||
#endif /* WOLFTPM_CHECK_WAIT_STATE */
|
||||
|
||||
/* Disable SPI */
|
||||
SPI0->SPI_CR = SPI_CR_SPIDIS;
|
||||
|
||||
(void)ctx;
|
||||
(void)userCtx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(WOLFTPM_I2C)
|
||||
static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
|
||||
#if defined(__linux__)
|
||||
ret = TPM2_IoCb_Linux_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#elif defined(WOLFSSL_STM32_CUBEMX)
|
||||
ret = TPM2_IoCb_STCubeMX_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#elif defined(WOLFSSL_ATMEL)
|
||||
ret = TPM2_IoCb_Atmel_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#else
|
||||
/* TODO: Add your platform here for HW interface */
|
||||
printf("Add your platform here for HW interface\n");
|
||||
|
||||
/* TODO: Add your platform here for HW SPI interface */
|
||||
printf("Add your platform here for HW SPI interface\n");
|
||||
(void)txBuf;
|
||||
(void)rxBuf;
|
||||
(void)xferSz;
|
||||
(void)userCtx;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
//printf("TPM2_IoCb: %d\n", xferSz);
|
||||
//TPM2_PrintBin(txBuf, xferSz);
|
||||
//TPM2_PrintBin(rxBuf, xferSz);
|
||||
(void)ctx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WOLFTPM_I2C */
|
||||
|
||||
|
||||
#ifdef WOLFTPM_ADV_IO
|
||||
int TPM2_IoCb(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf, word16 size,
|
||||
void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
#ifndef WOLFTPM_I2C
|
||||
byte txBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
||||
byte rxBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
||||
#endif
|
||||
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("TPM2_IoCb (Adv): Read %d, Addr %x, Size %d\n",
|
||||
isRead ? 1 : 0, addr, size);
|
||||
if (!isRead) {
|
||||
printf("Write Size %d\n", size);
|
||||
TPM2_PrintBin(buf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFTPM_I2C)
|
||||
#if defined(__linux__)
|
||||
/* Use Linux I2C */
|
||||
ret = TPM2_IoCb_Linux_I2C(ctx, isRead, addr, buf, size);
|
||||
#else
|
||||
/* TODO: Add your platform here for HW I2C interface */
|
||||
printf("Add your platform here for HW I2C interface\n");
|
||||
(void)isRead;
|
||||
(void)addr;
|
||||
(void)buf;
|
||||
(void)size;
|
||||
(void)userCtx;
|
||||
#endif
|
||||
#else
|
||||
/* Build SPI format buffer */
|
||||
if (isRead) {
|
||||
txBuf[0] = TPM_TIS_READ | ((size & 0xFF) - 1);
|
||||
txBuf[1] = (addr>>16) & 0xFF;
|
||||
txBuf[2] = (addr>>8) & 0xFF;
|
||||
txBuf[3] = (addr) & 0xFF;
|
||||
txBuf[4] = 0x00;
|
||||
XMEMSET(&txBuf[TPM_TIS_HEADER_SZ], 0, size);
|
||||
}
|
||||
else {
|
||||
txBuf[0] = TPM_TIS_WRITE | ((size & 0xFF) - 1);
|
||||
txBuf[1] = (addr>>16) & 0xFF;
|
||||
txBuf[2] = (addr>>8) & 0xFF;
|
||||
txBuf[3] = (addr) & 0xFF;
|
||||
txBuf[4] = 0x00;
|
||||
XMEMCPY(&txBuf[TPM_TIS_HEADER_SZ], buf, size);
|
||||
}
|
||||
|
||||
ret = TPM2_IoCb_SPI(ctx, txBuf, rxBuf, size + TPM_TIS_HEADER_SZ, userCtx);
|
||||
|
||||
if (isRead) {
|
||||
XMEMCPY(buf, &rxBuf[TPM_TIS_HEADER_SZ], size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
if (isRead) {
|
||||
printf("Read Size %d\n", size);
|
||||
TPM2_PrintBin(buf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)ctx;
|
||||
|
|
@ -134,6 +506,33 @@ int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* IO Callback */
|
||||
int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
int ret = TPM_RC_FAILURE;
|
||||
|
||||
#if !defined(WOLFTPM_I2C)
|
||||
ret = TPM2_IoCb_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#else
|
||||
#error Hardware interface for I2C only supported with WOLFTPM_ADV_IO
|
||||
#endif
|
||||
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("TPM2_IoCb: Ret %d, Sz %d\n", ret, xferSz);
|
||||
TPM2_PrintBin(txBuf, xferSz);
|
||||
TPM2_PrintBin(rxBuf, xferSz);
|
||||
#endif
|
||||
|
||||
(void)ctx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFTPM_ADV_IO */
|
||||
|
||||
/******************************************************************************/
|
||||
/* --- END IO Callback Logic -- */
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -39,9 +39,12 @@ static const char gStorageKeyAuth[] = "ThisIsMyStorageKeyAuth";
|
|||
static const char gKeyAuth[] = "ThisIsMyKeyAuth";
|
||||
|
||||
/* TPM2 IO Examples */
|
||||
void* TPM2_IoGetUserCtx(void);
|
||||
#ifdef WOLFTPM_ADV_IO
|
||||
int TPM2_IoCb(TPM2_CTX*, int isRead, word32 addr, byte* buf, word16 size,
|
||||
void* userCtx);
|
||||
#else
|
||||
int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TPM_IO_H_ */
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ static const byte kRsaPubKeyRaw[] = {
|
|||
0x03, 0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
#if !defined(WOLFTPM_ST33)
|
||||
/* from wolfSSL ./certs/ecc-client-keyPub.der */
|
||||
static const byte kEccPubKeyXRaw[] = {
|
||||
0x55, 0xBF, 0xF4, 0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B,
|
||||
|
|
@ -81,6 +82,7 @@ static const byte kEccPubKeyYRaw[] = {
|
|||
0x42, 0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D,
|
||||
0x7F, 0xB4
|
||||
};
|
||||
#endif /* !WOLFTPM_ST33 */
|
||||
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
@ -323,7 +325,7 @@ int TPM2_Wrapper_Test(void* userCtx)
|
|||
printf("ECC DH Generation Passed\n");
|
||||
|
||||
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFTPM_ST33)
|
||||
#ifdef HAVE_ECC
|
||||
/* Demonstrate loading wolf keys */
|
||||
|
||||
|
|
@ -351,7 +353,7 @@ int TPM2_Wrapper_Test(void* userCtx)
|
|||
rc = wolfTPM2_UnloadHandle(&dev, &publicKey.handle);
|
||||
if (rc != 0) goto exit;
|
||||
#endif /* NO_RSA */
|
||||
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
|
||||
#endif /* !WOLFTPM2_NO_WOLFCRYPT && !WOLFTPM_ST33 */
|
||||
|
||||
rc = wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
|
||||
if (rc != 0) goto exit;
|
||||
|
|
@ -432,7 +434,7 @@ int main(int argc, char *argv[])
|
|||
(void)argv;
|
||||
|
||||
#ifndef WOLFTPM2_NO_WRAPPER
|
||||
rc = TPM2_Wrapper_Test(TPM2_IoGetUserCtx());
|
||||
rc = TPM2_Wrapper_Test(NULL);
|
||||
#else
|
||||
printf("Wrapper code not compiled in\n");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ AC_DEFUN([AX_DEBUG],
|
|||
[ax_enable_debug=$enableval],
|
||||
[ax_enable_debug=no])
|
||||
|
||||
AS_IF([test "x$ax_enable_debug" = xyes],
|
||||
AS_IF([test "x$ax_enable_debug" != "xno"],
|
||||
[AC_DEFINE([DEBUG],[1],[Define to 1 to enable debugging code.])],
|
||||
[AC_SUBST([MCHECK])
|
||||
AC_DEFINE([DEBUG],[0],[Define to 1 to enable debugging code.])])
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@
|
|||
AX_APPEND_COMPILE_FLAGS([-Werror],[ax_append_compile_cflags_extra])
|
||||
])
|
||||
|
||||
AS_IF([test "$ax_enable_debug" = "yes"], [
|
||||
AS_IF([test "$ax_enable_debug" != "no"], [
|
||||
AX_APPEND_COMPILE_FLAGS([-g])
|
||||
AX_APPEND_COMPILE_FLAGS([-ggdb],,[$ax_append_compile_cflags_extra])
|
||||
AX_APPEND_COMPILE_FLAGS([-O0],,[$ax_append_compile_cflags_extra])
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
AX_APPEND_COMPILE_FLAGS([-Werror],[ax_append_compile_cxxflags_extra])
|
||||
])
|
||||
|
||||
AS_IF([test "$ax_enable_debug" = "yes" ], [
|
||||
AS_IF([test "$ax_enable_debug" != "no" ], [
|
||||
AX_APPEND_COMPILE_FLAGS([-g],,[$ax_append_compile_cxxflags_extra])
|
||||
AX_APPEND_COMPILE_FLAGS([-O0],,[$ax_append_compile_cxxflags_extra])
|
||||
AX_APPEND_COMPILE_FLAGS([-ggdb],,[$ax_append_compile_cxxflags_extra])
|
||||
|
|
|
|||
106
src/tpm2_tis.c
106
src/tpm2_tis.c
|
|
@ -27,9 +27,6 @@
|
|||
/* --- BEGIN TPM Interface Specification (TIS) Layer */
|
||||
/******************************************************************************/
|
||||
|
||||
#define TPM_TIS_SPI_READ 0x80
|
||||
#define TPM_TIS_SPI_WRITE 0x00
|
||||
|
||||
enum tpm_tis_access {
|
||||
TPM_ACCESS_VALID = 0x80,
|
||||
TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
|
||||
|
|
@ -60,13 +57,18 @@ enum tpm_tis_int_flags {
|
|||
TPM_INTF_DATA_AVAIL_INT = 0x001,
|
||||
};
|
||||
|
||||
|
||||
#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))
|
||||
#define TPM_INT_VECTOR(l) (TPM_BASE_ADDRESS | 0x000Cu | ((l) << 12u))
|
||||
#define TPM_INT_STATUS(l) (TPM_BASE_ADDRESS | 0x0010u | ((l) << 12u))
|
||||
#if defined(WOLFTPM_ST33) && defined(WOLFTPM_I2C)
|
||||
#define TPM_INTF_CAPS(l) (TPM_BASE_ADDRESS | 0x0030u | ((l) << 12u))
|
||||
#else
|
||||
#define TPM_INTF_CAPS(l) (TPM_BASE_ADDRESS | 0x0014u | ((l) << 12u))
|
||||
#endif
|
||||
#define TPM_STS(l) (TPM_BASE_ADDRESS | 0x0018u | ((l) << 12u))
|
||||
#define TPM_BURST_COUNT(l) (TPM_BASE_ADDRESS | 0x0019u | ((l) << 12u))
|
||||
#define TPM_DATA_FIFO(l) (TPM_BASE_ADDRESS | 0x0024u | ((l) << 12u))
|
||||
|
|
@ -76,47 +78,60 @@ enum tpm_tis_int_flags {
|
|||
#define TPM_RID(l) (TPM_BASE_ADDRESS | 0x0F04u | ((l) << 12u))
|
||||
|
||||
|
||||
int TPM2_TIS_SpiRead(TPM2_CTX* ctx, word32 addr, byte* result,
|
||||
int TPM2_TIS_Read(TPM2_CTX* ctx, word32 addr, byte* result,
|
||||
word32 len)
|
||||
{
|
||||
int rc;
|
||||
byte txBuf[MAX_SPI_FRAMESIZE+4];
|
||||
byte rxBuf[MAX_SPI_FRAMESIZE+4];
|
||||
#ifndef WOLFTPM_ADV_IO
|
||||
byte txBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
||||
byte rxBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
||||
#endif
|
||||
|
||||
if (ctx == NULL || result == NULL || len == 0 || len > MAX_SPI_FRAMESIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
txBuf[0] = TPM_TIS_SPI_READ | ((len & 0xFF) - 1);
|
||||
#ifdef WOLFTPM_ADV_IO
|
||||
rc = ctx->ioCb(ctx, TPM_TIS_READ, addr, result, len, ctx->userCtx);
|
||||
#else
|
||||
txBuf[0] = TPM_TIS_READ | ((len & 0xFF) - 1);
|
||||
txBuf[1] = (addr>>16) & 0xFF;
|
||||
txBuf[2] = (addr>>8) & 0xFF;
|
||||
txBuf[3] = (addr) & 0xFF;
|
||||
XMEMSET(&txBuf[4], 0, len);
|
||||
txBuf[4] = 0x00;
|
||||
XMEMSET(&txBuf[TPM_TIS_HEADER_SZ], 0, len);
|
||||
|
||||
rc = ctx->ioCb(ctx, txBuf, rxBuf, len + 4, ctx->userCtx);
|
||||
rc = ctx->ioCb(ctx, txBuf, rxBuf, len + TPM_TIS_HEADER_SZ, ctx->userCtx);
|
||||
|
||||
XMEMCPY(result, &rxBuf[4], len);
|
||||
XMEMCPY(result, &rxBuf[TPM_TIS_HEADER_SZ], len);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TPM2_TIS_SpiWrite(TPM2_CTX* ctx, word32 addr, const byte* value,
|
||||
int TPM2_TIS_Write(TPM2_CTX* ctx, word32 addr, const byte* value,
|
||||
word32 len)
|
||||
{
|
||||
int rc;
|
||||
byte txBuf[MAX_SPI_FRAMESIZE+4];
|
||||
byte rxBuf[MAX_SPI_FRAMESIZE+4];
|
||||
#ifndef WOLFTPM_ADV_IO
|
||||
byte txBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
||||
byte rxBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
||||
#endif
|
||||
|
||||
if (ctx == NULL || value == NULL || len == 0 || len > MAX_SPI_FRAMESIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
txBuf[0] = TPM_TIS_SPI_WRITE | ((len & 0xFF) - 1);
|
||||
#ifdef WOLFTPM_ADV_IO
|
||||
rc = ctx->ioCb(ctx, TPM_TIS_WRITE, addr, (byte*)value, len, ctx->userCtx);
|
||||
#else
|
||||
txBuf[0] = TPM_TIS_WRITE | ((len & 0xFF) - 1);
|
||||
txBuf[1] = (addr>>16) & 0xFF;
|
||||
txBuf[2] = (addr>>8) & 0xFF;
|
||||
txBuf[3] = (addr) & 0xFF;
|
||||
XMEMCPY(&txBuf[4], value, len);
|
||||
|
||||
rc = ctx->ioCb(ctx, txBuf, rxBuf, len + 4, ctx->userCtx);
|
||||
txBuf[4] = 0x00;
|
||||
XMEMCPY(&txBuf[TPM_TIS_HEADER_SZ], value, len);
|
||||
|
||||
rc = ctx->ioCb(ctx, txBuf, rxBuf, len + TPM_TIS_HEADER_SZ, ctx->userCtx);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +141,7 @@ int TPM2_TIS_StartupWait(TPM2_CTX* ctx, int timeout)
|
|||
byte access = 0;
|
||||
|
||||
do {
|
||||
rc = TPM2_TIS_SpiRead(ctx, TPM_ACCESS(0), &access, sizeof(access));
|
||||
rc = TPM2_TIS_Read(ctx, TPM_ACCESS(0), &access, sizeof(access));
|
||||
if (rc == TPM_RC_SUCCESS && (access & TPM_ACCESS_VALID))
|
||||
return TPM_RC_SUCCESS;
|
||||
XTPM_WAIT();
|
||||
|
|
@ -138,7 +153,7 @@ int TPM2_TIS_StartupWait(TPM2_CTX* ctx, int timeout)
|
|||
|
||||
int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality, byte* access)
|
||||
{
|
||||
return TPM2_TIS_SpiRead(ctx, TPM_ACCESS(locality), access, sizeof(*access));
|
||||
return TPM2_TIS_Read(ctx, TPM_ACCESS(locality), access, sizeof(*access));
|
||||
}
|
||||
|
||||
static int TPM2_TIS_CheckLocalityAccessValid(TPM2_CTX* ctx, int locality,
|
||||
|
|
@ -166,7 +181,7 @@ int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout)
|
|||
}
|
||||
|
||||
access = TPM_ACCESS_REQUEST_USE;
|
||||
rc = TPM2_TIS_SpiWrite(ctx, TPM_ACCESS(locality), &access, sizeof(access));
|
||||
rc = TPM2_TIS_Write(ctx, TPM_ACCESS(locality), &access, sizeof(access));
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
do {
|
||||
access = 0;
|
||||
|
|
@ -177,7 +192,7 @@ int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout)
|
|||
return rc;
|
||||
}
|
||||
XTPM_WAIT();
|
||||
} while (rc == TPM_RC_SUCCESS && --timeout > 0);
|
||||
} while (rc < 0 && --timeout > 0);
|
||||
if (timeout <= 0)
|
||||
return TPM_RC_TIMEOUT;
|
||||
}
|
||||
|
|
@ -190,20 +205,20 @@ int TPM2_TIS_GetInfo(TPM2_CTX* ctx)
|
|||
int rc;
|
||||
word32 reg;
|
||||
|
||||
rc = TPM2_TIS_SpiRead(ctx, TPM_INTF_CAPS(ctx->locality), (byte*)®,
|
||||
rc = TPM2_TIS_Read(ctx, TPM_INTF_CAPS(ctx->locality), (byte*)®,
|
||||
sizeof(reg));
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
ctx->caps = reg;
|
||||
}
|
||||
|
||||
rc = TPM2_TIS_SpiRead(ctx, TPM_DID_VID(ctx->locality), (byte*)®,
|
||||
rc = TPM2_TIS_Read(ctx, TPM_DID_VID(ctx->locality), (byte*)®,
|
||||
sizeof(reg));
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
ctx->did_vid = reg;
|
||||
}
|
||||
|
||||
reg = 0;
|
||||
rc = TPM2_TIS_SpiRead(ctx, TPM_RID(ctx->locality), (byte*)®, 1);
|
||||
rc = TPM2_TIS_Read(ctx, TPM_RID(ctx->locality), (byte*)®, 1);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
ctx->rid = reg;
|
||||
}
|
||||
|
|
@ -213,7 +228,7 @@ int TPM2_TIS_GetInfo(TPM2_CTX* ctx)
|
|||
|
||||
int TPM2_TIS_Status(TPM2_CTX* ctx, byte* status)
|
||||
{
|
||||
return TPM2_TIS_SpiRead(ctx, TPM_STS(ctx->locality), status,
|
||||
return TPM2_TIS_Read(ctx, TPM_STS(ctx->locality), status,
|
||||
sizeof(*status));
|
||||
}
|
||||
|
||||
|
|
@ -237,20 +252,26 @@ int TPM2_TIS_WaitForStatus(TPM2_CTX* ctx, byte status, byte status_mask)
|
|||
int TPM2_TIS_Ready(TPM2_CTX* ctx)
|
||||
{
|
||||
byte status = TPM_STS_COMMAND_READY;
|
||||
return TPM2_TIS_SpiWrite(ctx, TPM_STS(ctx->locality), &status, sizeof(status));
|
||||
return TPM2_TIS_Write(ctx, TPM_STS(ctx->locality), &status, sizeof(status));
|
||||
}
|
||||
|
||||
int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx, word16* burstCount)
|
||||
{
|
||||
int rc;;
|
||||
int rc = TPM_RC_SUCCESS;
|
||||
#ifndef WOLFTPM_ST33
|
||||
int timeout = TPM_TIMEOUT_TRIES;
|
||||
#endif
|
||||
|
||||
if (burstCount == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFTPM_ST33
|
||||
*burstCount = 32; /* fixed value */
|
||||
(void)ctx;
|
||||
#else
|
||||
*burstCount = 0;
|
||||
do {
|
||||
rc = TPM2_TIS_SpiRead(ctx, TPM_BURST_COUNT(ctx->locality),
|
||||
rc = TPM2_TIS_Read(ctx, TPM_BURST_COUNT(ctx->locality),
|
||||
(byte*)burstCount, sizeof(*burstCount));
|
||||
if (rc == TPM_RC_SUCCESS && *burstCount > 0)
|
||||
break;
|
||||
|
|
@ -262,6 +283,7 @@ int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx, word16* burstCount)
|
|||
|
||||
if (timeout <= 0)
|
||||
return TPM_RC_TIMEOUT;
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -280,18 +302,18 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
|
||||
/* Make sure TPM is ready for command */
|
||||
rc = TPM2_TIS_Status(ctx, &status);
|
||||
if (rc != 0)
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
goto exit;
|
||||
if ((status & TPM_STS_COMMAND_READY) == 0) {
|
||||
/* Tell TPM chip to expect a command */
|
||||
rc = TPM2_TIS_Ready(ctx);
|
||||
if (rc != 0)
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
goto exit;
|
||||
|
||||
/* Wait for command ready (TPM_STS_COMMAND_READY = 1) */
|
||||
rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_COMMAND_READY,
|
||||
TPM_STS_COMMAND_READY);
|
||||
if (rc != 0)
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
|
@ -306,7 +328,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
if (xferSz > burstCount)
|
||||
xferSz = burstCount;
|
||||
|
||||
rc = TPM2_TIS_SpiWrite(ctx, TPM_DATA_FIFO(ctx->locality), &cmd[pos],
|
||||
rc = TPM2_TIS_Write(ctx, TPM_DATA_FIFO(ctx->locality), &cmd[pos],
|
||||
xferSz);
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
goto exit;
|
||||
|
|
@ -316,7 +338,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
/* Wait for expect more data (TPM_STS_DATA_EXPECT = 1) */
|
||||
rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_EXPECT,
|
||||
TPM_STS_DATA_EXPECT);
|
||||
if (rc != 0) {
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("TPM2_TIS_SendCommand write expected more data!\n");
|
||||
#endif
|
||||
|
|
@ -325,6 +347,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef WOLFTPM_ST33
|
||||
/* Wait for TPM_STS_DATA_EXPECT = 0 and TPM_STS_VALID = 1 */
|
||||
rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_EXPECT | TPM_STS_VALID,
|
||||
TPM_STS_VALID);
|
||||
|
|
@ -334,10 +357,11 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
#endif
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Execute Command */
|
||||
access = TPM_STS_GO;
|
||||
rc = TPM2_TIS_SpiWrite(ctx, TPM_STS(ctx->locality), &access,
|
||||
rc = TPM2_TIS_Write(ctx, TPM_STS(ctx->locality), &access,
|
||||
sizeof(access));
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
goto exit;
|
||||
|
|
@ -349,7 +373,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
/* Wait for data to be available (TPM_STS_DATA_AVAIL = 1) */
|
||||
rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_AVAIL,
|
||||
TPM_STS_DATA_AVAIL);
|
||||
if (rc != 0) {
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("TPM2_TIS_SendCommand read no data available!\n");
|
||||
#endif
|
||||
|
|
@ -364,7 +388,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
if (xferSz > burstCount)
|
||||
xferSz = burstCount;
|
||||
|
||||
rc = TPM2_TIS_SpiRead(ctx, TPM_DATA_FIFO(ctx->locality), &cmd[pos],
|
||||
rc = TPM2_TIS_Read(ctx, TPM_DATA_FIFO(ctx->locality), &cmd[pos],
|
||||
xferSz);
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
goto exit;
|
||||
|
|
@ -375,6 +399,12 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
if (pos == (int)sizeof(TPM2_HEADER)) {
|
||||
TPM2_HEADER* header = (TPM2_HEADER*)cmd;
|
||||
rspSz = TPM2_Packet_SwapU32(header->size);
|
||||
|
||||
/* safety check for stuck FFFF case */
|
||||
if (rspSz == 0xFFFF) {
|
||||
rc = TPM_RC_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -383,12 +413,12 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz)
|
|||
TPM2_PrintBin(cmd, rspSz);
|
||||
#endif
|
||||
|
||||
rc = 0;
|
||||
rc = TPM_RC_SUCCESS;
|
||||
|
||||
exit:
|
||||
|
||||
/* Tell TPM we are done */
|
||||
if (rc == 0)
|
||||
if (rc == TPM_RC_SUCCESS)
|
||||
rc = TPM2_TIS_Ready(ctx);
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -1601,8 +1601,19 @@ typedef struct TPMS_AUTH_RESPONSE {
|
|||
/* HAL IO Callbacks */
|
||||
struct TPM2_CTX;
|
||||
|
||||
typedef int (*TPM2HalIoCb)(struct TPM2_CTX*, const BYTE*, BYTE*, UINT16 size,
|
||||
void* userCtx);
|
||||
/* make sure advanced IO is enabled for I2C */
|
||||
#ifdef WOLFTPM_I2C
|
||||
#undef WOLFTPM_ADV_IO
|
||||
#define WOLFTPM_ADV_IO
|
||||
#endif
|
||||
|
||||
#ifdef WOLFTPM_ADV_IO
|
||||
typedef int (*TPM2HalIoCb)(struct TPM2_CTX*, INT32 isRead, UINT32 addr,
|
||||
BYTE* xferBuf, UINT16 xferSz, void* userCtx);
|
||||
#else
|
||||
typedef int (*TPM2HalIoCb)(struct TPM2_CTX*, const BYTE* txBuf, BYTE* rxBuf,
|
||||
UINT16 xferSz, void* userCtx);
|
||||
#endif
|
||||
|
||||
typedef struct TPM2_CTX {
|
||||
TPM2HalIoCb ioCb;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,18 @@
|
|||
#define WOLFTPM_LOCALITY_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#define TPM_TIS_READ 0x80
|
||||
#define TPM_TIS_WRITE 0x00
|
||||
|
||||
#ifdef WOLFTPM_ST33
|
||||
#define TPM_TIS_HEADER_SZ 5
|
||||
#else
|
||||
#define TPM_TIS_HEADER_SZ 4
|
||||
#endif
|
||||
|
||||
#define TPM_TIS_READY_MASK 0x01
|
||||
|
||||
|
||||
WOLFTPM_LOCAL int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx, word16* burstCount);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_Ready(TPM2_CTX* ctx);
|
||||
|
|
@ -39,7 +51,7 @@ WOLFTPM_LOCAL int TPM2_TIS_GetInfo(TPM2_CTX* ctx);
|
|||
WOLFTPM_LOCAL int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality, byte* access);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_StartupWait(TPM2_CTX* ctx, int timeout);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_SpiWrite(TPM2_CTX* ctx, word32 addr, const byte* value, word32 len);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_SpiRead(TPM2_CTX* ctx, word32 addr, byte* result, word32 len);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_Write(TPM2_CTX* ctx, word32 addr, const byte* value, word32 len);
|
||||
WOLFTPM_LOCAL int TPM2_TIS_Read(TPM2_CTX* ctx, word32 addr, byte* result, word32 len);
|
||||
|
||||
#endif /* __TPM2_TIS_H__ */
|
||||
|
|
|
|||
|
|
@ -141,6 +141,10 @@ typedef int64_t INT64;
|
|||
#define TPM_TIMEOUT_TRIES 1000000
|
||||
#endif
|
||||
|
||||
#ifndef TPM_SPI_WAIT_RETRY
|
||||
#define TPM_SPI_WAIT_RETRY 50
|
||||
#endif
|
||||
|
||||
#ifndef MAX_SYM_BLOCK_SIZE
|
||||
#define MAX_SYM_BLOCK_SIZE 20
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue