In the following document and in TIFS-MCU document the term used to refer to the Firmware which runs on HSM core is TIFS-MCU Firmware. Please note that the terms 1.**HSMRt Firmware** and 2.**HSMRt** are synonymous to TIFS-MCU Firmware.
Introduction
The objective of HSM client is to provide APIs for accessing HSM services. Below given model explains the use of HSM client graphically. It uses SIPC Notify driver as a low level message passing mechanism to talk to HSM M4 core. HSM client APIs can be used with either FreeRTOS or noRTOS application.
The HSM Server provides APIs that will read the incoming request in the form of SIPC message and provide appropriate service based on it. The application which uses HSM server is also known as TIFS-MCU (HSM runtime firmware).
HSM CLIENT communication model
Along side providing services at runtime TIFS-MCU also enables secure boot flow. It is responsible for decrypting and authenticating R5Fs application images and sends a notification to SBL if it is a valid app image , later SBL will boot the R5 applications to respective cores.
The trusted R5Fs cores which can communicate with HSM are known as Secure hosts.
Note
For HS-SE device specific services, please contact your TI representative to get access to TIFS-MCU add-on package.
Following services are supported in MCU+SDK v9.1.0
BootNotify Service -: A special message sent by TIFS-MCU Firmware to indicate SBL that TIFS-MCU boot was successful.
GetVersion Service -: Get The current version of TIFS-MCU Firmware.
GetUID Service -: Get the unique ID of the device.
Debug Service -: For HS-SE device only. By default debug port for all R5F and HSM is closed. Secure R5Fs can request debug port access via runtime Debug services.
Firewall Service -: Configures the MPU firewall configuration.
Set Firewall Interrupt Service -: Configures the MPU firewall interrupt.
Read OTP Row Data Service -: For HS-SE device only. Get the data from Extended OTP row.
Write OTP Row Data Service -: For HS-SE device only. Write the data to Extended OTP row.
Lock OTP Row Service -: For HS-SE device only. Lock the Extended OTP row.
Get OTP Row Count Service -: For HS-SE device only. Get the count from Extended OTP row.
Get OTP Row Protection Service -: For HS-SE device only. Get the row protection info from Extended OTP row.
Proc Auth Boot Service -: For HS-SE device only. Perform secure boot checks for application images.
Read SW Revision Service -: For HS-SE device only. Get the software revision for SBL, HSM, Application.
Write SW Revision Service -: For HS-SE device only. write the software revision for SBL, HSM, Application.
Get DKEK Service -: For HS-SE device only. Get Derived KEK.
Get Random Number Service -: Get the random number as generated by TRNG engine.
Import Keyring Service -: For HS-SE device only. Import keyring in TIFS-MCU.
Key Writer Service -: For converting device from HSFS to HSSE.
HSM Client message format.
Which public cores are going to be secure hosts will be decided by sysconfig configurations of TIFS-MCU at compile time and user has to make sure that similar configurations is done on the R5F side as well.
Below mentioned is the Message structure defined by SIPC Notify driver. HSM client populates a SIPC message with relevant parameters and sends this message to HSM Server.
SIPC message structure
Message structure description.
DestClientID -: Client Id to which a message is going to be sent. In case of R5F -> HSM ( R5 send message to HSM ) this field will always be equal to 1 because TIFS-MCU is a NORTOS application and only one client is required.
SrcClientID -: Client Id from which a message is going to be sent. In case of HSM -> R5F( HSM send message to R5 ) this field will always be equal to 1.
flags -: Used for ACK and NACK response signals based on weather a request has been processed correctly or not.
Client side signals 1. AOP -> ACK on process 2. NOP -> No ACK on process
Server side signals 1. ACK -> request processed successfully 2. NACK -> request process failure.
Service_type -: Type of a requested service.
Pointer_to_args -: Pointer to the arguments required by a particular service.
CRC16(args) -: CRC16 to check the integrity of arguments.
CRC16(msg) -: CRC16 to check the integrity of message.
The argument will reside in OCRAM and only its pointer is going to be passed in the message itself. When HSM receive the message it reads the argument content from OCRAM and process it. Thus other information needed by HSM server can be passed along with the message through HSM MBOX.
Note
It is strongly suggested that user application must cleary define a boundary between secure R5FSS and non secure R5FSS core's OCRAM memory so that non secure core cannot access the parameters of HSM message. One way to define such boundary is to protect some predefined memory region in OCRAM with firewalls so that only secure cores can access this particular memory region.
HSM client Initialization.
User needs to add an instance of HSM client in Secure R5F's sysconfig configuration.
Select the Secure_host_id for the current secure R5F core.
Note
Make sure that SIPC Message Queue Depth, Number of secure Hosts fields are configured same as in HSM Server's sysconfig.
populate ReqMsg field of HsmClient_t with appropriate paramters.
ReqMsg → destClientId = 0
ReqMsg → srcClientId = current client ID.
ReqMsg → serType = supported service MACRO.
ReqMsg → flags = AOP if ack is expected otherwise NAOP
ReqMsg → args = pointer to message structure based on service type.
ReqMsg → crcArgs = crc of args which is in OCRAM
ReqMsg → crcMsg = crc of the ReqMsg without crcMsg field.
Use SIPC_sendMsg() Api to send the 13 byte message to HSM.
If HSM_FLAG_AOP flag is selected then pend on HsmClient_t::Semaphore till timeout exception occurs or a Response message is received. If HSM_FLAG_NAOP flag is passed then server will not respond with message.
HsmClient_isr() will receive the response message and copy the same in to HsmClient_t::RespMsg and post the semaphore. As this ISR is blocking we want to quickly read the message and exit it.
check RespMsg integrity i.e CRC16 for HSM message and CRC16 for args. if integrity check fails then return SystemP_FAILURE.
If HSM_FLAG_ACK is received then returns SystemP_SUCCESS else SystemP_FAILURE.
HSM Client Load TIFS-MCU API and BootNotify message.
HSM client Module is used by SBL to load TIFS-MCU Fiwmware on HSM core.
SBL includes hsmRtImg.h file which contains TIFS-MCU Firmware in byte format, next the TIFS-MCU will be built along with SBL application.
SBL instantiates HSM client Module via sysconfig and calls HsmClient_loadHSMRtFirmware() which will load the TIFS-MCU Firmware.
After loading TIFS-MCU Firmware SBL application will wait for a HSM_MSG_BOOT_NOTIFY message from HSM server. This messages indicates that TIFS-MCU load is successfull and HSM Server is now ready to take requests from Secure R5F cores.
Similarly on the HSM side once the TIFS-MCU initialization sequence completes it calls HsmServer_sendBootNotify() API to send a BootNotify message.
Boot Notify sequence Flow chart.
Boot Notify sequence Flow chart
HsmClient_waitForBootNotify() API takes two parameters one of them is timeToWaitInTicks, This parameter defines how long SBL will wait for HSM_MSG_BOOT_NOTIFY message .User can change this parameter in SBL source code as per need.
Note
Currently the HsmClient_waitForBootNotify()'s timeToWaitInTicks paramter is set to SystemP_WAIT_FOREVER i.e SBL will keep waiting for HSM_MSG_BOOT_NOTIFY message indefinitely.
This service is used to get the current version of TIFS-MCUFirmware running on HSM core.
User needs to instantiate HsmVer_t object and call HsmClient_getVersion() API to get the current TIFS-MCU's version.
Refer to HsmVer_t_ for the description of different fields that defines a unique TIFS-MCU Firmware version. If User needs to know just the unique 64 bit version ID then, user should read HsmVer_t_::HsmrtVer a 64 bit field which combines all the different fields of HsmVer_t_.
HsmClient_getVersion() API takes timeToWaitInTicks parameter as input which dictates how long application will wait for the response from HSM core. If the timeout exception occurs HsmClient_getVersion() API return SystemP_TIMEOUT.
Example Usage
Demo code for HsmClient_init(). This will be autogenerated by sysconfig.
/*
* HSM Client
*/
/* memory assigned for each R5x <-> HSM channel */
This service is used to configure MPU firewall regions.
User needs to instantiate FirewallReq_t object and populate regionCount and FirewallRegionArr. FirewallRegionArr is an array of mpu firewall regions(FirewallRegionReq_t) to be configured. User can configure 16 MPU firewall configurations in one request and hence the size of array can not be more than 16.
Once the request is processed, HSM populates statusFirewallRegionArr. Each bit of statusFirewallRegionArr represents the status of each region request from FirewallRegionArr. If some region configuration request was not honoured then the corresponding bit position in statusFirewallRegionArr as returned from HSM is 0, otherwise one. For example if a setFirewall request is sent for configuring 6 mpu regions and out of which 1st and 6th region request were illegal configuration then HSM will populate the statusFirewallRegionArr with 0xFFDE (1111 1111 1101 1110).
If status of HsmClient_setFirewall will return SystemP_SUCCESS only when all regions requested were configured by HSM.
User can use sysconfig for generation of region configurations and can use the array directly for instantiating FirewallReq_t object.
Sysconfig interface for generating region configurations
Region to be configured should be 1KB (0x400) aligned and 1KB is the minimum granularity supported for the protected memory map targets size.
Start Address should be a multiple of 1KB (0x400)
(End Address + 1) should be a multiple of 1KB (0x400)
Each Configurable System MPU region details , Configuration address, number of programmable regions are captured in the table below
MPU Firewall Id
MPU Region
MPU Config Addr
Num of Programmable MPU Regions
Target Start Address
Target Size
Target name
0
FW R5SS0_CORE0_AXIS_SLV
0x400A0000
8 (0-7)
0x78000000
64KB
R5SS0_CORE0_TCMA
0x78100000
64KB
R5SS0_CORE0_TCMB
0x74000000
8MB
R5SS0_CORE0_ICACHE
0x74800000
8MB
R5SS0_CORE0_DCACHE
1
FW R5SS0_CORE1_AXIS_SLV
0x400C0000
8 (0-7)
0x78200000
32KB
R5SS0_CORE1_TCMA
0x78300000
32KB
R5SS0_CORE1_TCMB
0x75000000
8MB
R5SS0_CORE1_ICACHE
0x75800000
8MB
R5SS0_CORE1_DCACHE
2
FW R5SS1_CORE0_AXIS_SLV
0x400E0000
8 (0-7)
0x78400000
64KB
R5SS1_CORE0_TCMA
0x78500000
64KB
R5SS1_CORE0_TCMB
0x76000000
8MB
R5SS1_CORE0_ICACHE
0x76800000
8MB
R5SS1_CORE0_DCACHE
3
FW R5SS1_CORE1_AXIS_SLV
0x40100000
8 (0-7)
0x78600000
32KB
R5SS1_CORE1_TCMA
0x78700000
32KB
R5SS1_CORE1_TCMB
0x77000000
8MB
R5SS1_CORE1_ICACHE
0x77800000
8MB
R5SS1_CORE1_DCACHE
4
FW L2OCRAM_BANK0_SLV
0x40020000
8 (0-7)
0x70000000
512 KB
L2OCRAM_BANK0
5
FW L2OCRAM_BANK1_SLV
0x40040000
8 (0-7)
0x70080000
512 KB
L2OCRAM_BANK1
6
FW L2OCRAM_BANK2_SLV
0x40060000
8 (0-7)
0x70100000
512 KB
L2OCRAM_BANK2
7
FW L2OCRAM_BANK3_SLV
0x40080000
8 (0-7)
0x70180000
512 KB
L2OCRAM_BANK3
8
FW MBOX_RAM_SLV
0x40140000
8 (0-7)
0x72000000
16 KB
MBOX_RAM
11
FW QSPI0_SLV
0x40160000
8 (0-7)
0x48200000
256 KB
QSPI0
0x60000000
32 MB
EXT_FLASH0
0x62000000
32 MB
EXT_FLASH1
12
FW SCRM2SCRP0_SLV
0x40180000
15 (1-15)
0x50000000
256 MB
SCRM2SCRP0
13
FW SCRM2SCRP1_SLV
0x401A0000
15 (1-15)
0x50000000
256 MB
SCRM2SCRP1
14
FW R5SS0_CORE0_AHB_MST
0x401C0000
15 (1-15)
0x50000000
256 MB
R5SS0_CORE0_AHB
15
FW R5SS0_CORE1_AHB_MST
0x401E0000
15 (1-15)
0x50000000
256 MB
R5SS0_CORE1_AHB
16
FW R5SS1_CORE0_AHB_MST
0x40200000
15 (1-15)
0x50000000
256 MB
R5SS1_CORE0_AHB
17
FW R5SS1_CORE1_AHB_MST
0x40220000
15 (1-15)
0x50000000
256 MB
R5SS1_CORE1_AHB
TOP_EFUSE_FARM is a non-configurable region and runtime firewall service request will be NACKed if the TOP_EFUSE_FARM falls in any region request.
The service issued to HSM Server verifies the certificate and by default the hsm flag is set to HSM_FLAG_AOP for this service.
Create certificate with full enable or public enable by using scritpts, send certificate via xmodem. Call HsmClient_openDbgFirewall() Api to use debug Services.
HSM Client Read OTP Row Service.
This service is available on HS-SE devices.
The service issued to HSM Server retrieves the data of Extended OTP row based on row index provided as param.
The service issued to HSM Server to transition device from HSFS to HSSE.
User needs to instantiate certificate and call HsmClient_keyWriter() API to convert device from HSFS to HSSE.
HSM Client Get Random Number Service.
This service is used to generate random number.
User needs to instantiate RNGReq_t object and populate resultLengthPtr, give inputs for DRBG Mode. Along with this the user needs to give seedValue and seedSize in words when DRBG Mode is enabled.
Once the request is processed, HSM populates resultPtr. Depending on the inputs given by the user the desired length the resultPtr stores the random number For example if a getRandomNum request is sent without DRBG Mode and desired length as 32 then the resultPtr stores eight 4 bytes random number without seedValue and seedSize inputs. However there are certain checks over the inputs given by the user for example the desired length should be less than equal to 128 and should be a multiple of 16. The seedSize should be less than or equal to 12 and right inputs for enabling and disabling should be given.
The status of HsmClient_getRandomNum will return SystemP_SUCCESS only when all parameters requested were configured by HSM.
Example getRandomNum output
Demo Get Random Number log
HSM Client Import Keyring Service.
This service is available on HS_SE devices.
The service issued to HSM Server by SBL.
This service is responsible for importing keyring.
Once the request, HSM will parse the sent X.509 certificate and populate the keyring in HSM secure ram.