mirror of https://github.com/wolfSSL/wolfTPM.git
Support for QNX with wolfTPM:
* Fix for `wolfTPM2_NVCreateAuth` to return `TPM_RC_NV_DEFINED` if already exists (it used to do this, but broke with GPIO changes). * Fixes for building wolfTPM with wolfCrypt only (no TLS). * Fix for building without RSA and ECC. * Fix for `--enable-smallstack` with parameter encryption, * Fix for nvram/store unused variable.pull/156/head
parent
55a22350c9
commit
ed1ec8c52d
|
@ -0,0 +1,165 @@
|
|||
# wolfTPM with QNX
|
||||
|
||||
Instructions for creating a QNX Momentics wolfTPM Project...
|
||||
|
||||
## Create a new QNX Application
|
||||
|
||||
1) Create folder for libraries (lib) and includes (inc)
|
||||
2) Add library sources into "lib" directory as "wolfssl" and "wolftpm"
|
||||
3) Edit Makefile to build sources and include directories.
|
||||
|
||||
```
|
||||
# wolfSSL and wolfTPM library includes/sources
|
||||
INCLUDES += -I./inc -I./lib/wolftpm -I./lib/wolfssl
|
||||
CCFLAGS_all += -DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS
|
||||
|
||||
SRCS += $(call wildcard, lib/wolfssl/wolfcrypt/src/*.c)
|
||||
SRCS += $(call wildcard, lib/wolfssl/wolfcrypt/src/port/arm/*.c)
|
||||
SRCS += $(call wildcard, lib/wolfssl/wolfcrypt/src/port/xilinx/*.c)
|
||||
SRCS += $(call wildcard, lib/wolftpm/src/*.c)
|
||||
|
||||
# The QNX SPI Driver
|
||||
LIBS += -lspi-master
|
||||
```
|
||||
|
||||
4) Create `inc/user_settings.h` for all wolf specific settings:
|
||||
|
||||
Here is a template:
|
||||
|
||||
```
|
||||
#ifndef WOLF_USER_SETTINGS_H
|
||||
#define WOLF_USER_SETTINGS_H
|
||||
|
||||
/* TPM */
|
||||
#define WOLFTPM_AUTODETECT
|
||||
#define WOLFTPM_CHECK_WAIT_STATE
|
||||
#define WOLFTPM_ADV_IO /* use advanced IO HAL callback */
|
||||
#define TPM_TIMEOUT_TRIES 100000
|
||||
|
||||
/* always perform self-test (some chips require) */
|
||||
#define WOLFTPM_PERFORM_SELFTEST
|
||||
|
||||
/* Reduce stack use */
|
||||
#define MAX_COMMAND_SIZE 1024
|
||||
#define MAX_RESPONSE_SIZE 1024
|
||||
#define WOLFTPM2_MAX_BUFFER 1500
|
||||
#define MAX_DIGEST_BUFFER 973
|
||||
|
||||
/* Debugging */
|
||||
#if 1
|
||||
#define DEBUG_WOLFTPM
|
||||
//#define WOLFTPM_DEBUG_VERBOSE
|
||||
//#define WOLFTPM_DEBUG_IO
|
||||
//#define WOLFTPM_DEBUG_TIMEOUT
|
||||
#endif
|
||||
|
||||
/* Platform */
|
||||
#define WOLFCRYPT_ONLY
|
||||
#define SINGLE_THREADED
|
||||
#define NO_FILESYSTEM
|
||||
#define WOLFSSL_IGNORE_FILE_WARN
|
||||
#define WOLFSSL_HAVE_MIN
|
||||
#define WOLFSSL_HAVE_MAX
|
||||
|
||||
/* Math */
|
||||
#define ECC_TIMING_RESISTANT
|
||||
#define TFM_TIMING_RESISTANT
|
||||
#define USE_FAST_MATH
|
||||
#define FP_MAX_BITS (2 * 4096)
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
#define ALT_ECC_SIZE
|
||||
|
||||
/* Enables */
|
||||
#define HAVE_ECC
|
||||
#define ECC_SHAMIR
|
||||
#define HAVE_AESGCM
|
||||
#define GCM_TABLE_4BIT
|
||||
|
||||
/* Disables */
|
||||
#define NO_MAIN_DRIVER
|
||||
#define NO_WOLFSSL_MEMORY
|
||||
#define NO_ASN
|
||||
#define NO_ASN_TIME
|
||||
#define NO_CODING
|
||||
#define NO_CERTS
|
||||
#define NO_PSK
|
||||
|
||||
#define NO_PWDBASED
|
||||
#define NO_DSA
|
||||
#define NO_RC4
|
||||
#define NO_MD4
|
||||
#define NO_MD5
|
||||
#define NO_SHA
|
||||
#define NO_HC128
|
||||
#define NO_RABBIT
|
||||
#define NO_DES3
|
||||
|
||||
#endif /* !WOLF_USER_SETTINGS_H */
|
||||
```
|
||||
|
||||
5) wolfTPM HAL: Use either `tpm_io.c` directly or copy the required HAL interface into your own .c.
|
||||
|
||||
6) Add wolfTPM example code into your own .c.
|
||||
|
||||
7) Consider QNX BSP SPI master patch for handling multiple calls with CS asserted, which is required for the SPI wait states.
|
||||
|
||||
## QNX SPI Master Patch for Manual Chip Select
|
||||
|
||||
Edit the following QNX BSP files:
|
||||
|
||||
1) `bsp/src/hardware/spi/xzynq/aarch64/dll.le.zcu102/xzynq_spi.c`
|
||||
|
||||
```
|
||||
@@ -442,7 +442,7 @@ static void xzynq_setup(xzynq_spi_t *dev, uint32_t device)
|
||||
spi_debug1("%s: CONFIG_SPI_REG = 0x%x", __func__, dev->ctrl[id]);
|
||||
#endif
|
||||
|
||||
- if(dev->fcs) {
|
||||
+ if(dev->fcs || (devlist[id].cfg.mode & SPI_MODE_MAN_CS)) {
|
||||
out32(base + XZYNQ_SPI_CR_OFFSET, dev->ctrl[id] | XZYNQ_SPI_CR_MAN_CS);
|
||||
} else {
|
||||
out32(base + XZYNQ_SPI_CR_OFFSET, dev->ctrl[id]);
|
||||
@@ -621,7 +621,7 @@ void *xzynq_xfer(void *hdl, uint32_t device, uint8_t *buf, int *len)
|
||||
reset = 1;
|
||||
}
|
||||
|
||||
- if(!dev->fcs) {
|
||||
+ if(!dev->fcs && !(devlist[id].cfg.mode & SPI_MODE_MAN_CS)) {
|
||||
xzynq_spi_slave_select(dev, id, 0);
|
||||
}
|
||||
```
|
||||
|
||||
2) `bsp/src/hardware/spi/xzynq/config.c`
|
||||
|
||||
```
|
||||
@@ -72,6 +73,16 @@ int xzynq_cfg(void *hdl, spi_cfg_t *cfg, int cs)
|
||||
/* Enable ModeFail generation */
|
||||
ctrl |= XZYNQ_SPI_CR_MFAIL_EN;
|
||||
|
||||
+ if (cfg->mode & SPI_MODE_MAN_CS)
|
||||
+ ctrl |= XZYNQ_SPI_CR_MAN_CS; /* enable manual CS mode */
|
||||
+
|
||||
+ if (cfg->mode & SPI_MODE_CLEAR_CS) {
|
||||
+ /* make sure all chip selects are de-asserted */
|
||||
+ /* set all CS bits high to de-assert */
|
||||
+ out32(base + XZYNQ_SPI_CR_OFFSET,
|
||||
+ in32(base + XZYNQ_SPI_CR_OFFSET) | XZYNQ_SPI_CR_CS);
|
||||
+ }
|
||||
+
|
||||
```
|
||||
|
||||
3) `target/qnx7/usr/include/hw/spi-master.h`
|
||||
|
||||
```
|
||||
@@ -71,6 +71,8 @@ typedef struct {
|
||||
#define SPI_MODE_RDY_LEVEL (2 << 14) /* Low level signal */
|
||||
#define SPI_MODE_IDLE_INSERT (1 << 16)
|
||||
+#define SPI_MODE_MAN_CS (1 << 17) /* Manual Chip select */
|
||||
+#define SPI_MODE_CLEAR_CS (1 << 18) /* Clear all chip selects (used with SPI_MODE_MAN_CS) */
|
||||
|
||||
#define SPI_MODE_LOCKED (1 << 31) /* The device is locked by another client */
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For questions please email support@wolfssl.com
|
|
@ -0,0 +1,5 @@
|
|||
# vim:ft=automake
|
||||
# included from Top Level Makefile.am
|
||||
# All paths should be given relative to the root
|
||||
|
||||
EXTRA_DIST+= IDE/QNX/README.md
|
|
@ -4,3 +4,4 @@
|
|||
|
||||
include IDE/OPENSTM32/include.am
|
||||
include IDE/IAR-EWARM/include.am
|
||||
include IDE/QNX/include.am
|
||||
|
|
|
@ -341,7 +341,13 @@ then
|
|||
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SMALL_STACK"
|
||||
|
||||
# Reduces max packet and buffer sizes to 1024 bytes
|
||||
AM_CFLAGS="$AM_CFLAGS -DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 -DMAX_SESSION_NUM=1 -DMAX_DIGEST_BUFFER=973"
|
||||
AM_CFLAGS="$AM_CFLAGS -DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 -DMAX_DIGEST_BUFFER=973"
|
||||
|
||||
# If parameter encryption is not used then maximum session count is one
|
||||
if test "x$ENABLED_WOLFCRYPT" = "xno"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DMAX_SESSION_NUM=1"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Runtime Module Detection
|
||||
|
|
|
@ -218,7 +218,7 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[])
|
|||
/* Define NV Index for GPIO */
|
||||
rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, nvIndex, nvAttributes,
|
||||
sizeof(BYTE), (byte*)gNvAuth, sizeof(gNvAuth)-1);
|
||||
if (rc != 0) {
|
||||
if (rc != 0 && rc != TPM_RC_NV_DEFINED) {
|
||||
printf("Creating NV Index for GPIO acccess failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ static void usage(void)
|
|||
{
|
||||
printf("Expected usage:\n");
|
||||
printf("./examples/seal/unseal [filename]\n");
|
||||
printf("* filename - File containg a TPM seal key\n");
|
||||
printf("* filename - File contaning a TPM seal key\n");
|
||||
printf("Demo usage, without arguments, uses keyblob.bin file input.\n");
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
int rc = -1;
|
||||
|
||||
#ifndef WOLFTPM2_NO_WRAPPER
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(NO_FILESYSTEM)
|
||||
rc = TPM2_Unseal_Example(NULL, argc, argv);
|
||||
#else
|
||||
printf("Wrapper code not compiled in\n");
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <wolftpm/tpm2_wrap.h>
|
||||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
|
||||
!defined(NO_WOLFSSL_CLIENT)
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(WOLFCRYPT_ONLY)
|
||||
|
||||
#include <examples/tpm_io.h>
|
||||
#include <examples/tpm_test.h>
|
||||
|
@ -305,7 +305,7 @@ int main(int argc, char *argv[])
|
|||
int rc = -1;
|
||||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
|
||||
!defined(NO_WOLFSSL_CLIENT)
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(WOLFCRYPT_ONLY)
|
||||
rc = TLS_ClientArgs(argc, argv);
|
||||
#else
|
||||
printf("WolfSSL Client code not compiled in\n");
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <wolftpm/tpm2.h>
|
||||
#include <wolftpm/tpm2_wrap.h>
|
||||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT)
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFCRYPT_ONLY)
|
||||
|
||||
#include <wolftpm/tpm2_socket.h>
|
||||
|
||||
|
|
|
@ -101,6 +101,13 @@
|
|||
#include <spi/spi.h>
|
||||
#include <spi/spi_gpio.h>
|
||||
|
||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||
/* QNX */
|
||||
#include "hw/spi-master.h"
|
||||
#ifndef TPM2_SPI_DEV
|
||||
#define TPM2_SPI_DEV "/dev/spi0"
|
||||
#endif
|
||||
|
||||
#elif defined(__XILINX__)
|
||||
|
||||
#include "xspips.h"
|
||||
|
@ -623,6 +630,95 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||
|
||||
/* customization to QNX SPI master to allow keeping
|
||||
CS asserted (low) till spi_close. See IDE/QNX for spi_master patch */
|
||||
#ifndef SPI_MODE_MAN_CS
|
||||
#define SPI_MODE_MAN_CS (1 << 17) /* Manual Chip select */
|
||||
#endif
|
||||
#ifndef SPI_MODE_CLEAR_CS
|
||||
#define SPI_MODE_CLEAR_CS (1 << 18) /* Clear all chip selects (used with SPI_MODE_MAN_CS) */
|
||||
#endif
|
||||
static int TPM2_IoCb_QNX_SPI(TPM2_CTX* ctx, const byte* txBuf,
|
||||
byte* rxBuf, word16 xferSz, void* userCtx)
|
||||
{
|
||||
int fd;
|
||||
int ret = TPM_RC_FAILURE;
|
||||
int status;
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
int timeout = TPM_SPI_WAIT_RETRY;
|
||||
#endif
|
||||
spi_cfg_t cfg;
|
||||
|
||||
/* open device */
|
||||
fd = spi_open(TPM2_SPI_DEV);
|
||||
if (fd == -1) {
|
||||
return TPM_RC_FAILURE;
|
||||
}
|
||||
XMEMSET(&cfg, 0, sizeof(cfg));
|
||||
cfg.mode = 8; /* 8-bits - CPOL=0/CPHA=0 */
|
||||
cfg.mode |= SPI_MODE_MAN_CS; /* manual chip select - leave asserted */
|
||||
cfg.clock_rate = TPM2_SPI_HZ;
|
||||
status = spi_setcfg(fd, SPI_DEV_DEFAULT, &cfg);
|
||||
if (status != 0) {
|
||||
spi_close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
||||
/* Send Header */
|
||||
status = spi_xchange(fd, SPI_DEV_DEFAULT,
|
||||
(byte*)txBuf, rxBuf, TPM_TIS_HEADER_SZ);
|
||||
if (status == -1) {
|
||||
spi_close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check for wait states */
|
||||
if ((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0) {
|
||||
do {
|
||||
/* Check for SPI ready */
|
||||
status = spi_xchange(fd, SPI_DEV_DEFAULT,
|
||||
(byte*)txBuf, rxBuf, 1);
|
||||
if (status != -1 && rxBuf[0] & TPM_TIS_READY_MASK)
|
||||
break;
|
||||
} while (--timeout > 0);
|
||||
#ifdef WOLFTPM_DEBUG_TIMEOUT
|
||||
printf("SPI Ready Wait %d\n", TPM_SPI_WAIT_RETRY - timeout);
|
||||
#endif
|
||||
if (timeout <= 0) {
|
||||
spi_close(fd);
|
||||
return TPM_RC_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send remainder of payload */
|
||||
status = spi_xchange(fd, SPI_DEV_DEFAULT,
|
||||
(byte*)&txBuf[TPM_TIS_HEADER_SZ],
|
||||
&rxBuf[TPM_TIS_HEADER_SZ],
|
||||
xferSz - TPM_TIS_HEADER_SZ);
|
||||
|
||||
/* inform spi_master we are done... de-assert SPI */
|
||||
cfg.mode |= (SPI_MODE_MAN_CS | SPI_MODE_CLEAR_CS);
|
||||
(void)spi_setcfg(fd, SPI_DEV_DEFAULT, &cfg);
|
||||
#else
|
||||
/* Send Entire Message - no wait states */
|
||||
status = spi_xchange(fd, SPI_DEV_DEFAULT,
|
||||
(byte*)txBuf, rxBuf, xferSz);
|
||||
#endif /* WOLFTPM_CHECK_WAIT_STATE */
|
||||
if (status != -1) {
|
||||
ret = TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
spi_close(fd);
|
||||
|
||||
(void)userCtx;
|
||||
(void)ctx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(__XILINX__)
|
||||
|
||||
#define XSpiPs_SendByte(BaseAddress, Data) \
|
||||
|
@ -799,7 +895,6 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -817,6 +912,8 @@ static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
|||
ret = TPM2_IoCb_Atmel_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#elif defined(__BAREBOX__)
|
||||
ret = TPM2_IoCb_Barebox_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||
ret = TPM2_IoCb_QNX_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#elif defined(__XILINX__)
|
||||
ret = TPM2_IoCb_Xilinx_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
|
||||
#else
|
||||
|
|
|
@ -107,8 +107,10 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
|
|||
"\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7";
|
||||
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#if defined(HAVE_ECC) || !defined(NO_RSA)
|
||||
int tpmDevId = INVALID_DEVID;
|
||||
word32 idx;
|
||||
#endif
|
||||
#ifndef NO_RSA
|
||||
RsaKey wolfRsaPubKey;
|
||||
RsaKey wolfRsaPrivKey;
|
||||
|
|
|
@ -653,6 +653,7 @@ int wolfTPM2_EncryptSalt(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
|
|||
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
|
||||
|
||||
(void)bindAuth; /* TODO: Add bind support */
|
||||
(void)dev;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -2567,7 +2568,7 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
|
|||
WOLFTPM2_NV* nv, word32 nvIndex, word32 nvAttributes, word32 maxSize,
|
||||
const byte* auth, int authSz)
|
||||
{
|
||||
int rc;
|
||||
int rc, alreadyExists = 0;
|
||||
NV_DefineSpace_In in;
|
||||
|
||||
if (dev == NULL || nv == NULL)
|
||||
|
@ -2593,6 +2594,7 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
|
|||
|
||||
rc = TPM2_NV_DefineSpace(&in);
|
||||
if (rc == TPM_RC_NV_DEFINED) {
|
||||
alreadyExists = 1;
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("TPM2_NV_DefineSpace: handle already exists\n");
|
||||
#endif
|
||||
|
@ -2629,7 +2631,8 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
|
|||
in.publicInfo.nvPublic.dataSize);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
/* if handle already existed then return `TPM_RC_NV_DEFINED` */
|
||||
return (rc == TPM_RC_SUCCESS && alreadyExists) ? TPM_RC_NV_DEFINED : rc;
|
||||
}
|
||||
|
||||
/* older API kept for compatibility, recommend using wolfTPM2_NVCreateAuth */
|
||||
|
@ -2928,11 +2931,11 @@ int wolfTPM2_NVDelete(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle,
|
|||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
struct WC_RNG* wolfTPM2_GetRng(WOLFTPM2_DEV* dev)
|
||||
{
|
||||
#ifdef WOLFTPM2_USE_WOLF_RNG
|
||||
if (dev) {
|
||||
#ifdef WOLFTPM2_USE_WOLF_RNG
|
||||
return &dev->ctx.rng;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef _TPM2_SOCKET_H_
|
||||
#define _TPM2_SOCKET_H_
|
||||
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(WOLFCRYPT_ONLY)
|
||||
#include <wolfssl/wolfio.h>
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue