Skip to content

Commit 80305ef

Browse files
committed
Added experimental support for Das U-Boot bootloader
* Recommended to use the SOFT SPI driver in U-boot * wolfTPM serves as a TPM 2.0 driver thanks to its internal TIS layer * wolfTPM provides native API with full access to all TPM 2.0 commands * wolfTPM offers wrappers API for complex and common TPM 2.0 operations
1 parent 05d5a0b commit 80305ef

File tree

6 files changed

+276
-0
lines changed

6 files changed

+276
-0
lines changed

examples/include.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dist_example_DATA+= examples/README.md \
2323
examples/tpm_io_linux.c \
2424
examples/tpm_io_st.c \
2525
examples/tpm_io_qnx.c \
26+
examples/tpm_io_uboot.c \
2627
examples/tpm_io_xilinx.c \
2728
examples/tpm_io.h \
2829
examples/tpm_test_keys.c \

examples/tpm_io.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
#include "examples/tpm_io_barebox.c"
5757
#elif defined(__QNX__) || defined(__QNXNTO__)
5858
#include "examples/tpm_io_qnx.c"
59+
#elif defined(__UBOOT__)
60+
#include "examples/tpm_io_uboot.c"
5961
#elif defined(__XILINX__)
6062
#include "examples/tpm_io_xilinx.c"
6163
#endif
@@ -76,6 +78,8 @@ static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
7678
ret = TPM2_IoCb_Barebox_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
7779
#elif defined(__QNX__) || defined(__QNXNTO__)
7880
ret = TPM2_IoCb_QNX_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
81+
#elif defined(__UBOOT__)
82+
ret = TPM2_IoCb_Uboot_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
7983
#elif defined(__XILINX__)
8084
ret = TPM2_IoCb_Xilinx_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
8185
#else

examples/tpm_io.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
* * Xilinx Zynq
4949
* * Barebox
5050
* * QNX
51+
* * Uboot
5152
*
5253
* Using custom IO Callback is always possible.
5354
*
@@ -91,6 +92,9 @@ int TPM2_IoCb_STCubeMX_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
9192
#elif defined(__QNX__) || defined(__QNXTO__)
9293
int TPM2_IoCb_QNX_SPI(TPM2_CTX* ctx, const byte* txBuf,
9394
byte* rxBuf, word16 xferSz, void* userCtx);
95+
#elif defined(__UBOOT__)
96+
int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
97+
byte* rxBuf, word16 xferSz, void* userCtx);
9498
#elif defined(__XILINX__)
9599
int TPM2_IoCb_Xilinx_SPI(TPM2_CTX* ctx, const byte* txBuf,
96100
byte* rxBuf, word16 xferSz, void* userCtx);

examples/tpm_io_uboot.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/* tpm_io_uboot.c
2+
*
3+
* Copyright (C) 2006-2021 wolfSSL Inc.
4+
*
5+
* This file is part of wolfTPM.
6+
*
7+
* wolfTPM is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfTPM is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
/* This example shows IO interfaces for Uboot */
23+
24+
25+
#include <wolftpm/tpm2.h>
26+
#include <wolftpm/tpm2_tis.h>
27+
#include "tpm_io.h"
28+
29+
/******************************************************************************/
30+
/* --- BEGIN IO Callback Logic -- */
31+
/******************************************************************************/
32+
33+
/* Included via tpm_io.c if WOLFTPM_INCLUDE_IO_FILE is defined */
34+
#ifdef WOLFTPM_INCLUDE_IO_FILE
35+
36+
#if ! (defined(WOLFTPM_LINUX_DEV) || \
37+
defined(WOLFTPM_SWTPM) || \
38+
defined(WOLFTPM_WINAPI) )
39+
40+
/* Use the max speed by default - see tpm2_types.h for chip specific max values */
41+
#ifndef TPM2_SPI_HZ
42+
#define TPM2_SPI_HZ TPM2_SPI_MAX_HZ
43+
#endif
44+
45+
#ifndef CONFIG_DEFAULT_SPI_BUS
46+
#define CONFIG_DEFAULT_SPI_BUS 1
47+
#define CONFIG_DEFAULT_SPI_CS 0
48+
#define CONFIG_DEFAULT_SPI_FREQ 1000000
49+
#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3
50+
#define CONFIG_DEFAULT_SPI_NAME "generic_1:0\0"
51+
#endif
52+
53+
#if defined(__UBOOT__)
54+
#include <common.h>
55+
#include <dm.h>
56+
#include <spi.h>
57+
58+
int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
59+
byte* rxBuf, word16 xferSz, void* userCtx)
60+
{
61+
int ret = TPM_RC_FAILURE;
62+
struct udevice *udev = NULL; /* u-boot device */
63+
struct spi_slave *slave = NULL;
64+
65+
#ifdef WOLFTPM_CHECK_WAIT_STATE
66+
#error SPI check wait state logic not supported for U-boot
67+
#endif
68+
69+
if (userCtx == NULL) {
70+
#ifdef DEBUG_WOLFTPM
71+
printf("userCtx is NULL, can not acccess udev\n");
72+
#endif
73+
return TPM_RC_FAILURE;
74+
}
75+
76+
#if CONFIG_IS_ENABLED(DM_SPI)
77+
/* If Driver-model is enabled, we can acquire SPI udevice using bus number */
78+
ret = spi_get_bus_and_cs(CONFIG_DEFAULT_SPI_BUS, CONFIG_DEFAULT_SPI_CS,
79+
CONFIG_DEFAULT_SPI_FREQ, CONFIG_DEFAULT_SPI_MODE,
80+
"spi_generic_drv", CONFIG_DEFAULT_SPI_NAME,
81+
&dev, &slave);
82+
if (ret) {
83+
return ret;
84+
}
85+
86+
#else
87+
/* Acquire the SPI bus from manually passed udevice through wolfTPM2_Init */
88+
udev = (struct udevice*)userCtx;
89+
slave = dev_get_parent_priv(dev);
90+
#endif
91+
92+
ret = spi_claim_bus(slave);
93+
if (ret < 0) {
94+
#ifdef DEBUG_WOLFTPM
95+
printf("Failed to acquire access to u-boot spi bus\n");
96+
return ret;
97+
#endif
98+
}
99+
100+
ret = spi_xfer(slave, xferSz * 8, tx_buf, rx_buf,
101+
SPI_XFER_BEGIN | /* Assert CS before transfer */
102+
SPI_XFER_END); /* Deassert CS after transfer */
103+
#ifdef DEBUG_WOLFTPM
104+
if (ret < 0) {
105+
printf("Failed to transmit data over the SPI bus\n");
106+
}
107+
#endif
108+
109+
/* Regardless of the SPI operation outcome, release the SPI bus */
110+
spi_release_bus(slave);
111+
112+
if (ret == 0) {
113+
ret = TPM_RC_SUCCESS;
114+
}
115+
116+
(void)ctx;
117+
118+
return ret;
119+
}
120+
121+
#endif
122+
#endif /* !(WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI) */
123+
#endif /* WOLFTPM_INCLUDE_IO_FILE */
124+
125+
/******************************************************************************/
126+
/* --- END IO Callback Logic -- */
127+
/******************************************************************************/

examples/u-boot/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Experimental support for Das U-boot
2+
3+
wolfTPM could be used with all platforms that have hardware SPI support or can use the U-boot software bit-bang implementation(SPI_SOFT).
4+
5+
The example wolfTPM IO Callback was tested on RPI3 model B with ST33 TPM 2.0 module, using `make rpi_3_32b_defconfig` and changes to the DeviceTree as described below in `U-boot preparations`.
6+
7+
https://source.denx.de/u-boot/u-boot
8+
9+
## Current state of TPM support in U-boot
10+
11+
The internal U-boot support for TPM is limited to only several commands:
12+
13+
* TPM2_PCR_Read
14+
* TPM2_PCR_Extend
15+
* TPM2_GetCapability
16+
17+
and few others for maintenance purposes, like TPM2_Clear.
18+
19+
## Using wolfTPM with U-boot
20+
21+
Thanks to wolfTPM, U-boot can perform all TPM 2.0 operations, including TPM2_Seal/Unseal, TPM2_Quote, TPM2_EncryptDecrypt2 and TPM2_NV_Write/TPM2_NV_Read.
22+
23+
### U-boot preparation
24+
25+
wolfTPM has a internal TPM Interface Command(TIS) layer and allows wolfTPM to be used as TPM 2.0 driver for baremetal and embedded systems.
26+
27+
Our example IO callback in examples/tpm_io_uboot.c uses the existing SPI driver in U-boot. It is up to the developer to choose between hardware SPI driver or U-boot's software SPI driver. Best compatibility is offered through the software SPI driver that uses bit-bang GPIO to implement SPI interface. For example, U-boot does not offer hardware SPI for Raspberry Pi boards and other Broadcom SoC systems.
28+
29+
To enable U-boot's software SPI driver make sure to enable SPI_SOFT in your U-boot's configuration manually or using `make menuconfig` under Device Drivers, SPI Support.
30+
31+
Once enabled, it is also needed to add Device Tree entry for SPI Slave device
32+
33+
```
34+
35+
tpm2-spi {
36+
37+
compatible = "spi-gpio"; /* Selection the SPI_SOFT driver */
38+
cs-gpios = <&gpio 24 0>; /* Pinout from ST33 RPI Eval Board */
39+
gpio-sck = <&gpio 23 0>;
40+
gpio-miso = <&gpio 21 0>;
41+
gpio-mosi = <&gpio 19 0>;
42+
spi-delay-us = <10>;
43+
cs@0 {
44+
};
45+
};
46+
47+
```
48+
49+
Note:
50+
51+
U-boot should use the new Driver Model or when initializing wolfTPM in U-boot it is required to pass handle to the SPI device registered as the user context. Example below:
52+
53+
```
54+
55+
struct udevice *uDev = &spiDev; /* replace with correct udevice instance */
56+
WOLFTPM2_DEV tpmDev;
57+
wolfTPM2_Init(&tpmDev, TPM2_IoCb_SPI, uDev);
58+
59+
```
60+
61+
In case U-boot's driver model is used, then the Io Callback will try to automatically acquire the spi device at the default SPI bus.
62+
63+
### wolfTPM compilation
64+
65+
To build static version of wolfTPM for U-boot, use the configure script or use the example options.h file in examples/u-boot.
66+
67+
To use configure:
68+
69+
./configure --disable-shared --enable-autodetect --disable-wolfcrypt
70+
71+
This way u-boot can be later linked together with wolfTPM.
72+
73+
## Benefits of using wolfTPM with U-boot
74+
75+
### Native API
76+
77+
wolfTPM provides native API with full access to all TPM 2.0 commands. For example:
78+
79+
* TPM2_Seal/TPM2_Unseal
80+
* TPM2_DefineSpace/TPM2_UndefineSpace
81+
* TPM2_CreatePrimary/TPM2_Create
82+
* TPM2_EncryptDecrypt2
83+
84+
Internal U-boot TPM support for these commands is missing. By adding wolfTPM the system can perform symmetric and asymmetric key generation, PCR operations, TPM 2.0 Quote, TPM 2.0 Certify Creation, Key import, extra GPIO for safety-critical systems, Signature verification, Hash generation and all other TPM 2.0 capabilities.
85+
86+
### Wrappers
87+
88+
wolfTPM's rich API provides wrappers for performing complete TPM 2.0 operations. There are wolfTPM wrappers for the most common and complex TPM 2.0 operations. The wrappers also protect from wrong TPM 2.0 settings and execute all necessary TPM 2.0 commands to achieve the end goal.
89+
90+
wolfTPM wrappers also provide templates for the most commonly used types of TPM 2.0 keys.
91+
92+
Please contact us at [email protected] if you are interested in using wolfTPM with U-boot.

examples/u-boot/options.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* examples/u-boot/options.h
2+
*
3+
* Copyright (C) 2006-2021 wolfSSL Inc.
4+
*
5+
* This file is part of wolfTPM.
6+
*
7+
* wolfTPM is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfTPM is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
/* Example wolfTPM options.h for U-boot compilation */
23+
24+
#ifndef WOLFTPM_OPTIONS_H
25+
#define WOLFTPM_OPTIONS_H
26+
27+
#ifdef __cplusplus
28+
extern "C" {
29+
#endif
30+
31+
#undef __UBOOT__
32+
#define __UBOOT__
33+
34+
#undef SIZEOF_LONG
35+
#define SIZEOF_LONG 8
36+
37+
#undef WOLFTPM2_NO_WOLFCRYPT
38+
#define WOLFTPM2_NO_WOLFCRYPT
39+
40+
#undef WOLFTPM_AUTODETECT
41+
#define WOLFTPM_AUTODETECT
42+
43+
#ifdef __cplusplus
44+
}
45+
#endif
46+
47+
#endif /* WOLFTPM_OPTIONS_H */
48+

0 commit comments

Comments
 (0)