diff --git a/Makefile-test.am b/Makefile-test.am index 7a1bd8fa0..ecd759d80 100644 --- a/Makefile-test.am +++ b/Makefile-test.am @@ -543,16 +543,19 @@ test_unit_tcti_spi_ltt2go_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS) test_unit_tcti_spi_ltt2go_LDADD = $(CMOCKA_LIBS) $(libtss2_tcti_spi_helper) test_unit_tcti_spi_ltt2go_LDFLAGS = -Wl,--wrap=libusb_bulk_transfer \ -Wl,--wrap=libusb_claim_interface \ + -Wl,--wrap=libusb_open \ -Wl,--wrap=libusb_close \ -Wl,--wrap=libusb_control_transfer \ -Wl,--wrap=libusb_dev_mem_alloc \ -Wl,--wrap=libusb_dev_mem_free \ -Wl,--wrap=libusb_exit \ -Wl,--wrap=libusb_free_config_descriptor \ + -Wl,--wrap=libusb_free_device_list \ -Wl,--wrap=libusb_get_config_descriptor \ - -Wl,--wrap=libusb_get_device \ + -Wl,--wrap=libusb_get_device_list \ + -Wl,--wrap=libusb_get_device_descriptor \ + -Wl,--wrap=libusb_get_string_descriptor_ascii \ -Wl,--wrap=libusb_init \ - -Wl,--wrap=libusb_open_device_with_vid_pid \ -Wl,--wrap=libusb_release_interface \ -Wl,--wrap=libusb_set_auto_detach_kernel_driver \ -Wl,--wrap=libusb_strerror \ diff --git a/Makefile.am b/Makefile.am index b97480203..f14bc4b6f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -204,7 +204,8 @@ include Makefile-fuzz.am ### Distribution files ### # Add udev rule -udevrules_DATA = dist/tpm-udev.rules +udevrules_DATA = dist/tpm-udev.rules \ + dist/ltt2go-udev.rules # Adding user and developer information EXTRA_DIST += \ @@ -976,7 +977,8 @@ install-man: install-man3 install-man7 $(LN_S) -f Tss2_TctiLdr_Initialize.3 $(DESTDIR)$(man3dir)/Tss2_TctiLdr_Initialize_Ex.3 endif #FAPI -EXTRA_DIST += dist/tpm-udev.rules +EXTRA_DIST += dist/tpm-udev.rules \ + dist/ltt2go-udev.rules install-dirs: if HOSTOS_LINUX @@ -1003,10 +1005,12 @@ endif install-data-hook: install-dirs -if [ ! -z "$(udevrulesprefix)" ]; then \ mv $(DESTDIR)$(udevrulesdir)/tpm-udev.rules $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)tpm-udev.rules; \ + mv $(DESTDIR)$(udevrulesdir)/ltt2go-udev.rules $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)ltt2go-udev.rules; \ fi uninstall-local: -rm $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)tpm-udev.rules + -rm $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)ltt2go-udev.rules cd $(DESTDIR)$(man3dir) && \ [ -L Tss2_TctiLdr_Initialize_Ex.3 ] && \ rm -f Tss2_TctiLdr_Initialize_Ex.3 || true diff --git a/dist/ltt2go-udev.rules b/dist/ltt2go-udev.rules new file mode 100644 index 000000000..0f265f7b6 --- /dev/null +++ b/dist/ltt2go-udev.rules @@ -0,0 +1,2 @@ +# ltt2go USB devices can only be accessed by the tss user +SUBSYSTEM=="usb", ATTRS{idVendor}=="365d", ATTRS{idProduct}=="1337", TAG+="systemd", MODE="0600", OWNER="tss" diff --git a/doc/tcti-spi-ltt2go.md b/doc/tcti-spi-ltt2go.md index 1543af699..07622478e 100644 --- a/doc/tcti-spi-ltt2go.md +++ b/doc/tcti-spi-ltt2go.md @@ -5,18 +5,8 @@ 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: -``` +```console 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 @@ -31,18 +21,148 @@ sudo udevadm info -e | grep LetsTrust E: ID_SERIAL=www.pi3g.com_LetsTrust-TPM2Go_Y23CW29NR00000RND987654321012 ``` -Use tcti-spi-ltt2go to communicate with LetsTrust-TPM2Go: +After plugging in the LetsTrust-TPM2Go, the USB interface access permission is granted to the user `tss`. The `tcti-spi-ltt2go` can now be used to communicate with the TPM. ```console -tpm2_startup -Tspi-ltt2go -c -tpm2_getrandom -Tspi-ltt2go 8 --hex +sudo -u tss tpm2_startup -Tspi-ltt2go -c +sudo -u tss tpm2_getrandom -Tspi-ltt2go 8 --hex ``` -Enable abrmd: +If multiple LetsTrust-TPM2Go devices are plugged in, it is possible to choose which one to address by specifying the serial number. The input format supports regex. ```console +sudo -u tss tpm2_getrandom -Tspi-ltt2go:Y23CW29NR00000RND987654321012 8 --hex +sudo -u tss tpm2_getrandom -Tspi-ltt2go:RND98765 8 --hex +sudo -u tss tpm2_getrandom -Tspi-ltt2go:21012$ 8 --hex +``` + +## ABRMD (Alone) + +Manually launch the abrmd (log in as root user): +```console +sudo su + 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 +``` + +## ABRMD (As a Systemd Service) + +Launch the abrmd as a service (supports only **a single** LetsTrust-TPM2Go at a time). + +Edit the service file using `systemctl edit --full tpm2-abrmd`. Then, update the service file content to: +``` +[Unit] +Description=TPM2 Access Broker and Resource Management Daemon +# These settings are needed when using the device TCTI. If the +# TCP mssim is used then the settings should be commented out. +#After=dev-tpm0.device +#Requires=dev-tpm0.device + +[Service] +Type=dbus +BusName=com.intel.tss2.Tabrmd +ExecStart=/usr/local/sbin/tpm2-abrmd --tcti=spi-ltt2go +User=tss + +[Install] +WantedBy=multi-user.target +``` + +After editing the service file, the TPM is accessible by: +```console +sudo systemctl start tpm2-abrmd + +export TPM2TOOLS_TCTI="tabrmd:bus_name=com.intel.tss2.Tabrmd" +sudo -u tss tpm2_startup -c +sudo -u tss tpm2_getrandom 8 --hex +``` + +## ABRMD (Udev + Systemd Service) + +By configuring the udev rules to automatically start the abrmd service when a LetsTrust-TPM2Go is plugged in and stop the service upon removal (supports only **a single** LetsTrust-TPM2Go at a time). + +Make the following modifications to `tpm2-abrmd/dist/tpm2-abrmd.service.in`: +``` +[Unit] +Description=TPM2 Access Broker and Resource Management Daemon +# These settings are needed when using the device TCTI. If the +# TCP mssim is used then the settings should be commented out. +#After=dev-tpm0.device +#Requires=dev-tpm0.device + +[Service] +Type=dbus +BusName=com.intel.tss2.Tabrmd +ExecStart=@SBINDIR@/tpm2-abrmd --tcti=spi-ltt2go:%i +User=tss + +[Install] +WantedBy=multi-user.target +``` + +After (re)installing the tpm2-abrmd, rename the service file on your host from `tpm2-abrmd.service` to `tpm2-abrmd@.service`. + +Make the following modifications to `tpm2-tss/dist/ltt2go-udev.rules`: +``` +SUBSYSTEM=="usb", ATTRS{idVendor}=="365d", ATTRS{idProduct}=="1337", ACTION=="add", TAG+="systemd", MODE="0600", OWNER="tss", RUN+="/bin/ltt2go_add.sh $env{DEVNAME}" +SUBSYSTEM=="usb", ACTION=="remove", TAG+="systemd", ENV{PRODUCT}=="365d/1337/0", RUN+="/bin/ltt2go_remove.sh $env{DEVNAME}" +``` + +Create a script at `/bin/ltt2go_add.sh` and make it executable. +``` +#!/bin/sh + +DEVNAME=$1 + +ID_SERIAL_SHORT=$(udevadm info --query=env --name=$DEVNAME | grep ID_SERIAL_SHORT | cut -d= -f2) + +if [ -z "${ID_SERIAL_SHORT}" ]; then + exit 1 +fi + +mkdir -p /run/ltt2go/$DEVNAME +echo $ID_SERIAL_SHORT > /run/ltt2go/${DEVNAME}/sn + +systemctl start tpm2-abrmd@${ID_SERIAL_SHORT}.service + +exit 0 +``` + +Create a script at `/bin/ltt2go_remove.sh` and make it executable: +``` +#!/bin/sh + +DEVNAME=$1 + +SN_DIR=/run/ltt2go/$DEVNAME + +if [ -f ${SN_DIR}/sn ]; then + SERIAL_NUMBER=$(cat ${SN_DIR}/sn) + + systemctl stop tpm2-abrmd@${SERIAL_NUMBER}.service + + rm -f ${SN_DIR}/sn + find /run/ltt2go -type d -empty -not -path /run/ltt2go -delete +else + exit 1 +fi + +exit 0 +``` + +After (re)installing the tpm2-tss, reload the udev rules and systemd: +```console +sudo udevadm control --reload-rules +sudo udevadm trigger +sudo systemctl daemon-reload +``` + +Now, plug in the LetsTrust-TPM2Go and access it by: +```console +export TPM2TOOLS_TCTI="tabrmd:bus_name=com.intel.tss2.Tabrmd" +sudo -u tss tpm2_startup -c +sudo -u tss tpm2_getrandom 8 --hex ``` \ No newline at end of file diff --git a/src/tss2-tcti/tcti-spi-ltt2go.c b/src/tss2-tcti/tcti-spi-ltt2go.c index f8fd40351..81c998276 100644 --- a/src/tss2-tcti/tcti-spi-ltt2go.c +++ b/src/tss2-tcti/tcti-spi-ltt2go.c @@ -3,6 +3,7 @@ * Copyright 2020 Peter Huewe */ #include // for errno +#include // for regcomp, regexec... #include // for true, bool, false #include // for NULL, size_t #include // for free, calloc @@ -193,12 +194,18 @@ platform_finalize(void *user_data) } TSS2_RC -create_tcti_spi_ltt2go_platform (TSS2_TCTI_SPI_HELPER_PLATFORM *platform) +create_tcti_spi_ltt2go_platform (TSS2_TCTI_SPI_HELPER_PLATFORM *platform, const char* config) { int ret = 0; int nb_ifaces = 0; + ssize_t i, dev_cnt = 0; + libusb_device **devs = NULL; libusb_device *dev = NULL; struct libusb_config_descriptor *conf_desc = NULL; + struct libusb_device_descriptor dev_desc; + char serial_number[256]; + char regex_errmsg[256]; + regex_t regex; /* Create required platform user data */ PLATFORM_USERDATA *platform_data = calloc (1, sizeof (PLATFORM_USERDATA)); @@ -210,52 +217,115 @@ create_tcti_spi_ltt2go_platform (TSS2_TCTI_SPI_HELPER_PLATFORM *platform) ret = libusb_init (&platform_data->ctx); if (ret) { LOG_ERROR ("libusb init failed: %s.", libusb_strerror (ret)); - goto out; + goto out_free_pf; } - platform_data->dev_handle = libusb_open_device_with_vid_pid (platform_data->ctx, VID_PI3G, PID_LTT2GO); - if (!platform_data->dev_handle) { - LOG_ERROR ("LetsTrust-TPM2Go not found."); - goto out; + dev_cnt = libusb_get_device_list (platform_data->ctx, &devs); + if (dev_cnt < 0) { + LOG_ERROR ("libusb_get_device_list failed: %s.", libusb_strerror (dev_cnt)); + goto out_pf_ctx; } - dev = libusb_get_device (platform_data->dev_handle); - if (dev == NULL) { - LOG_ERROR ("libusb_get_device failed."); - goto out; - } + for (i = 0; i < dev_cnt; i++) { + dev = devs[i]; + ret = libusb_get_device_descriptor (dev, &dev_desc); + if (ret) { + LOG_WARNING ("libusb_get_device_descriptor failed: %s.", libusb_strerror (ret)); + continue; + } - ret = libusb_get_config_descriptor (dev, 0, &conf_desc); - if (ret) { - LOG_ERROR ("libusb_get_config_descriptor failed: %s.", libusb_strerror (ret)); - goto out; + if ((dev_desc.idVendor == VID_PI3G) && (dev_desc.idProduct == PID_LTT2GO)) { + /*LOG_INFO("LTT2GO Device %04x:%04x (bus %d, device %d)\n", + desc.idVendor, desc.idProduct, + libusb_get_bus_number(dev), + libusb_get_device_address(dev));*/ + + ret = libusb_get_config_descriptor (dev, 0, &conf_desc); + if (ret) { + LOG_ERROR ("libusb_get_config_descriptor failed: %s.", libusb_strerror (ret)); + goto out_free_dev_list; + } + + nb_ifaces = conf_desc->bNumInterfaces; + libusb_free_config_descriptor(conf_desc); + if (!nb_ifaces) { + LOG_ERROR ("libusb no interface found."); + goto out_free_dev_list; + } + + ret = libusb_open (dev, &platform_data->dev_handle); + if (ret < 0) { + LOG_ERROR ("libusb_open failed: %s.", libusb_strerror (ret)); + goto out_free_dev_list; + } + + if (dev_desc.iSerialNumber) { + ret = libusb_get_string_descriptor_ascii (platform_data->dev_handle, + dev_desc.iSerialNumber, + (unsigned char*)serial_number, + sizeof(serial_number)); + if (ret > 0) { + if (config) { /* Perform matching based on the given serial number */ + ret = regcomp (®ex, config, REG_EXTENDED); + if (ret) { + regerror (ret, ®ex, regex_errmsg, sizeof (regex_errmsg)); + LOG_ERROR ("Failed to process regex: %s.", regex_errmsg); + goto out_dev_close; + } + + ret = regexec (®ex, serial_number, 0, NULL, 0); + regfree (®ex); + + if (!ret) { + LOG_INFO ("Matching serial number found: %s.", serial_number); + break; + } else if (ret == REG_NOMATCH) { + LOG_INFO ("Serial number found (%s) is not a match.", serial_number); + } else { + regerror (ret, ®ex, regex_errmsg, sizeof (regex_errmsg)); + LOG_ERROR ("Regex matching failed: %s\n", regex_errmsg); + goto out_dev_close; + } + } else { + /* Return the first matched device */ + break; + } + } else { + LOG_WARNING ("Failed to get serial number: %s.", libusb_strerror (ret)); + } + } else { + LOG_WARNING ("Device has no serial number."); + } + + libusb_close (platform_data->dev_handle); + } } - nb_ifaces = conf_desc->bNumInterfaces; - libusb_free_config_descriptor(conf_desc); - if (!nb_ifaces) { - LOG_ERROR ("libusb no interface found."); - goto out; + if (i >= dev_cnt) { + LOG_ERROR ("LetsTrust-TPM2Go not found."); + goto out_free_dev_list; } ret = libusb_set_auto_detach_kernel_driver (platform_data->dev_handle, 1); if (ret) { LOG_ERROR ("libusb_set_auto_detach_kernel_driver failed: %s.", libusb_strerror (ret)); - goto out; + goto out_dev_close; } ret = libusb_claim_interface (platform_data->dev_handle, 0); if (ret) { LOG_ERROR ("libusb_claim_interface failed: %s.", libusb_strerror (ret)); - goto out; + goto out_dev_close; } platform_data->spi_dma_buffer = libusb_dev_mem_alloc (platform_data->dev_handle, SPI_MAX_TRANSFER); if (!platform_data->spi_dma_buffer){ LOG_ERROR ("libusb_dev_mem_alloc failed."); - goto out; + goto out_release_interface; } + libusb_free_device_list(devs, 1); + /* Create TCTI SPI platform struct with custom platform methods */ platform->user_data = platform_data; platform->sleep_ms = platform_sleep_ms; @@ -267,37 +337,25 @@ create_tcti_spi_ltt2go_platform (TSS2_TCTI_SPI_HELPER_PLATFORM *platform) platform->finalize = platform_finalize; return TSS2_RC_SUCCESS; - -out: - if (platform_data->spi_dma_buffer) - libusb_dev_mem_free (platform_data->dev_handle, platform_data->spi_dma_buffer, SPI_MAX_TRANSFER); - - if (platform_data->dev_handle) { - /* Release the interface we claimed */ - ret = libusb_release_interface(platform_data->dev_handle, 0); - if (ret) { - LOG_WARNING ("libusb_release_interface failed: %s.", libusb_strerror (ret)); - } - - /* Close the device we opened */ - libusb_close (platform_data->dev_handle); - } - - if (platform_data->ctx) { - /* Needs to be called after closing all open devices - and before your application terminates */ - libusb_exit (platform_data->ctx); +out_release_interface: + ret = libusb_release_interface(platform_data->dev_handle, 0); + if (ret) { + LOG_ERROR ("libusb_release_interface failed: %s.", libusb_strerror (ret)); } - +out_dev_close: + libusb_close (platform_data->dev_handle); +out_free_dev_list: + libusb_free_device_list(devs, 1); +out_pf_ctx: + libusb_exit (platform_data->ctx); +out_free_pf: free(platform_data); - return TSS2_BASE_RC_IO_ERROR; } TSS2_RC Tss2_Tcti_Spi_Ltt2go_Init (TSS2_TCTI_CONTEXT* tcti_context, size_t* size, const char* config) { - (void) config; TSS2_RC ret = 0; TSS2_TCTI_SPI_HELPER_PLATFORM tcti_platform = {0}; @@ -306,7 +364,7 @@ Tss2_Tcti_Spi_Ltt2go_Init (TSS2_TCTI_CONTEXT* tcti_context, size_t* size, const return Tss2_Tcti_Spi_Helper_Init (NULL, size, NULL); } - if ((ret = create_tcti_spi_ltt2go_platform (&tcti_platform))) { + if ((ret = create_tcti_spi_ltt2go_platform (&tcti_platform, config))) { return ret; } diff --git a/test/unit/tcti-spi-ltt2go.c b/test/unit/tcti-spi-ltt2go.c index 52b3abb1a..c273b19c9 100644 --- a/test/unit/tcti-spi-ltt2go.c +++ b/test/unit/tcti-spi-ltt2go.c @@ -26,8 +26,12 @@ struct timeval; struct timezone; +#define DEV_DESC_SERIAL_NUMBER_INDEX 1 +#define DEV_DESC_SERIAL_NUMBER "Y23CW29NR00000RND987654321012" + #define VID_PI3G 0x365Du #define PID_LTT2GO 0x1337u + #define CTRL_SET 0xC0u #define CY_CMD_SPI 0xCAu #define CY_SPI_WRITEREAD 0x03u @@ -51,10 +55,12 @@ static const unsigned char TPM_ACCESS_0[] = {0x80, 0xd4, 0x00, 0x00, 0xa1}; static const unsigned char TPM_STS_0[] = {0x83, 0xd4, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00}; static const unsigned char TPM_RID_0[] = {0x80, 0xd4, 0x0f, 0x04, 0x00}; +static tpm_state_t tpm_state = TPM_DID_VID_HEAD_RX; static libusb_device_handle *device_handle; static libusb_context *context; -struct libusb_config_descriptor *config_descriptor; -static libusb_device *usb_device; +static libusb_device *device; +static libusb_device **device_list; +static struct libusb_config_descriptor *config_descriptor; static unsigned char *device_mem_alloc; static size_t device_mem_alloc_length; static uint16_t transfer_length; @@ -93,13 +99,54 @@ int __wrap_gettimeofday (struct timeval *tv, } /* - * Mock function libusb_get_device. + * Mock function libusb_get_device_list. + */ +ssize_t __wrap_libusb_get_device_list (libusb_context *ctx, libusb_device ***list) +{ + ssize_t num_of_devs = 1; + + assert_ptr_equal (ctx, context); + + *list = device_list = malloc (sizeof (*list)); + **list = device = malloc (sizeof (**list)); + + return num_of_devs; +} + +/* + * Mock function libusb_get_device_descriptor. + */ +int __wrap_libusb_get_device_descriptor (libusb_device *dev, + struct libusb_device_descriptor *desc) +{ + assert_ptr_equal (dev, device); + assert_non_null (desc); + + desc->idVendor = VID_PI3G; + desc->idProduct = PID_LTT2GO; + desc->iSerialNumber = DEV_DESC_SERIAL_NUMBER_INDEX; + + return 0; +} + +/* + * Mock function libusb_get_string_descriptor_ascii. */ -libusb_device * __wrap_libusb_get_device (libusb_device_handle *dev_handle) +int __wrap_libusb_get_string_descriptor_ascii (libusb_device_handle *dev_handle, + uint8_t desc_index, unsigned char *data, int length) { + unsigned char *sn = (unsigned char *)DEV_DESC_SERIAL_NUMBER; + int sn_size = strlen ((const char *)sn) + 1; + assert_ptr_equal (dev_handle, device_handle); - usb_device = malloc (1); - return usb_device; + assert_int_equal (desc_index, DEV_DESC_SERIAL_NUMBER_INDEX); + assert_non_null (data); + assert_int_equal (length, 256); + assert_true (length >= sn_size); + + memcpy (data, (const void *)sn, sn_size); + + return sn_size; } /* @@ -108,7 +155,7 @@ libusb_device * __wrap_libusb_get_device (libusb_device_handle *dev_handle) int __wrap_libusb_get_config_descriptor (libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config) { - assert_ptr_equal (dev, usb_device); + assert_ptr_equal (dev, device); assert_int_equal (config_index, 0); config_descriptor = malloc (sizeof (struct libusb_config_descriptor)); config_descriptor->bNumInterfaces = 2; @@ -124,7 +171,23 @@ void __wrap_libusb_free_config_descriptor ( struct libusb_config_descriptor *config) { assert_ptr_equal (config, config_descriptor); - free (config); + free (config_descriptor); + config_descriptor = NULL; +} + +/* + * Mock function libusb_free_device_list. + */ +void __wrap_libusb_free_device_list ( + libusb_device **list, int unref_devices) +{ + assert_ptr_equal (list, device_list); + assert_ptr_equal (*list, device); + assert_int_equal (unref_devices, 1); + free (device); + free (device_list); + device = NULL; + device_list = NULL; } /* @@ -195,8 +258,6 @@ int __wrap_libusb_bulk_transfer (libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout) { - static tpm_state_t tpm_state = TPM_DID_VID_HEAD_RX; - assert_ptr_equal (dev_handle, device_handle); assert_int_equal (timeout, TIMEOUT); assert_int_equal (length, transfer_length); @@ -252,14 +313,26 @@ int __wrap_libusb_bulk_transfer (libusb_device_handle *dev_handle, return 0; } +/* + * Mock function libusb_open. + */ +int __wrap_libusb_open (libusb_device *dev, libusb_device_handle **dev_handle) +{ + assert_ptr_equal (dev, device); + assert_non_null (dev_handle); + *dev_handle = device_handle = malloc (1); + + return 0; +} + /* * Mock function libusb_close. */ void __wrap_libusb_close (libusb_device_handle *dev_handle) { assert_ptr_equal (dev_handle, device_handle); - free (usb_device); - free (dev_handle); + free (device_handle); + device_handle = NULL; } /* @@ -268,7 +341,8 @@ void __wrap_libusb_close (libusb_device_handle *dev_handle) void __wrap_libusb_exit (libusb_context *ctx) { assert_ptr_equal (ctx, context); - free (ctx); + free (context); + context = NULL; } /* @@ -290,21 +364,6 @@ const char * __wrap_libusb_strerror (int errcode) return NULL; } -/* - * Mock function libusb_open_device_with_vid_pid. - */ -libusb_device_handle * __wrap_libusb_open_device_with_vid_pid ( - libusb_context *ctx, uint16_t vendor_id, uint16_t product_id) -{ - assert_ptr_equal (ctx, context); - assert_int_equal (vendor_id, VID_PI3G); - assert_int_equal (product_id, PID_LTT2GO); - - device_handle = malloc (1); - - return device_handle; -} - /* * Mock function libusb_dev_mem_alloc. */ @@ -328,9 +387,9 @@ int __wrap_libusb_dev_mem_free (libusb_device_handle *dev_handle, assert_ptr_equal (dev_handle, device_handle); assert_ptr_equal (buffer, device_mem_alloc); assert_int_equal (length, device_mem_alloc_length); - - free (dev_handle); - free (buffer); + free (device_mem_alloc); + device_mem_alloc = NULL; + device_mem_alloc_length = 0; return 0; } @@ -358,11 +417,85 @@ tcti_spi_no_wait_state_success_test (void **state) assert_non_null (tcti_ctx); /* Initialize TCTI context */ + tpm_state = TPM_DID_VID_HEAD_RX; rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, NULL); assert_int_equal (rc, TSS2_RC_SUCCESS); - TSS2_TCTI_SPI_HELPER_PLATFORM platform = ((TSS2_TCTI_SPI_HELPER_CONTEXT *) tcti_ctx)->platform; - free (platform.user_data); + Tss2_Tcti_Finalize (tcti_ctx); + free (tcti_ctx); +} + +/* + * This test is similar to tcti_spi_no_wait_state_success_test(), + * with the difference being that the serial number is provided as + * one of the input arguments. The focus of this test is to verify + * the serial number matching algorithm. + */ +static void +tcti_spi_no_wait_state_regex_success_test (void **state) +{ + TSS2_RC rc; + size_t size; + TSS2_TCTI_CONTEXT* tcti_ctx; + + /* Get requested TCTI context size */ + rc = Tss2_Tcti_Spi_Ltt2go_Init (NULL, &size, NULL); + assert_int_equal (rc, TSS2_RC_SUCCESS); + + /* Allocate TCTI context size */ + tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc (1, size); + assert_non_null (tcti_ctx); + + /* Positive tests: */ + + /* Initialize TCTI context with S/N: DEV_DESC_SERIAL_NUMBER */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, DEV_DESC_SERIAL_NUMBER); + assert_int_equal (rc, TSS2_RC_SUCCESS); + Tss2_Tcti_Finalize (tcti_ctx); + memset (tcti_ctx, 0, size); + + /* Initialize TCTI context with S/N starting with "Y23CW" */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, "^Y23CW"); + assert_int_equal (rc, TSS2_RC_SUCCESS); + Tss2_Tcti_Finalize (tcti_ctx); + memset (tcti_ctx, 0, size); + + /* Initialize TCTI context with S/N containing "RND9876" */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, "RND9876"); + assert_int_equal (rc, TSS2_RC_SUCCESS); + Tss2_Tcti_Finalize (tcti_ctx); + memset (tcti_ctx, 0, size); + + /* Initialize TCTI context with S/N ending with "321012" */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, "321012$"); + assert_int_equal (rc, TSS2_RC_SUCCESS); + Tss2_Tcti_Finalize (tcti_ctx); + memset (tcti_ctx, 0, size); + + /* Negative tests: */ + + /* Initialize TCTI context with S/N starting with "Z23CW" */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, "^Z23CW"); + assert_int_equal (rc, TSS2_BASE_RC_IO_ERROR); + memset (tcti_ctx, 0, size); + + /* Initialize TCTI context with S/N containing "RND8876" */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, "RND8876"); + assert_int_equal (rc, TSS2_BASE_RC_IO_ERROR); + memset (tcti_ctx, 0, size); + + /* Initialize TCTI context with S/N ending with "321011" */ + tpm_state = TPM_DID_VID_HEAD_RX; + rc = Tss2_Tcti_Spi_Ltt2go_Init (tcti_ctx, &size, "321011$"); + assert_int_equal (rc, TSS2_BASE_RC_IO_ERROR); + + /* Release tcti_ctx */ free (tcti_ctx); } @@ -372,6 +505,7 @@ main (int argc, { const struct CMUnitTest tests[] = { cmocka_unit_test (tcti_spi_no_wait_state_success_test), + cmocka_unit_test (tcti_spi_no_wait_state_regex_success_test), }; return cmocka_run_group_tests (tests, NULL, NULL);