|
hsw-nbt 1.2.0
OPTIGA Authenticate NBT Host Library for C
|
C library for Global Platform T=1' communication
This library implements the Global Platform T=1' protocol as a reusable layer for generic Protocol stacks.
As the protocol only works over I2C or SPI a concrete driver implementation of the Infineon hsw-i2c or hsw-spi and hsw-timer interface is required when consuming this library.
If not using cmake to build the code, following macros need to be defined for compilation. Define the IFX_T1PRIME_USE_I2C and IFX_T1PRIME_INTERFACE_I2C macro with a true value (e.g. 1) when compiling your code (this enables the build for the I2C variant of the T=1' protocol).
If using cmake to build the code.
or, during cmake build, we can use
Note: The
SPIinterface is enabled by settingIFX_T1PRIME_USE_I2C=OFF, which will not defineIFX_T1PRIME_INTERFACE_I2C. By defaultIFX_T1PRIME_USE_I2C=ONis enabled from CmakeLists.txt file.
hsw-i2c or hsw-spi:
hsw-i2c or hsw-spi interface is used to abstract the I2C/SPI-specific communication functionality from the target platform. This interface is built on the hsw-protocol APIs. To implement concrete implementation of I2C/SPI driver, (at least) the following functions need to be provided. These functions shall mainly wrap the target MCU's I2C/SPI functions that can be used in hsw-protocol library.
ifx_protocol_t object with the concrete implementation (e.g. ifx_i2c_psoc6_initialize()).This function sets up all members of the provided ifx_protocol_t struct and makes it usable in a generic protocol stack. This function shall do the platform-specific I2C/SPI driver initialization.I2C/SPI (e.g. ifx_i2c_psoc6_transmit()).I2C/SPI (e.g. ifx_i2c_psoc6_receive())For the I2C/SPI-specific functionality the getters and setters also need to be implemented. These shall be used to update the I2C/SPI driver's parameters.(e.g. for I2C - frequency, slave address, or guard time). These getters and setters are defined in the infineon/ifx-i2c.h or infineon/ifx-spi.h interface, which has to be included in the platform-specific implementation.
For the SPI specific functionality the following getters and setters need to be implemented:
ifx_spi_get_clock_frequency(ifx_protocol_t *self, uint32_t *frequency_hz_buffer)ifx_spi_set_clock_frequency(ifx_protocol_t *self, uint32_t frequency_hz)ifx_spi_get_clock_polarity(ifx_protocol_t *self, bool *cpol_buffer)ifx_spi_set_clock_polarity(ifx_protocol_t *self, bool cpol)ifx_spi_get_clock_phase(ifx_protocol_t *self, bool *cpha_buffer)ifx_spi_set_clock_phase(ifx_protocol_t *self, bool cpha)ifx_spi_get_buffer_size(ifx_protocol_t *self, size_t *buffer_size_buffer)ifx_spi_set_buffer_size(ifx_protocol_t *self, size_t buffer_size)ifx_spi_get_guard_time(ifx_protocol_t *self, uint32_t *guard_time_us_buffer)ifx_spi_set_guard_time(ifx_protocol_t *self, uint32_t guard_time_us)For the I2C specific functionality the following getters and setters need to be implemented:
ifx_i2c_get_clock_frequency(ifx_protocol_t *self, uint32_t *frequency_buffer)ifx_i2c_set_clock_frequency(ifx_protocol_t *self, uint32_t frequency)ifx_i2c_get_slave_address(ifx_protocol_t *self, uint16_t *address_buffer)ifx_i2c_set_slave_address(ifx_protocol_t *self, uint16_t address)ifx_i2c_get_guard_time(ifx_protocol_t *self, uint32_t *guard_time_us_buffer)ifx_i2c_set_guard_time(ifx_protocol_t *self, uint32_t guard_time_us)hsw-timer:
The hsw-timer interface is used to abstract timer calls from the target platform. Objects of the ifx_timer_t struct are used throughout all libraries to measure timeout values, waiting times, etc. For a concrete implementation of the timer interface, (at least) the following function(s) need to be provided. These functions shall mainly wrap the target MCU's timer functions which are defined in the hsw-timer interface.
ifx_timer_t object with the concrete implementation (e.g. ifx_timer_psoc6_initialize()). This function sets up all members of the provided ifx_timer_t struct. This function shall do the platform-specific timer driver initialization.void *_start: Pointer to start of the timer.uint64_t _duration: Duration of the timer.For the timer-specific functionality, the following functions need to be implemented. These functions are defined in the infineon/ifx-timer.h interface, which has to be included in the platform-specific implementation.
ifx_timer_set(ifx_timer_t *timer, uint64_t us): Sets a new timer for the amount of microseconds provided in us and stores all required information in its timer parameter.ifx_timer_has_elapsed(const ifx_timer_t *timer): Checks if the given timer has elapsed. Developers can use the members set by ifx_timer_set() to check if the timer has already elapsed.ifx_timer_join(const ifx_timer_t *timer): Waits for the given timer to elapse. Once again developers can use the data they previously set in ifx_timer_set() to calculate timer end times, etc.ifx_timer_destroy(ifx_timer_t *timer): If ifx_timer_set() allocated any dynamic data this function can be used to perform the necessary cleanup.hsw-logger:
hsw-logger interface offers generic ifx_logger_t structs that can be populated by concrete implementations. These ifx_logger_t structs are self-contained and can therefore be nested, joined, etc. The actual logging function uses printf syntax so it should feel familiar to C developers. These loggers can be configured at runtime to a specific level to only trace the desired data (Debug, Info, Warning, Error). Concrete platform implementations are required to use the host MCU's preferred logging methods (e.g. stdout, file-logger). To provide concrete implementation of logger interface, (at least) the following function(s)need to be provided. These functions shall mainly wrap the target MCU's logging function which are used in the hsw-logger interface.
ifx_logger_t object with the concrete implementation (e.g. ifx_logger_psoc6_initialize()). This function sets up all members of the provided ifx_logger_t struct. This function shall do the platform-specific logger initialization.ifx_logger_log_callback_t _log: Logging function for concrete implementation. This _log function shall be set to platform-specific implementation of the logging function, (e.g. printf, UART writing, etc., ).ifx_logger_set_level_callback_t _set_level: Set log level. By default ifx_logger_set_level() will simply update ifx_logger_t._level. If no custom setter is required use NULL.ifx_logger_destroy_callback_t _destructor: ifx_logger_destroy() will call free() for ifx_logger_t._data . If any further cleanup is necessary implement it in this function. Otherwise use NULL.ifx_log_level _level: Set by ifx_logger_set_level(). This shall be initialized to 0.void *_data: Logger properties/state that can be used internally. This shall be set to NULL, if there is no logger properties to be used.The actual logging functions are available in the infineon/ifx-logger.h interface.
Initialize the t1-prime protocol and call the protocol APIs for further protocol communications.
The implementation supports both the T=1' interrupt as well as the polling mode to detect when the secure element is ready to send data. By default polling mode is used.
To enable interrupt mode use ifx_t1prime_set_irq_handler() to set a custom interrupt handler. This interrupt handler shall wait until the GPIO interrupt has triggered or the given amount of microseconds has elapsed. It is up to the concrete implementation to check which GPIO pin to use and how to check if the time has elapsed. This enables platform independent code with interrupt handling being an optional plug-in solution.
The GP T=1' host library implements the proprietary Power On Reset(POR) with S-block(POR-Request) with PCB 1101 1000b (0xd8). This POR performs cold reset and does not replay a response. The Host Device shall wait for a duration of Power Wake-Up Time (PWT) according to the GP T=1' specification before initiating any communication with the Secure Element. Calling ifx_t1prime_s_por() will automatically wait for PWT after transmitting the S(POR) block. The function shall be called as shown below.
The library directory is structured according to the Pitchfork Layout.
Timer related APIs used in Global Platform T=1' protocol stack. It contains mock implementations of source code.