-
Notifications
You must be signed in to change notification settings - Fork 365
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new TCTI module that can talk to TPMs connected via spidev to the host. Signed-off-by: Andreas Fuchs <andreas.fuchs@infineon.com>
- Loading branch information
1 parent
ede63dd
commit eb53dc4
Showing
10 changed files
with
558 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# SPI TCTI LTT2GO | ||
The SPI TCTI LTT2GO can be used for communication with LetsTrust-TPM2Go USB TPM. | ||
The LTT2GO module utilizes the `tcti-spi-helper` library for PTP SPI protocol handling | ||
and the `libusb-1.0-0-dev` library for USB communication. | ||
|
||
# EXAMPLES | ||
|
||
Set udev rules for LetsTrust-TPM2Go by creating a file `/etc/udev/rules.d/60-tpm2go.rules`: | ||
``` | ||
ATTRS{idVendor}=="365d", ATTRS{idProduct}=="1337", TAG+="uaccess" | ||
``` | ||
|
||
Activate the udev rules: | ||
```console | ||
sudo udevadm control --reload | ||
``` | ||
|
||
You should see the following after plugging in the LetsTrust-TPM2Go: | ||
``` | ||
dmesg | ||
[ 1019.115823] usb 3-2: new full-speed USB device number 5 using xhci_hcd | ||
[ 1019.480333] usb 3-2: New USB device found, idVendor=365d, idProduct=1337, bcdDevice= 0.00 | ||
[ 1019.480360] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 | ||
[ 1019.480382] usb 3-2: Product: LetsTrust-TPM2Go | ||
[ 1019.480405] usb 3-2: Manufacturer: www.pi3g.com | ||
[ 1019.480426] usb 3-2: SerialNumber: Y23CW29NR00000RND987654321012 | ||
sudo udevadm info -e | grep LetsTrust | ||
E: ID_MODEL=LetsTrust-TPM2Go | ||
E: ID_MODEL_ENC=LetsTrust-TPM2Go | ||
E: ID_SERIAL=www.pi3g.com_LetsTrust-TPM2Go_Y23CW29NR00000RND987654321012 | ||
``` | ||
|
||
Use tcti-spi-ltt2go to communicate with LetsTrust-TPM2Go: | ||
```console | ||
tpm2_startup -Tspi-ltt2go -c | ||
tpm2_getrandom -Tspi-ltt2go 8 --hex | ||
``` | ||
|
||
Enable abrmd: | ||
```console | ||
export DBUS_SESSION_BUS_ADDRESS=`dbus-daemon --session --print-address --fork` | ||
tpm2-abrmd --allow-root --session --tcti=spi-ltt2go & | ||
|
||
export TPM2TOOLS_TCTI="tabrmd:bus_name=com.intel.tss2.Tabrmd,bus_type=session" | ||
tpm2_startup -c | ||
tpm2_getrandom 8 --hex | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* SPDX-License-Identifier: BSD-2-Clause */ | ||
/* | ||
* Copyright 2023 Infineon Technologies AG | ||
*/ | ||
#ifndef TSS2_TCTI_SPIDEV_H | ||
#define TSS2_TCTI_SPIDEV_H | ||
|
||
#include <stdbool.h> | ||
#include "tss2_tcti.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
TSS2_RC Tss2_Tcti_Spidev_Init ( | ||
TSS2_TCTI_CONTEXT *tctiContext, | ||
size_t *size, | ||
const char *config); | ||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* TSS2_TCTI_SPIDEV_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
LIBRARY tss2-tcti-spidev | ||
EXPORTS | ||
Tss2_Tcti_Info | ||
Tss2_Tcti_Spidev_Init |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
global: | ||
Tss2_Tcti_Info; | ||
Tss2_Tcti_Spidev_Init; | ||
local: | ||
*; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
prefix=@prefix@ | ||
exec_prefix=@exec_prefix@ | ||
libdir=@libdir@ | ||
includedir=@includedir@ | ||
|
||
Name: tss2-tcti-spidev | ||
Description: TCTI library for communicating with the TPM over spidev. | ||
URL: https://github.com/tpm2-software/tpm2-tss | ||
Version: @VERSION@ | ||
Cflags: -I${includedir} -I${includedir}/tss | ||
Libs: -ltss2-tcti-spi-helper -ltss2-tcti-spi-ltt2go -L${libdir} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/* SPDX-License-Identifier: BSD-2-Clause */ | ||
/* | ||
* Copyright 2020 Peter Huewe | ||
*/ | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <inttypes.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdbool.h> | ||
#include <string.h> | ||
#include <sys/stat.h> | ||
#include <sys/select.h> | ||
#include <sys/time.h> | ||
#include <sys/ioctl.h> | ||
#include <linux/ioctl.h> | ||
#include <unistd.h> | ||
#include <assert.h> | ||
#include <linux/spi/spidev.h> | ||
|
||
#include "tss2_tcti.h" | ||
#include "tss2_tcti_spidev.h" | ||
#include "tss2_tcti_spi_helper.h" | ||
#include "tcti-common.h" | ||
#include "tss2_mu.h" | ||
#define LOGMODULE tcti | ||
#include "util/log.h" | ||
|
||
typedef struct { | ||
struct timeval timeout; | ||
int fd; | ||
} PLATFORM_USERDATA; | ||
|
||
struct spi_ioc_transfer tr = { | ||
Check notice Code scanning / CodeQL Short global name Note
Poor global variable name 'tr'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo).
|
||
.delay_usecs = 0, | ||
.speed_hz = 5000000, | ||
.bits_per_word = 8, | ||
}; | ||
|
||
TSS2_RC | ||
platform_spi_acquire (void *user_data) | ||
{ | ||
PLATFORM_USERDATA *platform_data = (PLATFORM_USERDATA *) user_data; | ||
tr.cs_change = 1; | ||
tr.len = 0; | ||
int ret = ioctl(platform_data->fd, SPI_IOC_MESSAGE(1), &tr); | ||
if (ret < 0) { | ||
LOG_ERROR("SPI acquire failed: %s", strerror(errno)); | ||
return TSS2_TCTI_RC_IO_ERROR; | ||
} | ||
return TSS2_RC_SUCCESS; | ||
} | ||
|
||
TSS2_RC | ||
platform_spi_release (void *user_data) | ||
{ | ||
PLATFORM_USERDATA *platform_data = (PLATFORM_USERDATA *) user_data; | ||
tr.cs_change = 0; | ||
tr.len = 0; | ||
int ret = ioctl(platform_data->fd, SPI_IOC_MESSAGE(1), &tr); | ||
if (ret < 0) { | ||
LOG_ERROR("SPI release failed: %s", strerror(errno)); | ||
return TSS2_TCTI_RC_IO_ERROR; | ||
} | ||
return TSS2_RC_SUCCESS; | ||
} | ||
|
||
TSS2_RC | ||
platform_spi_transfer (void *user_data, const void *data_out, void *data_in, size_t cnt) | ||
{ | ||
LOGBLOB_DEBUG(data_out, cnt, "Transferring data over ioctl:"); | ||
PLATFORM_USERDATA *platform_data = (PLATFORM_USERDATA *) user_data; | ||
|
||
tr.cs_change = 1; | ||
tr.len = cnt; | ||
tr.tx_buf = (unsigned long) data_out; | ||
tr.rx_buf = (unsigned long) data_in; | ||
int ret = ioctl(platform_data->fd, SPI_IOC_MESSAGE(1), &tr); | ||
if (ret < 0) { | ||
LOG_ERROR("SPI acquire failed: %s", strerror(errno)); | ||
return TSS2_TCTI_RC_IO_ERROR; | ||
} | ||
LOGBLOB_DEBUG(data_in, cnt, "Received data over ioctl:"); | ||
return TSS2_RC_SUCCESS; | ||
} | ||
|
||
TSS2_RC | ||
platform_sleep_ms (void *user_data, int32_t milliseconds) | ||
{ | ||
(void) user_data; | ||
struct timeval tv = {milliseconds/1000, (milliseconds%1000)*1000}; | ||
select (0, NULL, NULL, NULL, &tv); | ||
|
||
return TSS2_RC_SUCCESS; | ||
} | ||
|
||
TSS2_RC | ||
platform_start_timeout (void *user_data, int32_t milliseconds) | ||
{ | ||
PLATFORM_USERDATA *platform_data = (PLATFORM_USERDATA *) user_data; | ||
|
||
memset (&platform_data->timeout, 0, sizeof (struct timeval)); | ||
|
||
if (gettimeofday (&platform_data->timeout, NULL)) { | ||
LOG_ERROR ("getimeofday failed with errno: %d.", errno); | ||
return TSS2_TCTI_RC_GENERAL_FAILURE; | ||
} | ||
|
||
platform_data->timeout.tv_sec += (milliseconds/1000); | ||
platform_data->timeout.tv_usec += (milliseconds%1000)*1000; | ||
if (platform_data->timeout.tv_usec > 999999) { | ||
platform_data->timeout.tv_sec++; | ||
platform_data->timeout.tv_usec -= 1000000; | ||
} | ||
|
||
return TSS2_RC_SUCCESS; | ||
} | ||
|
||
TSS2_RC | ||
platform_timeout_expired (void *user_data, bool *is_timeout_expired) | ||
{ | ||
PLATFORM_USERDATA *platform_data = (PLATFORM_USERDATA *) user_data; | ||
|
||
struct timeval now; | ||
if (gettimeofday (&now, NULL)) { | ||
LOG_ERROR ("getimeofday failed with errno: %d.", errno); | ||
return TSS2_TCTI_RC_GENERAL_FAILURE; | ||
} | ||
|
||
if (now.tv_sec > platform_data->timeout.tv_sec) { | ||
*is_timeout_expired = true; | ||
} else if ((now.tv_sec == platform_data->timeout.tv_sec) | ||
&& (now.tv_usec > platform_data->timeout.tv_usec)) { | ||
*is_timeout_expired = true; | ||
} else { | ||
*is_timeout_expired = false; | ||
} | ||
|
||
return TSS2_RC_SUCCESS; | ||
} | ||
|
||
void | ||
platform_finalize(void *user_data) | ||
{ | ||
PLATFORM_USERDATA *platform_data = (PLATFORM_USERDATA *) user_data; | ||
close(platform_data->fd); | ||
free(platform_data); | ||
} | ||
|
||
TSS2_RC | ||
Tss2_Tcti_Spidev_Init (TSS2_TCTI_CONTEXT* tcti_context, size_t* size, const char* config) | ||
{ | ||
TSS2_TCTI_SPI_HELPER_PLATFORM platform = {0}; | ||
|
||
if (!config || config[0] == '\0') | ||
config = "/dev/spidev0.1"; | ||
|
||
/* Check if context size is requested */ | ||
if (tcti_context == NULL) { | ||
return Tss2_Tcti_Spi_Helper_Init (NULL, size, NULL); | ||
} | ||
|
||
/* Create required platform user data */ | ||
PLATFORM_USERDATA *platform_data = calloc (1, sizeof (PLATFORM_USERDATA)); | ||
if (platform_data == NULL) { | ||
return TSS2_BASE_RC_MEMORY; | ||
} | ||
|
||
platform_data->fd = open(config, O_RDWR); | ||
if (!platform_data->fd) { | ||
LOG_ERROR("%s cannot be opened: %s", config, strerror(errno)); | ||
free(platform_data); | ||
return TSS2_TCTI_RC_IO_ERROR; | ||
} | ||
|
||
/* Create TCTI SPI platform struct with custom platform methods */ | ||
platform.user_data = platform_data; | ||
platform.sleep_ms = platform_sleep_ms; | ||
platform.start_timeout = platform_start_timeout; | ||
platform.timeout_expired = platform_timeout_expired; | ||
platform.spi_acquire = platform_spi_acquire; | ||
platform.spi_release = platform_spi_release; | ||
platform.spi_transfer = platform_spi_transfer; | ||
platform.finalize = platform_finalize; | ||
|
||
/* Initialize TCTI context */ | ||
return Tss2_Tcti_Spi_Helper_Init (tcti_context, size, &platform); | ||
} | ||
|
||
const TSS2_TCTI_INFO tss2_tcti_info = { | ||
.version = TCTI_VERSION, | ||
.name = "tcti-spidev", | ||
.description = "TCTI for communicating with a TPM via spidev.", | ||
.config_help = "Path to spidev (Default: /dev/spidev0.1).", | ||
.init = Tss2_Tcti_Spidev_Init | ||
}; | ||
|
||
const TSS2_TCTI_INFO * | ||
Tss2_Tcti_Info (void) | ||
{ | ||
return &tss2_tcti_info; | ||
} |
Oops, something went wrong.