** [[#table-of-contents][Table of Contents]] :TOC:QUOTE:
[[#introduction][Introduction]]
[[#key-management-preparing-the-developers-private-dfu-key-and-public-key-certificate][Key management: preparing the developer’s private DFU key and public-key certificate]]
[[#trust-x-personalization-installing-the-developer-certificate-onto-trust-x][Trust X personalization: installing the developer certificate onto Trust X]]
[[#application-preparing-a-dummy-application-for-testing][Application: preparing a dummy application for testing]]
[[#bootloader-prepare-a-trust-x-based-bootloader][Bootloader: prepare a Trust X based bootloader]]
[[#prepare-complete-firmware-binary][Prepare complete firmware binary]]
[[#testing-secure-boot][Testing secure boot]]
[[#using-secure-dfu-without-secure-boot][Using Secure DFU without Secure Boot]]
[[#faq-and-troubleshooting][FAQ and troubleshooting]]
[[#appendix][Appendix]]
Introduction
This guide describes how to set-up and conduct secure device firmware update (DFU) and secure boot on Nordic nRF52 using Infineon hardware-based security. The overall tooling and setup process can appear quite complex, and the individual steps have dependencies on other steps. But once understood, Nordic SDK and Trust X provide an easy, production-quality and exhaustive solution to introduce secure DFU and secure boot into your product. All the steps are illustrated and summarized here: [[file:./doc/dfu-full-flow.png]]
[[#table-of-contents][Top]]
** Required hardware and software
This guide requires a target system (your device) composed of:
[[file:./doc/optiga_trust_x_dfu_s.jpg]]
The software development framework is composed of:
[[#table-of-contents][Top]]
** Development environment
*** Segger Embedded Studio (SES)
This guides is written for Segger Embedded Studio to configure and compile the provided project files. SES is free to use for Nordic customers, and available via [[https://www.nordicsemi.com/Software-and-Tools/Development-Tools/Segger-Embedded-Studio][Nordic's website]].
*** Nordic nRF Connect for Desktop
Nordic's nRF Connect for Desktop, is available at [[https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop][Nordic's website]].
*** Nordic nRF5x Command Line Tools
The nRF5x Command Line Tools contain (among others) the following required tools: =mergehex=, =nrfjprog=. They are typically installed in ~C:\Program Files (x86)\Nordic Semiconductor\nrf5x\bin~ directory. Obtain the complete package from [[https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF5-Command-Line-Tools][Nordic's website]].
** Nordic nrfutil The Nordic command line tool =nrfutil= has to be installed in your Python environment. The Nordic tools require Python 2*, thus install the latest version of Python 2.7. This guide assumes a virtual python environment, located in ~pyenv~. If you are on Windows, and your Python is installed in =C:\Python27\=, create and activate your virtual environment as follows (using PowerShell):
C:\Python27\Scripts\virtualenv.exe pyvenv .\pyvenv\Scripts\activate.ps1
Install ~nrfutil~ with the following command:
pip install nrfutil
** OpenSSL OpenSSL* is a powerful toolkit for cryptography and public key management. OpenSSL in binary form can be obtained via [[http://wiki.overbyte.eu/wiki/index.php/ICS_Download#Download_OpenSSL_Binaries_.28required_for_SSL-enabled_components.29][here]].
*** OPTIGA™ tools python script This small Python script =bin2chex.py= converts any (binary) file into a string formatted as a C array initializer.
[[#table-of-contents][Top]]
** Generate the developer's private key, using Nordic tools Execute the following command:
nrfutil.exe keys generate .\key\developer_key.private.pem
*** Important note on private key protection This private key must be strongly protected:
[[#table-of-contents][Top]]
** Create a self-signed developer certificate Using OpenSSL, create a self-signed developer certificate that contains the developer's public key. The certificate is signed with the private key of the developer.
openssl.exe req -x509 -key .\key\developer_key.private.pem -extensions v3_req -out .\key\developer_key.cert.der -outform DER -config .\tools\openssl.cnf -sha256 -subj '/CN=Developer' -days 10000
The result is the file =developer_key.cert.der=, which contains the developer's public key, wrapped inside a self-signed X.509 certificate. The certificate is encoded in DER format. To compile the certificate into a firmware binary, it needs to be converted into a C-style array that can be inserted into a C source file.
[[#table-of-contents][Top]]
** Output the certificate as C-array formatted string Use the Python script ~bin2chex.py~ to get the certificate printed as a C-array string:
python.exe .\tools\bin2chex.py -f .\key\developer_key.cert.der
[[#table-of-contents][Top]]
[[#table-of-contents][Top]]
** Implement personalization application The SES project for the personalization firmware is located in ~fw_perso\ses\pca10040\s132\ses\perso_pca10040_s132.emProject~.
[[#table-of-contents][Top]]
** About metadata Trust X provides storage slots for several data objects. These data objects can store secret keys, public-key certificates, or general-purpose data. Access conditions must be fulfilled to access or use a data object. [[./doc/trustx-objects.png]]
[[#table-of-contents][Top]]
*** Access types There are four access types.
*** Access conditions
**** Qualifiers | Operator | Symbol | Value (1 B) | --------------+------------+------------- | equal | ~==~ | 0xFA | greater than | ~>~ | 0xFB | less than | ~<~ | 0xFC | logical and | ~&&~ | 0xFD | logical or | \vert\vert | 0xFE |
---|
**** Reference values for LcsG/LcsA/LcsO
Bit State desription 7 6 5 4 3 2 1 0 0 0 0 0 x x x x RFU 0 0 0 0 0 0 0 1 Creation state "cr" = 0x01 0 0 0 0 0 0 1 1 Initialization "in" = 0x03 0 0 0 0 0 1 1 1 Operational "op" = 0x07 0 0 0 0 1 1 1 1 Termination "te" = 0x0F
**** Tags for TLVs Find [[https://github.com/Infineon/optiga-trust-x/wiki/Metadata-and-Access-Conditions#metadata-associated-with-data-and-key-objects][here]]
**** Example
20 11 c0 01 01 c4 01 64 c5 01 64 d0 03 e1 fc 04 d1 01 00 20 11 Metadata constructed TLV object; max metadata size is 0x11 = 17 bytes c0 01 01 LcsO (object life cycle) = creation (cr) c4 01 64 max size of the data object is 0x64 = 100 bytes c5 01 64 used size of the data object 0x64 = 100 bytes d0 03 e1 fc 04 Change access condition descriptor; LcsO [e1] < [fc] 4 [value] == "object can only be changed if if creation or init state" (that is LcsO is either initialization (in) or creation (cr) state) d1 01 00 read access condition; always (ALW)
** Copy developer certificate into personalization application The project contains a C module =ifx_optiga_perso_dfu.c=, which declares and defines an array that contains the entire developer certificate. Locate the variable
static const uint8_t SECURE_DFU_BOOT_CERTIFICATE[]
and copy the C-array formatted string from above.
The application also verifies if the certificate was correctly personalized. This verification steps is done in ~ifx_optiga_perso_dfu.c~, in function ~ifx_optiga_perso_dfu_verify()~. You need to compute a signature that matches your private key, in order for this check to succeed. The instructions are listed in the function's comment block. If you want to skip this step, comment out the verification step and always return ~true~.
[[#table-of-contents][Top]]
** Compile and program the application Compile and link the application, using SES. Connect the target system and program the application onto the nRF52832. Run the application once to conduct the personalization of Trust X. During personalization, the developer certificate is transfer to Trust X and stored safely in the non-volatile memory of Trust X. From now on, it can be used to verify digital signatures that were computed using the developer's private key.
[[#table-of-contents][Top]]
** Preparing the project and compiling the firmware binary One important aspect when preparing the application and the bootloader is to properly and explicitly specify the respective flash sizes and locations. The relevant project-level settings are ~FLASH_SIZE~ and ~FLASH_START~ for each project, as well as ~NRF_DFU_APP_DATA_AREA_SIZE~ for the application project. The following figure shows the memory layout as it is used in the provided bootloader and application: [[./doc/memory-layout.png]]
To demonstrate and test the DFU procedure, at least two application firmware images need to be prepared, to simulate two distinct /versions/ of the application. A dummy SES project for the application is located in ~secure-dfu-boot\fw_app\ses\dummy_app\pca10040\s132\ses\dummy_app_pca10040_s132.emProject~. Open the ~main.c~ and locate the infinite ~while(1)~-loop at the end of the ~main(void)~ function. Modify the ~NRF_LOG_INFO()~ statement to print ~Running application Version 1~. Compile and link the application, using SES. The resulting firmware binary is placed in ~secure-dfu-boot\fw_app\ses\dummy_app\pca10040\s132\ses\Output\Debug\Exe\dummy_app_pca10040_s132.hex~. Copy the hex file ~secure-dfu-boot\fw_app\ses\pca10040\s132\ses\Output\Release\Exe\dummy_app_pca10040_s132.hex~ to secure-dfu-boot\fw_app\hex\~ and rename it to ~v1.hex~. Then, modify the ~NRF_LOG_INFO()~ statement again, to print ~Version 2~ instead. Compile the binary, and copy the resulting hex file, and rename it to ~v2.hex~. Repeat the procedure a few more times to have 5 versions of your application, named ~v1.hex~ to ~v5.hex~.
[[#table-of-contents][Top]]
** Preparing the update packages (ZIP files) The application binaries need to be packaged into update package, composed of the init packet and the firmware binary. The following command create a firmware package that contains a new application binary.
nrfutil pkg generate --sd-req 0xB7 --application .\fw_app\hex\v1.hex --application-version 1 --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --hw-version 52 --key-file .\key\developer_key.private.pem .\fw_app\zip_sec-boot\v1.zip
~--sd-req 0xB7~ defines the requirement SoftDevice version. Use the command ~nrfutil pkg generate --help~ to obtain a list of possible firmware IDs. ~--hw-version 52~ refers to the hardware, with 52 meaning nRF52832, and 52840 meaning nRF52840. ~--application-version-version X~ specifies the version of the application and is used to prevent downgrades (if enabled in bootloader's ~sdk_config.h~). Repeat the above command four more times, to create also update packages for versions 2 throughout 5. Note, that you have to not only change the name of the hex file and the zip files, but also the ~--application-version~ parameter to 2, 3, 4, and 5 respectively.
Print the content of a zip package using the command
nrfutil pkg display .\fw_app\zip_sec-boot\v1.zip
The output looks like the following:
DFU Package: <.\fw_app\zip_sec-boot\v1.zip>: | - Image count: 1 | |
---|---|---|
- Image #0: | ||
- Type: application | ||
- Image file: v1.bin | ||
- Init packet file: v1.dat | ||
- op_code: INIT | ||
- signature_type: ECDSA_P256_SHA256 | ||
- signature (little-endian): afcfdb3870f21a79b3123142fad752a4c13a913960be47df5f30344e016ac56007ab097b4dd8610a5a1c0b4816ecc3fc1774f097512fcb71eba93572378c3fed | ||
- fw_version: 0x00000001 (1) | ||
- hw_version 0x00000034 (52) | ||
- sd_req: 0xB7 | ||
- type: APPLICATION | ||
- sd_size: 0 | ||
- bl_size: 0 | ||
- app_size: 20140 | ||
- hash_type: SHA256 | ||
- hash (little-endian): 296e5aa0c034fb3e7bb67bd3003dbabf943850296e4f52619b3b0fe676a04172 | ||
- boot_validation_type: ['VALIDATE_ECDSA_P256_SHA256'] | ||
- boot_validation_signature (little-endian): ['3b6288a32dd8e4a55f85c6de7a7c22699add9de0013d62e73b6e9f039d4022a622483831fe3f3d6cf0397e209d211bfc45de02ca8a87424f7d4a0a4bc4b5f4f4'] | ||
- is_debug: False |
[[#table-of-contents][Top]]
[[#table-of-contents][Top]]
** Add Trust X dependencies to Nordic SDK bootloader :PROPERTIES: :CUSTOM_ID: section-add-trustx-deps :END: A ready-to-use bootloader project for Trust X is located in ~fw_bootloader\project\pca10040_ble_debug_optiga\ses\secure_bootloader_secure_boot_ble_s132_pca10040_debug.emProject~. It is based on the above Nordic SDK example. The modifications that have been conducted to enable Trust X for signature verification during secure DFU are explained in the appendix. You can go ahead with the bootloader as prepared.
[[#table-of-contents][Top]]
** Testing
*** Program the bootloader To test the bootloader, compile it with SES. Then, connect a Nordic nRF52832 development board, with OPTIGA™ Trust X shield plugged-in on top, to the computer. To make sure the flash of the nRF52832 is completely erased, first connect J-Link (Target > Connect J-Link), and erase the flash (Target > Erase All). Then, program the application and start debuggin (Debug > Go; or F5).
** Conduct a secure firmware update Use a second Nordic development board and connect it to your PC. Run nRF Connect and launch the app Bluetooth Low Engergy. If it is not available in the list, install it via Add/remove apps*.
The app will use your second Nordic board to scan for Bluetooth devices, and to conduct the secure DFU. Thus, select the board and confirm the installation of the required firmware. Start the scan process, and look for your bootloader advertising as =DfuTarg=. Connect to it, and the device will be shown on the screen. Use the /Start Secure DFU/ button to open a dialog where to select the desired firmware update package. Point to one of the ZIP files generated before, and start the DFU process.
If the process completes successfully, the bootloader has successfully verified the firmware update using Trust X.
[[#table-of-contents][Top]]
Therefore, we need to generate a full firmware binary, which includes:
[[#table-of-contents][Top]]
** Create a bootloader settings page To create the bootloader settings page, use =nrfutil=:
nrfutil settings generate --family NRF52 --application .\fw_app\hex\v1.hex --application-version 1 --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --sd-boot-validation VALIDATE_ECDSA_P256_SHA256 --softdevice .\fw_softdevice\s132_nrf52_6.1.1_softdevice.hex --bootloader-version 1 --bl-settings-version 2 --key-file .\key\developer_key.private.pem .\fw_bootloader-settings-page\bls.hex
The option =--bl-settings-version= must be set to 2 (it is not related to the application version, but to its contents). For nRF52832, specify the =--family= option =NRF52=, for nRF52840 the corresponding value is =NRF52840=. The above string splits the command over multiple lines. When pasting it into a console prompt, remove the line breaks to execute it as a single command.
The output will look similar to:
Generated Bootloader DFU settings .hex file and stored it in: .\fw_bootloader-settings-page\bls.hex
Bootloader DFU Settings:
[[#table-of-contents][Top]]
** Merge all firmware binaries into one The four firmware binaries need to be merged into a single hex file. Since =mergehex= only supports merging three files at once, two steps need to be conducted. First, merge bootloader and bootloader settings page: [fn::The line breaks in the command are only to increase readability, remove them before pasting the command into a console window]
mergehex.exe -m .\fw_bootloader-settings-page\bls.hex .\fw_bootloader\hex\secure_bootloader_secure_boot_ble_s132_pca10040_debug.hex -o .\fw_merged\bl+bls.hex
Second, merge previously merged bootloader and settings with SoftDevice and application:
mergehex.exe -m .\fw_merged\bl+bls.hex .\fw_softdevice\s132_nrf52_6.1.1_softdevice.hex .\fw_app\hex\v1.hex -o .\fw_merged\bl+bls+sd+app_v1.hex
[[#table-of-contents][Top]]
** Programming the merged firmware binary For programming, use the Nordic tool =nrfjprog=. First, erase user available code and UICR flash areas:
nrfjprog.exe -e
Then, program the merged hex binary:
nrfjprog.exe --program .\fw_merged\bl+bls+sd+app_v1.hex
Finally, reset your device:
nrfjprog.exe -r
The bootloader will start up your application. To bring the device back into DFU mode, hold button 4 while pressing the reset button. Both buttons are located on the nRF52 development board.
[[#table-of-contents][Top]]
** Conducting a firmware update After the merged firmware binary was programmed, the application version 1 is running on the development kit hardware.
To bring the device back into DFU mode, hold button 4 while resetting the devices with the BOOT/RESET button. The device will immediately enter DFU mode, and can be scanned for with the nRF Connect tool. It will advertise itself as "DfuTarg". Connect to it, and click the DFU button. Select ~fw_app\zip\v1.zip~ and install a new application version. An error will appear, explaining that the firmware version is not accepted by the bootloader (~FW_VERSION_FAILURE~). This happens because the initial, merged firmware that we programmed using ~nrfjprog.exe~, already is version 1, and the bootloader is configured to accept only strictly higher versions.
Thus, select ~fw_app\zip\v2.zip~ and install a new application version - this time successfully.
[[#table-of-contents][Top]]
** Testing secure boot There are two different ways how the effect of secure boot can be observed.
[[#table-of-contents][Top]]
*** Modify the signed application and reset the device Flash version 2 of firmware binary a. Reset the device multiple times, and observe that it always boots into the application. Then, use ~nrfjprog.exe~ to replace the application with another, currently not installed version, e.g., version 5:
nrfjprog.exe --family nrf52 --program .\fw_app\hex\v5.hex --sectorerase
If the device reboots now (e.g., using ~IF BOOT/RESET~ button on the Nordic DK), the secure boot bootloader will detect that the firmware was modified externally, without proper signature update in the settings page. As a result, the application will not be executed, but the bootloader will enter DFU mode again.
*** Add a debug statement to highlight when Trust X is used during the process Alternatively, one can add a debug statement to observe when the signature verification steps is conducted using Trust X, to see the secure boot in action.
diff --git a/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdsa.c b/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdsa.c index 34ba894..ed98474 100644 --- a/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdsa.c +++ b/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdsa.c @@ -50,6 +50,8 @@
+#include "nrf_log.h" + /lint -save -e????/
/lint -restore/ @@ -136,6 +138,9 @@ ret_code_t nrf_crypto_backend_optiga_verify( &oid); }
// consider everything that is not success a signature failure if (res != OPTIGA_LIB_SUCCESS) {
[[#table-of-contents][Top]]
When creating the DFU update ZIP packages, use the following command, which does not add the signature-based boot validation feature, but a simple CRC check instead:
nrfutil pkg generate --sd-req 0xB7 --application .\fw_app\hex\v1.hex --application-version 1 --app-boot-validation VALIDATE_GENERATED_CRC --hw-version 52 --key-file .\key\developer_key.private.pem .\fw_app\zip_dfu-only\v1.zip
Modify the bootloader project: change the ~NRF_BL_APP_SIGNATURE_CHECK_REQUIRED~ from ~1~ to ~0~. ~NRF_BL_APP_SIGNATURE_CHECK_REQUIRED~ tells the bootloader to perform the signature check on the application. The enabled flag requires the signature to be sent in the init packet.
Then re-compile the bootloader, and re-generate the bootloader settings page (note the removed signature requirement for the boot validation, and the lack of need for a key to sign the application):
nrfutil settings generate --family NRF52 --application .\fw_app\hex\v1.hex --application-version 1 --app-boot-validation VALIDATE_GENERATED_CRC --sd-boot-validation VALIDATE_GENERATED_CRC --softdevice .\fw_softdevice\s132_nrf52_6.1.1_softdevice.hex --bootloader-version 1 --bl-settings-version 2 .\fw_bootloader-settings-page\bls.hex
Finally, merge again the hex files using ~mergehex~, and program the merged application using ~nrfjprog~.
[[#table-of-contents][Top]]
The above validation function calls the signature computation via the ~nrf_crypto~ API. In the above project, the OPTIGA™ implementation for the ~nrf_crypto~ API has been enabled in ~sdk_config.h~, thus the verification is conducted using Trust X. Additionally, the public verification key is not part of the bootloader firmware, but stored securely on Trust X.
[[#table-of-contents][Top]]
** LED interference When using the Nordic PCA10040 board with the Trust X Shield the LEDs ~BSP_BOARD_LED_1~ and ~BSP_BOARD_LED_2~ must not be used. These pins are needed for the correct operation of the OPTIGA™ Trust X when using the Arduino-compatible Trust X Shield (Version 0.5).
[[#table-of-contents][Top]]
** Initialization of Trust X backend is stuck
*** Observation The ~while (!timer_elapsed)~ loop in ~pal_os.c:198~ does not exit. The call resulted from the ~optiga_backend_init()~ > ~optiga_util_open_application()~ > ~pal_os_timer_delay_in_milliseconds()~.
*** Investigation The bootloader is doing a ~NVIC_SystemReset~ before the re-initialization of the backend happens. The RTC2 could thus be in an undefined state.
*** Solution For secure boot phase, the SoftDevice is not initialized, and thus also not a clock that the OPTIGA™ PAL relies on. Explicitly initialize the clock: The PAL uses RTC2 for internal timers. To enable this timer the user must ensure that LF clock is running before calling any functions from the OPTIGA™ libraries or the nrf_crypto backend.
// OPTIGA™ stack needs LF clock for RTC2
if (!nrf_clock_lf_is_running())
{
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
}
[[#table-of-contents][Top]]
** Logging debug output of bootloader and application The RTT client can only connect to either the bootloader's logger, or to the application's logger. Thus, there are two workarounds:
[[#table-of-contents][Top]]
** Optimizing bootloader size
*** Forcing a warning if bootloader size exceeds the specified parameters
Nordic's documentation [fn::[https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Findex.html 2019-02-12]] explains:
SES will not detect whether the debug bootloader is too large, instead it will place the code in the MBR params page. To make SES detect this, add the following line in flash_placement.xml:
Place this line immediately after:
The production bootloader is not affected by this issue.
[[#table-of-contents][Top]]
*** Determining the minimum possible bootloader size Two variables describe the bootloader size:
[[#table-of-contents][Top]]
** Where in memory is the master boot record located? The master boot record (MBR) is Nordic proprietary and the source code is not distributed publicly by Nordic. The MBR is part of the SoftDevice binary file. In memory, the MBR is located from ~0x0000 0000~ to ~0x0000 FFFF~.
[[#table-of-contents][Top]]
** Error during DFU procedure (result code 5 - invalid object)
*** Observation 2 or 3 seconds after initiating the download of the update ZIP package to a device in DFU mode, using nRF Connect, an error occurs. The error text says:
When writing 'EXECUTE' command to Control Point Characteristic of DFU Target: Operation code 4 (EXECUTE) failed on DFU Target. Result code 5 (INVALID_OBJECT)
*** Solution One possible for this solution could be incorrect memory sizes for bootloader and/or the applicatoin. Please consult the memory layout illustrated in this guide, and make sure to have no overlap between bootloader and application.
** Error 0x80001003 *** Observation A Trust X host library functions returns the status code 0x8001003 during the signature verification.
[[#table-of-contents][Top]]
*** Solution The error is likely caused by not having increased the heap size to 8192 Byte.
[[#table-of-contents][Top]]
** Modifications to enabled Trust X in bootloader
*** Housekeeping In the file ~secure_bootloader_ble_s132_pca10040.emProject~, replace all occurrences of ~../../../../..~ with the macro ~$(NORDIC_SDK)~. Next, define two new project macros under Project > Right click > Options > Common > Build > Project macros:
INFINEON_LIB=../../../../sdk/optiga-trust-x NORDIC_SDK=NORDIC_SDK=../../../../sdk/nRF5
*** Modifying functionality
**** dfu_public_key.c
Remove the file =dfu_public_key.c= from the project.
Instead, include the file ~
**** nrf_bootloader_dfu_timers.c
First, exclude existing file from the build:
In SES project explorer, navigate to Solution > Project > nRF_Bootloader > nrf_bootloader_dfu_timers.c > Right click > Exclude From Build.
Include the modified file ~
**** nrf_dfu_validation.c Exclude the existing file from the build: In SES project explorer, navigate to Solution > Project > nRF_DFU > nrf_dfu_validation.c > Right click > Exclude From Build. Include the modified file ~fw_bootloader\project\secure_bootloader_secure_boot\pca10040_ble_optiga_debug\nrf_dfu_validation_timers.c~. The modification introduces a new ~#define BOOTLOADER_PUB_KEY_OID~, and initializes the static variable ~m_public_key~ with this OID, instead of the raw public key data.
** OPTIGA-related dependencies
Copy the following lines as a "child" to ~
<folder Name="nRF_Drivers for OPTIGA">
<file file_name="$(NORDIC_SDK)/modules/nrfx/drivers/src/nrfx_rtc.c" />
<file file_name="$(NORDIC_SDK)/modules/nrfx/drivers/src/nrfx_twi.c" />
<file file_name="$(NORDIC_SDK)/modules/nrfx/drivers/src/nrfx_twim.c" />
<file file_name="$(NORDIC_SDK)/integration/nrfx/legacy/nrf_drv_twi.c" />
</folder>
<folder Name="nRF_Libraries for OPTIGA">
<file file_name="$(NORDIC_SDK)/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c" />
<file file_name="$(NORDIC_SDK)/components/libraries/twi_mngr/nrf_twi_mngr.c" />
</folder>
<folder Name="Infineon">
<folder Name="optiga">
<folder Name="cmd">
<file file_name="$(INFINEON_LIB)/optiga/cmd/CommandLib.c" />
</folder>
<folder Name="common">
<file file_name="$(INFINEON_LIB)/optiga/common/Logger.c" />
<file file_name="$(INFINEON_LIB)/optiga/common/Util.c" />
</folder>
<folder Name="comms">
<file file_name="$(INFINEON_LIB)/optiga/comms/optiga_comms.c" />
<folder Name="ifx_i2c">
<file file_name="$(INFINEON_LIB)/optiga/comms/ifx_i2c/ifx_i2c.c" />
<file file_name="$(INFINEON_LIB)/optiga/comms/ifx_i2c/ifx_i2c_config.c" />
<file file_name="$(INFINEON_LIB)/optiga/comms/ifx_i2c/ifx_i2c_data_link_layer.c" />
<file file_name="$(INFINEON_LIB)/optiga/comms/ifx_i2c/ifx_i2c_physical_layer.c" />
<file file_name="$(INFINEON_LIB)/optiga/comms/ifx_i2c/ifx_i2c_transport_layer.c" />
</folder>
</folder>
<folder Name="crypt">
<file file_name="$(INFINEON_LIB)/optiga/crypt/optiga_crypt.c" />
</folder>
<folder Name="include">
<folder Name="optiga">
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/CryptoLib.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/optiga_crypt.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/optiga_util.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/Version.h" />
<folder Name="cmd">
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/cmd/CommandLib.h" />
</folder>
<folder Name="common">
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/common/AuthLibSettings.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/common/Datatypes.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/common/ErrorCodes.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/common/Logger.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/common/MemoryMgmt.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/common/Util.h" />
</folder>
<folder Name="comms">
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/comms/optiga_comms.h" />
</folder>
<folder Name="ifx_i2c">
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/ifx_i2c/ifx_i2c.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/ifx_i2c/ifx_i2c_config.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/ifx_i2c/ifx_i2c_data_link_layer.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/ifx_i2c/ifx_i2c_physical_layer.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/ifx_i2c/ifx_i2c_transport_layer.h" />
</folder>
<folder Name="pal">
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/pal/pal.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/pal/pal_gpio.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/pal/pal_i2c.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/pal/pal_ifx_i2c_config.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/pal/pal_os_event.h" />
<file file_name="$(INFINEON_LIB)/optiga/include/optiga/pal/pal_os_timer.h" />
</folder>
</folder>
</folder>
<folder Name="util">
<file file_name="$(INFINEON_LIB)/optiga/util/optiga_util.c" />
</folder>
</folder>
<folder Name="pal">
<folder Name="nrf5x">
<file file_name="$(INFINEON_LIB)/pal/nrf5x/pal_gpio.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/pal_i2c.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/pal_ifx_i2c_config.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/pal_os.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/pal_os_lock.c" />
<folder Name="nrf_crypto_backend">
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecc.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecc.h" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdh.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdh.h" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdsa.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_ecdsa.h" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_init.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_rng.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_rng.h" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_utils.c" />
<file file_name="$(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend/optiga_backend_utils.h" />
</folder>
</folder>
</folder>
</folder>
*** Update the user include directories The most user-friendly way to edit them is to right click the project > Options > Common > Preprocessor > User Include Directories.
Remove the line:
$(NORDIC_SDK)/components/libraries/crypto/backend/optiga
Add the lines (make sure there are not spaces after each line!):
$(INFINEON_LIB)/optiga/include $(INFINEON_LIB)/pal/nrf5x/nrf_crypto_backend $(NORDIC_SDK)/components/libraries/mutex $(NORDIC_SDK)/components/libraries/timer $(NORDIC_SDK)/components/libraries/twi_mngr $(NORDIC_SDK)/components/libraries/twi_sensor $(NORDIC_SDK)/modules/nrfx/drivers/include $(NORDIC_SDK)/integration/nrfx/legacy $(NORDIC_SDK)/components/libraries/pwr_mgmt
*** Preprocessor definitions Add the following to preprocessor definitions at Project > Right click > Common > Preprocessor > Preprocessor Definintions.
BOOTLOADER_PUB_KEY_OID=0xE0EF DL_MAX_FRAME_SIZE=250
The ~BOOTLOADER_PUB_KEY_OID~ specifies the object ID of the Trust X data object that holds the public key certificate. The OID value must correspond to the OID value used in the personalization application, where this public-key certificate is stored in the respective slot.
Due to EasyDMA restrictions on nRF52832 devices, it is necessary to set a project-level define =DL_MAX_FRAME_SIZE=250= to use the nrf5x Platform Abstraction Layer (PAL). This PAL is required by the Trust X host library, which is used by the OPTIGA™ backend implementation.
*** SDK configuration (sdk_config.h) Modify the following values in the ~sdk_config.h~:
NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED 0 NRF_CRYPTO_BACKEND_OPTIGA_ENABLED 1 NRF_CRYPTO_RNG_AUTO_INIT_ENABLED 0 NRF_QUEUE_ENABLED 1
Replace the lines
with
// NRF_TWI_MNGR_ENABLED - nrf_twi_mngr - TWI transaction manager
//
//
// <0=> RC // <1=> XTAL // <2=> Synth // <131073=> External Low Swing // <196609=> External Full Swing
//
// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice // <0=> 0 (highest) // <1=> 1 // <2=> 2 // <3=> 3 // <4=> 4 // <5=> 5 // <6=> 6 // <7=> 7
//
//
//
// RTC_DEFAULT_CONFIG_RELIABLE - Ensures safe compare event triggering
//
// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice // <0=> 0 (highest) // <1=> 1 // <2=> 2 // <3=> 3 // <4=> 4 // <5=> 5 // <6=> 6 // <7=> 7
// RTC0_ENABLED - Enable RTC0 instance
// RTC1_ENABLED - Enable RTC1 instance
// RTC2_ENABLED - Enable RTC2 instance
//
//
//
//
// <26738688=> 100k // <67108864=> 250k // <104857600=> 400k
// TWI_DEFAULT_CONFIG_CLR_BUS_INIT - Enables bus clearing procedure during init
// TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit
//
// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice // <0=> 0 (highest) // <1=> 1 // <2=> 2 // <3=> 3 // <4=> 4 // <5=> 5 // <6=> 6 // <7=> 7
//
// TWI0_USE_EASY_DMA - Use EasyDMA (if present)
//
//
// TWI1_USE_EASY_DMA - Use EasyDMA (if present)
//
//
// //==========================================================
And replace
with
//
//
// Selected pin will be set when CPU is in sleep mode. //==========================================================
//
// <0=> 0 (P0.0) // <1=> 1 (P0.1) // <2=> 2 (P0.2) // <3=> 3 (P0.3) // <4=> 4 (P0.4) // <5=> 5 (P0.5) // <6=> 6 (P0.6) // <7=> 7 (P0.7) // <8=> 8 (P0.8) // <9=> 9 (P0.9) // <10=> 10 (P0.10) // <11=> 11 (P0.11) // <12=> 12 (P0.12) // <13=> 13 (P0.13) // <14=> 14 (P0.14) // <15=> 15 (P0.15) // <16=> 16 (P0.16) // <17=> 17 (P0.17) // <18=> 18 (P0.18) // <19=> 19 (P0.19) // <20=> 20 (P0.20) // <21=> 21 (P0.21) // <22=> 22 (P0.22) // <23=> 23 (P0.23) // <24=> 24 (P0.24) // <25=> 25 (P0.25) // <26=> 26 (P0.26) // <27=> 27 (P0.27) // <28=> 28 (P0.28) // <29=> 29 (P0.29) // <30=> 30 (P0.30) // <31=> 31 (P0.31) // <4294967295=> Not connected
//
// NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED - Enables CPU usage monitor.
// Module will trace percentage of CPU usage in one second intervals.
//
//
//
// NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED - Enables FPU event cleaning.
// NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY - Blocked shutdown procedure will be retried every second.
// NRF_PWR_MGMT_CONFIG_USE_SCHEDULER - Module will use @ref app_scheduler.
//
//
*** Linker settings The OPTIGA™ library allocates memory on the heap. For proper operation, the heap should have a size of 8,192 Bytes or larger. Configure the heap size at Project > Right click > Common > Runtime Memory Area > Heap Size.
*** Section placement macros The placement of memory sections is defined by the XML file ~flash_placement.xml~, referenced from Project > Right click > Common > Linker > Section Placement File. The file uses macros to specify bootloader and application sizes, defined in Project > Right click > Common > Linker > Section Placement Macros. The macros =FLASH_START= and =FLASH_SIZE= define the location and size of the bootloader's program code. For the provided example, use the following values:
FLASH_START=0x70000 FLASH_SIZE=0x0e000
Nordic explains in a blog post[fn::https://devzone.nordicsemi.com/tutorials/b/getting-started/posts/adjustment-of-ram-and-flash-memory 2019-01-21] how a developer can adjust the RAM and FLASH memory start addresses.
*** Pin conflict (Trust X Shield) The pins for LEDs 1 and 2 on the Nordic DK are conflicting with the RST and VCC pins for Trust X. To resolve this issue, comment out the lines that control the respective LEDs in the bootloader's ~main.c~ file:
// bsp_board_led_on(BSP_BOARD_LED_1); // bsp_board_led_off(BSP_BOARD_LED_2); // bsp_board_led_off(BSP_BOARD_LED_1); // bsp_board_led_on(BSP_BOARD_LED_2);
[[#table-of-contents][Top]]