Merge pull request #172 from tomoveu/add-nuvoton-gpio

Add GPIO example for NPCT7xx
pull/180/head
David Garske 2021-07-12 15:08:31 -07:00 committed by GitHub
commit da5a1adf9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 485 additions and 60 deletions

1
.gitignore vendored
View File

@ -55,6 +55,7 @@ examples/nvram/read
examples/gpio/gpio_config
examples/gpio/gpio_set
examples/gpio/gpio_read
examples/gpio/gpio_nuvoton
examples/seal/seal
examples/seal/unseal
examples/attestation/make_credential

View File

@ -8,7 +8,7 @@ The PKCS #7 and TLS examples require generating CSR's and signing them using a t
To enable parameter encryption use `-aes` for AES-CFB mode or `-xor` for XOR mode. Only some TPM commands / responses support parameter encryption. If the TPM2_ API has .flags `CMD_FLAG_ENC2` or `CMD_FLAG_DEC2` set then the command will use parameter encryption / decryption.
There are some vendor specific examples, like the TPM 2.0 extra GPIO examples for ST33.
There are some vendor specific examples, like the TPM 2.0 extra GPIO examples for ST33 and NPCT75x.
## Native API Test
@ -427,22 +427,27 @@ mySecretMessage
After a successful unsealing, the data is stored into a new file. If no filename is provided, the `unseal` tool stores the data in `unseal.bin`.
## GPIO control
## GPIO Control
Some TPM 2.0 modules have extra I/O functionalities and additional GPIO that the developer could use. This extra GPIO could be used to signal other subsystems about security events or system states.
Currently, the GPIO control examples support only ST33 TPM 2.0 modules.
Currently, the GPIO control examples support ST33 and NPCT75x TPM 2.0 modules.
There are three examples available: `gpio/gpio_config`, `gpio/gpio_set`, `gpio/gpio_read`.
There are four examples available: `gpio/gpio_config` for ST33 and `gpio/gpio_nuvoton` for NPCT75x.
Every example has a help option `-h`. Please consult with `gpio_config -h` about the various GPIO modes.
Demo usage is available, when no parameters are supplied. Then, GPIO 0 is used in output mode.
Once configured, a GPIO can be controlled using `gpio/gpio_set` and `gpio/gpio_read`.
Demo usage is available, when no parameters are supplied. Recommended is to use carefully selected options, because GPIO interact with the physical world.
### GPIO Config
ST33 supports 6 modes, information from `gpio/gpio_config` below:
```
examples/gpio/gpio_config -h
$ ./examples/gpio/gpio_config -h
Expected usage:
./examples/gpio/gpio_config [num] [mode]
* num is a GPIO number between 0-3 (default 0)
@ -455,45 +460,81 @@ Expected usage:
5. pushpull - output in push pull configuration
6. unconfigure - delete the NV index for the selected GPIO
Example usage, without parameters, configures GPIO0 as input with a pull down.
```
Example usage for configuring a GPIO to output can be found below:
```
$ ./examples/gpio/gpio_config
$ ./examples/gpio/gpio_config 0 5
GPIO num is: 0
GPIO mode is: 5
Example how to use extra GPIO on a TPM 2.0 modules
wolfTPM2_Init: success
Trying to configure GPIO0...
TPM2_GPIO_Config success
NV Index for GPIO access created
$ ./examples/gpio/gpio_set
GPIO0 set to high level
```
Switching a GPIO configuration is seamless, because gpio/config takes care of deleting existing NV Index, so a new GPIO configuration can be chosen.
Example usage for configuring a GPIO as input with a pulp-up can be found below:
Example usage for configuring a GPIO as input with a pull-up on ST33 can be found below:
```
$ ./examples/gpio/gpio_config 0 3
GPIO num is: 0
GPIO mode is: 3
Demo how to use extra GPIO on a TPM 2.0 modules
wolfTPM2_Init: success
Trying to configure GPIO0...
TPM2_GPIO_Config success
NV Index for GPIO access created
$ ./examples/gpio/gpio_read 0
GPIO0 is Low
```
### GPIO Config (NPCT75xx)
NPCT75x supports 3 output modes, information from `gpio/gpio_nuvoton` below:
```
$ ./examples/gpio/gpio_nuvoton -h
Expected usage:
./examples/gpio/gpio_nuvoton [num] [mode]
* num is a GPIO number between 3 and 4 (default 3)
* mode is either push-pull, open-drain or open-drain with pull-up
1. pushpull - output in push pull configuration
2. opendrain - output in open drain configuration
3. pullup - output in open drain with pull-up enabled
4. unconfig - delete NV index for GPIO access
Example usage, without parameters, configures GPIO3 as push-pull output.
```
Please note that NPCT75x GPIO numbering starts from GPIO3, while ST33 starts from GPIO0.
```
$ ./examples/gpio/gpio_nuvoton 4 1
Example for GPIO configuration of a NPTC7xx TPM 2.0 module
GPIO number: 4
GPIO mode: 1
Successfully read the current configuration
Successfully wrote new configuration
NV Index for GPIO access created
```
### GPIO Usage
Switching a GPIO configuration is seamless.
* For ST33 `gpio/gpio_config` takes care of deleting existing NV Index, so a new GPIO configuration can be chosen.
* For NPCT75xx `gpio/gpio_nuvoton` can reconfigure any GPIO without deleting the created NV index.
```
$ ./examples/gpio/gpio_set 0 -high
GPIO0 set to high level
$ ./examples/gpio/gpio_set 0 -low
GPIO0 set to low level
```
```
$ ./examples/gpio/gpio_read 0
GPIO0 is Low
```
## Support
If you need more information about using these examples please contact us at support@wolfssl.com

View File

@ -26,14 +26,24 @@
extern "C" {
#endif
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_NUVOTON) || defined(WOLFTPM_AUTODETECT)
#define GPIO_NUM_MIN TPM_GPIO_A
#define GPIO_NUM_MAX (TPM_GPIO_COUNT-1) /* see wolftpm/tpm2.h */
#define GPIO_NUM_MAX TPM_GPIO_A+TPM_GPIO_COUNT-1 /* see wolftpm/tpm2.h */
#endif
#ifdef WOLFTPM_NUVOTON
/* Nuvoton GPIO Modes - only output */
#define NUVOTON_GPIO_MODE_PUSHPULL 1
#define NUVOTON_GPIO_MODE_OPENDRAIN 2
#define NUVOTON_GPIO_MODE_PULLUP 3
#define NUVOTON_GPIO_MODE_UNCONFIG 4 /* Not a real GPIO mode, deleting NV index */
#define NUVOTON_GPIO_MODE_MAX 4
#endif
int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[]);
int TPM2_GPIO_Read_Example(void* userCtx, int argc, char *argv[]);
int TPM2_GPIO_Set_Example(void* userCtx, int argc, char *argv[]);
int TPM2_GPIO_Nuvoton_Example(void* userCtx, int argc, char *argv[]);
#ifdef __cplusplus
} /* extern "C" */

View File

@ -150,7 +150,7 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[])
/* Enable TPM2_GPIO_Config command */
if (caps.mfg != TPM_MFG_STM) {
printf("Extra GPIO is supported only on ST33 TPM 2.0 modules\n");
printf("TPM model mismatch. GPIO support requires an ST33 TPM 2.0 module\n");
goto exit;
}
@ -255,7 +255,7 @@ int main(int argc, char *argv[])
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
rc = TPM2_GPIO_Config_Example(NULL, argc, argv);
#else
printf("Extra GPIO is supported only on ST33 TPM 2.0 modules.\n");
printf("GPIO configuration requires an ST33 TPM 2.0 module built with WOLFTPM_ST33 or --enable-st33\n");
(void)argc;
(void)argv;
#endif /* WOLFTPM_ST33 || WOLFTPM_AUTODETECT */

View File

@ -0,0 +1,248 @@
/* gpio_nuvoton.c
*
* Copyright (C) 2006-2021 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
*/
/* This examples demonstrates the use of GPIO available on
* Nuvoton TPM 2.0 Modules, e.g. NPCT750 with FW version 7.2.3
*/
#include <wolftpm/tpm2_wrap.h>
#if defined(WOLFTPM_NUVOTON)
#include <examples/gpio/gpio.h>
#include <examples/tpm_io.h>
#include <examples/tpm_test.h>
#include <stdio.h>
#include <stdlib.h> /* atoi */
/******************************************************************************/
/* --- BEGIN TPM2.0 GPIO Configuration example -- */
/******************************************************************************/
static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/gpio/gpio_nuvoton [num] [mode]\n");
printf("* num is a GPIO number between 3 and 4 (default %d)\n", GPIO_NUM_MIN);
printf("* mode is either push-pull, open-drain or open-drain with pull-up\n");
printf("\t1. pushpull - output in push pull configuration\n");
printf("\t2. opendrain - output in open drain configuration\n");
printf("\t3. pullup - output in open drain with pull-up enabled\n");
printf("\t4. unconfig - delete NV index for GPIO access\n");
printf("Example usage, without parameters, configures GPIO3 as push-pull output.\n");
}
int TPM2_GPIO_Nuvoton_Example(void* userCtx, int argc, char *argv[])
{
int rc = -1;
WOLFTPM2_DEV dev;
WOLFTPM2_CAPS caps;
WOLFTPM2_NV nv;
WOLFTPM2_HANDLE parent;
TPM_HANDLE nvIndex = TPM_NV_GPIO_SPACE;
word32 nvAttributes;
int gpioNum = 0;
int gpioMode = NUVOTON_GPIO_MODE_PUSHPULL;
/* Nuvoton specific structures */
CFG_STRUCT newConfig;
NTC2_GetConfig_Out getConfig;
NTC2_PreConfig_In preConfig;
if (argc >= 2) {
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
XSTRNCMP(argv[1], "-h", 2) == 0 ||
XSTRNCMP(argv[1], "--help", 6) == 0) {
usage();
return 0;
}
if (argc == 3) {
gpioMode = atoi(argv[2]);
if (gpioMode > NUVOTON_GPIO_MODE_MAX) {
printf("GPIO mode is out of range (1-3)\n");
usage();
goto exit_badargs;
}
/* Preparing to process next argument */
argc--;
}
if (argc == 2) {
gpioNum = atoi(argv[1]);
if (gpioNum < GPIO_NUM_MIN || gpioNum > GPIO_NUM_MAX) {
printf("GPIO is out of range (%d-%d)\n", GPIO_NUM_MIN, GPIO_NUM_MAX);
usage();
goto exit_badargs;
}
nvIndex = TPM_NV_GPIO_SPACE + (gpioNum-GPIO_NUM_MIN);
/* all arguments processed */
}
}
else if (argc == 1) {
/* Default behavior, without arguments: GPIO 3 as pushpull output */
gpioMode = NUVOTON_GPIO_MODE_PUSHPULL;
gpioNum = GPIO_NUM_MIN;
}
else {
printf("Incorrect arguments\n");
usage();
goto exit_badargs;
}
printf("Example for GPIO configuration of a NPTC7xx TPM 2.0 module\n");
printf("GPIO number: %d\n", gpioNum);
printf("GPIO mode: %d\n", gpioMode);
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
printf("wolfTPM2_Init: success\n");
/* Get TPM capabilities, to discover the TPM vendor */
rc = wolfTPM2_GetCapabilities(&dev, &caps);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_GetCapabilities failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
}
/* Confirm the TPM vendor */
if (caps.mfg != TPM_MFG_NUVOTON) {
printf("TPM model mismatch. GPIO support requires a Nuvoton NPCT7xx TPM 2.0 module\n");
goto exit;
}
/* GPIO un-configuration is done using NVDelete, no further action needed */
/* Nuvoton can reconfigure any GPIO without deleting the created NV index */
if (gpioMode == NUVOTON_GPIO_MODE_UNCONFIG) {
printf("Reconfiguration does not require to NV index deletion\n");
goto exit;
}
XMEMSET(&newConfig, 0, sizeof(newConfig));
XMEMSET(&getConfig, 0, sizeof(getConfig));
rc = TPM2_NTC2_GetConfig(&getConfig);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_NTC2_GetConfig failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
printf("Successfully read the current configuration\n");
XMEMCPY(&newConfig, &getConfig.preConfig, sizeof(newConfig));
#ifdef WOLFTPM_DEBUG_VERBOSE
printf("getConfig CFG_CONFIG structure:\n");
TPM2_PrintBin((byte*)&getConfig.preConfig, sizeof(getConfig.preConfig));
#endif
/* Prepare GPIO configuration according to Nuvoton requirements */
if(gpioMode == NUVOTON_GPIO_MODE_PUSHPULL) {
/* For NUVOTON_GPIO_MODE_PUSHPULL */
newConfig.GpioPushPull |= (1 << gpioNum);
}
else {
/* For NUVOTON_GPIO_MODE_OPENDRAIN or NUVOTON_GPIO_MODE_PULLUP */
newConfig.GpioPushPull &= ~(1 << gpioNum);
}
/* Set pull-up to disabled by default, configure below only if requested */
newConfig.GpioPullUp &= ~(1 << gpioNum);
/* Extra step for open-drain with pull-up mode */
if (gpioMode == NUVOTON_GPIO_MODE_PULLUP) {
newConfig.GpioPullUp &= ~(1 << gpioNum);
}
#ifdef WOLFTPM_DEBUG_VERBOSE
printf("newConfig CFG_CONFIG structure:\n");
TPM2_PrintBin((byte*)&newConfig, sizeof(newConfig));
#endif
/* Configuring a TPM GPIO requires a PLATFORM authorization. Afterwards,
* using that GPIO is up to the user. Therefore, NV Indexes are operated
* using OWNER authorization. See below NVCreateAuth.
*/
XMEMSET(&preConfig, 0, sizeof(preConfig));
preConfig.authHandle = TPM_RH_PLATFORM;
XMEMCPY(&preConfig.preConfig, &newConfig, sizeof(newConfig));
rc = TPM2_NTC2_PreConfig(&preConfig);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_NTC2_PreConfig failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
printf("Successfully wrote new configuration\n");
/* Configure NV Index for access to this GPIO */
XMEMSET(&nv, 0, sizeof(nv));
XMEMSET(&parent, 0, sizeof(parent));
/* Initial NV attributes */
parent.hndl = TPM_RH_PLATFORM;
rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes);
/* Add NV attributes required by Nuvoton specification */
nvAttributes |= (TPMA_NV_PLATFORMCREATE | TPMA_NV_POLICY_DELETE);
nvAttributes |= (TPM_NT_ORDINARY & TPMA_NV_TPM_NT);
if (rc != 0) {
printf("Setting NV attributes failed\n");
goto exit;
}
#ifdef DEBUG_WOLFTPM
printf("nvAttributes = 0x%8.8X\n", nvAttributes);
#endif
/* Define NV Index for GPIO */
rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, nvIndex, nvAttributes,
sizeof(BYTE), (byte*)gNvAuth, sizeof(gNvAuth)-1);
if (rc != 0 && rc != TPM_RC_NV_DEFINED) {
printf("Creating NV Index for GPIO acccess failed\n");
goto exit;
}
printf("NV Index for GPIO access created\n");
exit:
wolfTPM2_Cleanup(&dev);
exit_badargs:
return rc;
}
/******************************************************************************/
/* --- END TPM2.0 GPIO Configuration example -- */
/******************************************************************************/
#endif /* WOLFTPM_NUVOTON */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = -1;
#if defined(WOLFTPM_NUVOTON)
rc = TPM2_GPIO_Nuvoton_Example(NULL, argc, argv);
#else
printf("GPIO configuration requires a Nuvoton NPCT75x TPM 2.0 module built with WOLFTPM_NUVOTON or --enable-nuvoton.\n");
(void)argc;
(void)argv;
#endif /* WOLFTPM_NUVOTON */
return rc;
}
#endif

View File

@ -21,7 +21,7 @@
/* Example for reading the voltage level of TPM's GPIO
*
* Note: GPIO must be first configured using gpio/config
* Note: GPIO must be first configured using gpio/gpio_config
*
*/
@ -36,7 +36,7 @@
#include <stdlib.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && \
(defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT))
(defined(WOLFTPM_ST33) || defined(WOLFTPM_NUVOTON) || defined(WOLFTPM_AUTODETECT))
/******************************************************************************/
/* --- BEGIN TPM GPIO Read Example -- */
@ -71,7 +71,7 @@ int TPM2_GPIO_Read_Example(void* userCtx, int argc, char *argv[])
usage();
return 0;
}
nvIndex += pin;
nvIndex = TPM_NV_GPIO_SPACE + (pin-GPIO_NUM_MIN);
}
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
@ -86,7 +86,11 @@ int TPM2_GPIO_Read_Example(void* userCtx, int argc, char *argv[])
nv.handle.hndl = nvIndex;
nv.handle.auth.size = sizeof(gNvAuth)-1;
XMEMCPY(nv.handle.auth.buffer, (byte*)gNvAuth, nv.handle.auth.size);
#ifdef WOLFTPM_NUVOTON
parent.hndl = TPM_RH_PLATFORM;
#else
parent.hndl = TPM_RH_OWNER;
#endif
/* Read GPIO state */
readSize = sizeof(pinState);
rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, &pinState, &readSize, 0);
@ -118,7 +122,7 @@ exit:
/******************************************************************************/
/* --- END TPM GPIO Store Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER && (WOLFTPM_ST33 || WOLFTPM_AUTODETECT) */
#endif /* !WOLFTPM2_NO_WRAPPER && (WOLFTPM_ST33 || WOLFTPM_NUVOTON || WOLFTPM_AUTODETECT) */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
@ -126,7 +130,7 @@ int main(int argc, char *argv[])
int rc = NOT_COMPILED_IN;
#if !defined(WOLFTPM2_NO_WRAPPER) && \
(defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT))
(defined(WOLFTPM_ST33) || defined(WOLFTPM_NUVOTON) || defined(WOLFTPM_AUTODETECT))
rc = TPM2_GPIO_Read_Example(NULL, argc, argv);
#else
printf("GPIO code not compiled in\n");

View File

@ -21,7 +21,7 @@
/* Example for setting the voltage level of TPM's GPIO
*
* Note: GPIO must be first configured using gpio/config
* Note: GPIO must be first configured using gpio/gpio_config
*
*/
@ -35,7 +35,7 @@
#include <stdlib.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && \
(defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT))
(defined(WOLFTPM_ST33) || defined(WOLFTPM_NUVOTON) || defined(WOLFTPM_AUTODETECT))
/******************************************************************************/
/* --- BEGIN TPM GPIO Set Example -- */
@ -70,7 +70,7 @@ int TPM2_GPIO_Set_Example(void* userCtx, int argc, char *argv[])
usage();
return 0;
}
nvIndex += pin;
nvIndex = TPM_NV_GPIO_SPACE + (pin-GPIO_NUM_MIN);
}
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-high", 5) == 0) {
@ -94,7 +94,11 @@ int TPM2_GPIO_Set_Example(void* userCtx, int argc, char *argv[])
nv.handle.hndl = nvIndex;
nv.handle.auth.size = sizeof(gNvAuth)-1;
XMEMCPY(nv.handle.auth.buffer, (byte*)gNvAuth, nv.handle.auth.size);
#ifdef WOLFTPM_NUVOTON
parent.hndl = TPM_RH_PLATFORM;
#else
parent.hndl = TPM_RH_OWNER;
#endif
/* Read GPIO state */
writeSize = sizeof(pinState);
rc = wolfTPM2_NVWriteAuth(&dev, &nv, nvIndex, &pinState, writeSize, 0);
@ -123,7 +127,7 @@ exit:
/******************************************************************************/
/* --- END TPM GPIO Set Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER && (WOLFTPM_ST33 || WOLFTPM_AUTODETECT) */
#endif /* !WOLFTPM2_NO_WRAPPER && (WOLFTPM_ST33 || WOLFTPM_NUVOTON || WOLFTPM_AUTODETECT) */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
@ -131,7 +135,7 @@ int main(int argc, char *argv[])
int rc = NOT_COMPILED_IN;
#if !defined(WOLFTPM2_NO_WRAPPER) && \
(defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT))
(defined(WOLFTPM_ST33) || defined(WOLFTPM_NUVOTON) || defined(WOLFTPM_AUTODETECT))
rc = TPM2_GPIO_Set_Example(NULL, argc, argv);
#else
printf("GPIO code not compiled in\n");

View File

@ -22,13 +22,23 @@ examples_gpio_gpio_set_SOURCES = examples/gpio/gpio_set.c \
examples/tpm_io.c
examples_gpio_gpio_set_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_gpio_gpio_set_DEPENDENCIES = src/libwolftpm.la
endif
if BUILD_NUVOTON
noinst_PROGRAMS += examples/gpio/gpio_nuvoton
examples_gpio_gpio_nuvoton_SOURCES = examples/gpio/gpio_nuvoton.c \
examples/tpm_io.c
examples_gpio_gpio_nuvoton_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_gpio_gpio_nuvoton_DEPENDENCIES = src/libwolftpm.la
endif
dist_example_DATA+= examples/gpio/gpio_config.c
dist_example_DATA+= examples/gpio/gpio_read.c
dist_example_DATA+= examples/gpio/gpio_set.c
dist_example_DATA+= examples/gpio/gpio_nuvoton.c
DISTCLEANFILES+= examples/gpio/.libs/gpio_config
DISTCLEANFILES+= examples/gpio/.libs/gpio_read
DISTCLEANFILES+= examples/gpio/.libs/gpio_set
DISTCLEANFILES+= examples/gpio/.libs/gpio_nuvoton

View File

@ -5227,6 +5227,61 @@ int TPM2_GPIO_Config(GpioConfig_In* in)
}
return rc;
}
#elif defined(WOLFTPM_NUVOTON)
int TPM2_NTC2_PreConfig(NTC2_PreConfig_In* in)
{
int rc;
TPM2_CTX* ctx = TPM2_GetActiveCtx();
if (in == NULL || ctx == NULL)
return BAD_FUNC_ARG;
rc = TPM2_AcquireLock(ctx);
if (rc == TPM_RC_SUCCESS) {
CmdInfo_t info = {
.inHandleCnt = 1,
};
TPM2_Packet packet;
TPM2_Packet_Init(ctx, &packet);
/* Process the auth handle for GPIO configuration */
TPM2_Packet_AppendU32(&packet, in->authHandle);
info.authCnt = TPM2_Packet_AppendAuth(&packet, ctx);
/* Process the NPCT7xx configuration */
TPM2_Packet_AppendBytes(&packet, (byte*)&in->preConfig, sizeof(in->preConfig));
TPM2_Packet_Finalize(&packet, TPM_ST_SESSIONS, TPM_CC_NTC2_PreConfig);
/* Send the new NPCT7xx configuration */
rc = TPM2_SendCommandAuth(ctx, &packet, &info);
TPM2_ReleaseLock(ctx);
}
return rc;
}
int TPM2_NTC2_GetConfig(NTC2_GetConfig_Out* out)
{
int rc;
TPM2_CTX* ctx = TPM2_GetActiveCtx();
if (out == NULL || ctx == NULL)
return BAD_FUNC_ARG;
rc = TPM2_AcquireLock(ctx);
if (rc == TPM_RC_SUCCESS) {
TPM2_Packet packet;
TPM2_Packet_Init(ctx, &packet);
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NTC2_GetConfig);
/* Request the current NPCT7xx configuration */
rc = TPM2_SendCommand(ctx, &packet);
if (rc == TPM_RC_SUCCESS) {
TPM2_Packet_ParseBytes(&packet, (byte*)&out->preConfig, sizeof(out->preConfig));
}
TPM2_ReleaseLock(ctx);
}
return rc;
}
#endif
/******************************************************************************/
/* --- END Manufacture Specific TPM API's -- */

View File

@ -255,6 +255,9 @@ typedef enum {
TPM_CC_RestoreEK = CC_VEND + 0x030A,
TPM_CC_SetCommandSetLock = CC_VEND + 0x030B,
TPM_CC_GPIO_Config = CC_VEND + 0x030F,
#elif defined(WOLFTPM_NUVOTON)
TPM_CC_NTC2_PreConfig = CC_VEND + 0x0211,
TPM_CC_NTC2_GetConfig = CC_VEND + 0x0213,
#endif
} TPM_CC_T;
typedef UINT32 TPM_CC;
@ -2754,6 +2757,26 @@ WOLFTPM_API TPM_RC TPM2_NV_Certify(NV_Certify_In* in, NV_Certify_Out* out);
/* Vendor Specific API's */
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
#undef MAX_GPIO_COUNT
#ifdef WOLFTPM_I2C
#define MAX_GPIO_COUNT 4
#else /* SPI variant */
#define MAX_GPIO_COUNT 2
#endif
/* ST33 variants can have different count of GPIO available:
* * SPI variant - 0, 1 or 2
* * I2C variant - 0, 1, 2, 3 or 4
* The user can configure this option at build or use default value.
*/
#ifndef TPM_GPIO_COUNT
#define TPM_GPIO_COUNT MAX_GPIO_COUNT
#endif
/* GPIO configuration uses specific range of NV space */
#define TPM_NV_GPIO_SPACE 0x01C40000
#define MAX_TPM_NV_GPIO_SPACE 0x01C4000F
typedef struct {
TPMI_RH_HIERARCHY authHandle;
TPM_CC commandCode;
@ -2782,25 +2805,6 @@ typedef struct {
} SetMode_In;
WOLFTPM_API int TPM2_SetMode(SetMode_In* in);
#undef MAX_GPIO_COUNT
#ifdef WOLFTPM_I2C
#define MAX_GPIO_COUNT 4
#else /* SPI variant */
#define MAX_GPIO_COUNT 2
#endif
/* ST33 variants can have different count of GPIO available:
* * SPI variant - 0, 1 or 2
* * I2C variant - 0, 1, 2, 3 or 4
* The user can configure this option at build or use default value.
*/
#ifndef TPM_GPIO_COUNT
#define TPM_GPIO_COUNT MAX_GPIO_COUNT
#endif
/* GPIO configuration uses specific range of NV space */
#define TPM_NV_GPIO_SPACE 0x01C40000
#define MAX_TPM_NV_GPIO_SPACE 0x01C4000F
typedef enum {
TPM_GPIO_PP = 0x00000000, /* GPIO A by default is a Physical Presence pin */
TPM_GPIO_LP = 0x00000001, /* GPIO B can only be used as an input */
@ -2812,7 +2816,7 @@ typedef enum {
} TPMI_GPIO_NAME_T;
typedef UINT32 TPMI_GPIO_NAME;
/* For readability in code */
/* For portability and readability in code */
#define TPM_GPIO_A TPM_GPIO_PP
#define TPM_GPIO_B TPM_GPIO_LP
@ -2838,12 +2842,60 @@ typedef struct TPML_GPIO_CONFIG {
} TPML_GPIO_CONFIG;
typedef struct {
TPMI_RH_PLATFORM authHandle;
TPMI_RH_PLATFORM authHandle;
TPML_GPIO_CONFIG config;
} GpioConfig_In;
WOLFTPM_API int TPM2_GPIO_Config(GpioConfig_In* in);
#elif defined(WOLFTPM_NUVOTON)
#undef MAX_GPIO_COUNT
#define MAX_GPIO_COUNT 2
/* NPCT7XX supports a maximum of 2 GPIO for user control */
#undef TPM_GPIO_COUNT
#define TPM_GPIO_COUNT MAX_GPIO_COUNT
/* For portability */
#undef TPM_GPIO_A
#define TPM_GPIO_A 3 /* NPCT75xx GPIO start at number 3 */
/* GPIO configuration uses specific range of NV space */
#define TPM_NV_GPIO_SPACE 0x01C40003
#define MAX_TPM_NV_GPIO_SPACE 0x01C40004
typedef struct {
BYTE Base0;
BYTE Base1;
BYTE GpioAltCfg;
BYTE GpioInitValue;
BYTE GpioPullUp;
BYTE GpioPushPull;
BYTE Cfg_A;
BYTE Cfg_B;
BYTE Cfg_C;
BYTE Cfg_D;
BYTE Cfg_E;
BYTE Cfg_F;
BYTE Cfg_G;
BYTE Cfg_H;
BYTE Cfg_I;
BYTE Cfg_J;
BYTE isValid;
BYTE isLocked;
} CFG_STRUCT;
typedef struct {
TPMI_RH_PLATFORM authHandle;
CFG_STRUCT preConfig;
} NTC2_PreConfig_In;
WOLFTPM_API int TPM2_NTC2_PreConfig(NTC2_PreConfig_In* in);
typedef struct {
CFG_STRUCT preConfig;
} NTC2_GetConfig_Out;
WOLFTPM_API int TPM2_NTC2_GetConfig(NTC2_GetConfig_Out* out);
#endif /* WOLFTPM_ST33 || WOLFTPM_AUTODETECT */
/* Non-standard API's */
/** @defgroup TPM2_Proprietary TPM2 Proprietary