Secure blink

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
OnPi_2263161
Level 4
Level 4
First like received Code Expert

Hi all,

I would like to write own DFU application in C++. My first step is to try to make blink example to be verified by the Chain of Trust. It shows me how to sign an application, setup TOC2 and use generated RSA keys.

I took CE222802_Bootloader_Encrypted_App and Secure Image as a reference design. From them TOC2, cy_si_keystorage.c (public key generated part is changed to match project RSA key), cypress standard application header, linker scripts, and application signature were used.

The project takes signed elf files for both cores merges them in single elf file which is digitally signed by the cymcuelftool and RSA key. Now I am in a state that TOC2 should be written in the right place (no other example is running on a chip after the project is written) but signature validation fails. No eFuse is written all are tested in Normal mode.

Could someone look at my project and tell me what can be wrong? How can verification be debugged or what steps I can take to test TOC2, signature or other Chain of Trust parts to find a root of the issue?

Best Regards

Ondrej

0 Likes
10 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

In which step of validation is it failing?

You can check where exactly it fails in the Chain of Trust:

(1) Doesn't enter FlashBoot ---> SFlash validation failed

(2) Doesn't enter Secure Image Application ----> Secure Image validation failed

(3) Doesn't enter User Application -----> User Image validation failed

Can you explain in detail the changes you did to TOC2, cy_si_keystorage.c and other files you were using?

Details regarding TOC2 can be found in Page#15 in the following document: https://www.cypress.com/file/447981/download

Regards,
Dheeraj

0 Likes

Hi Dheeraj,

How can I check 1 and 2.? From GDB I know that execution halted on the address 0x1f34.

All files was taken without changes except cy_si_keystorage.c where I use new key.

My project is based on the proposed document.

Regards

Ondrej

0 Likes

Before you make use of the files in your application, please use PSoC Creator to ensure its working. The IDE will make it easier to check if the root of trust is working correctly after which you can switch to using it in your application.

If SFLASH validation fails it means the secure_hash calculated using the factory hash + TOC2 + Public Key has failed validation. Hence the error is either in the TOC2 configuration or due to an incorrect public key.

You can use UART to print useful information when it enters the secure image application and eventually the user application. If it doesn't enter the secure image application, then the public key might be causing the issue.

Since only the cy_si_keystorage.c file was changed, where the public key is stored, I think this might be root cause behind this. Please generate new keys following the steps listed in the application note correctly and try again: https://www.cypress.com/file/447981/download

Regards,

Dheeraj

0 Likes

RSA key check: I taken RSA key (private/public) and cy_si_keystorage.c from the example CE222802. With the key SFLASH validation failed too.

I know that cypress application header and merged elf file is correct because whole project starts when I change CY_SI_FLASHBOOT_FLAGS to not validate:

/* Flashboot parameters */

#define CY_SI_FLASHBOOT_FLAGS ((CY_SI_FLASHBOOT_VALIDATE_NO << CY_SI_TOC_FLAGS_APP_VERIFY_POS) \

                                | (CY_SI_FLASHBOOT_WAIT_20MS << CY_SI_TOC_FLAGS_DELAY_POS) \

                                | (CY_SI_FLASHBOOT_CLK_25MHZ << CY_SI_TOC_FLAGS_CLOCKS_POS))

Where is secure_hash stored and should I somehow compute it?

Is there a way how to manualy perform same check as SFLASH validation do?

Regards

Ondrej

0 Likes

The SECURE_HASH validation is done only after you transition from Normal to Secure mode. Did you blow the E-Fuse bits to put the device into secure mode?

The secure hash is stored in the E-Fuse and the sflash validation is executed in the ROM. You need not compute it, you need to only make sure you provide the right values in the TOC2 and public key.

Note that if you haven't written into the efuse bits to put it into secure mode, then secure hash validation doesn't come into picture. You should be able to enter the secure image application if you have provided the right public key.

Regards,

Dheeraj

I would like to test everything possible in the Normal mode and later transits in the Secure one. Especially because there isn't transition back to the Normal.

My TOC2 is following (linker_scripts was taken from the CE222802 example😞

/* Flashboot parameters */

#define CY_SI_FLASHBOOT_FLAGS ((CY_SI_FLASHBOOT_VALIDATE_NO << CY_SI_TOC_FLAGS_APP_VERIFY_POS) \

                                | (CY_SI_FLASHBOOT_WAIT_20MS << CY_SI_TOC_FLAGS_DELAY_POS) \

                                | (CY_SI_FLASHBOOT_CLK_25MHZ << CY_SI_TOC_FLAGS_CLOCKS_POS))

/* TOC Part 2 Definition */

__attribute__ ((section(".cy_toc_part2"))) __USED

const cy_stc_si_toc_t cy_toc2 = {

  .objSize        = sizeof(cy_stc_si_toc_t) - sizeof(uint32_t),   /**< Object Size (Bytes) excluding CRC */

  .magicNum       = CY_SI_TOC2_MAGICNUMBER,                       /**< TOC2 ID (magic number) */

  //.userKeyAddr    = 0,                                            /**< User key storage address */

  .userKeyAddr    = (uint32_t) &CySecureKeyStorage,               /**< User key storage address */

  .smifCfgAddr    = 0UL,                                          /**< SMIF config list pointer */

  .appAddr1       = (uint32_t) (&__cy_app0_verify_start),                       /**< App0 start address */

  .appFormat1     = CY_DFU_CYPRESS_APP,                           /**< App0 Format */

  .appAddr2       = 0,                                            /**< App1 start address */

  .appFormat2     = CY_DFU_BASIC_APP,                           /**< App1 Format */

  .shashObj       = 1UL,                                          /**< Include public key in the SECURE HASH */

  .sigKeyAddr     = (uint32_t)&SFLASH->PUBLIC_KEY,                /**< Address of signature verification key */

  .addObj         = {0},

  .tocFlags       = CY_SI_FLASHBOOT_FLAGS,                        /**< Flashboot flags stored in TOC2 */

  .crc            = 0UL,                                          /**< CRC populated by cymcuelftool */

};

Actually, I think that a correct application header is needed too.

__attribute__ ((section(".cy_app_header"))) __USED

const cy_stc_user_appheader_t applicationHeader = {

  .objSize        = (uint32_t) (&__cy_app0_verify_length),   /* Application Size (Bytes) excluding hash */

  .appId          = CY_SI_APP_VERSION,                /* App ID */

  .appAttributes  = 0UL,                              /* Reserved */

  .numCores       = 2UL,                              /* CM0+ and CM4 */

  .core0Vt        = (uint32_t)(&__Vectors[0]) - APP0_START_ADDRESS - offsetof(cy_stc_user_appheader_t, core0Vt),               /* Offset to CM0+ Vector Table in flash */

  .core1Vt        = (uint32_t)(&__cy_app_core1_start_addr) - APP0_START_ADDRESS - offsetof(cy_stc_user_appheader_t, core1Vt),  /* Offset to CM4 Vector Table in flash */

  .core0Id        = CY_ARM_CM0P_CPUID,                /* ARM CM0+ CPU ID */

  .core1Id        = CY_ARM_CM4_CPUID,                 /* ARM CM4 CPU ID */

};

Would you please correct me if the following procedure with the cymcuelftool isn't correct:

cymcuelftool --sign cortexM4.elf --output cortexM4_signed.elf

cymcuelftool --sign cortexM0p.elf --output cortexM0p_signed.elf

cymcuelftool --merge cortexM4_signed.elf cortexM0p_signed.elf --output merged.elf

cymcuelftool --sign merged.elf SHA256 --encrypt RSASSA-PKCS --key cypress_key.pem --output final.elf --hex final.hex

Regards

Ondrej

0 Likes

Could you write and provide a software tool which verifies if an image is valid for the Chain of Trust?

It will be helpfull to know that everything is properly set before locking a chip in Secured mode (lock with wrong values is expensive operation).

0 Likes

Hello Ondrej,

The procedure used for cymcuelftool is correct. Yes, before you switch to Secure mode, you can make use of Secure with Debug mode to make sure everything works as expected. Please debug your project to get more information on where the validation is failing.

Please note that you cannot make a transition from Secure w/ Debug to Secure. Have a look at the Lifecycle Stages section in this Application Note to know more.

We do not have a tool to verify if the image is valid. I will pass this request to the product development team who will process your query.

Regards,

Dheeraj

0 Likes

Hello Dheerajk,

finally, I fixed my secured blink example.

Could you please extend Creating a Secure System (AN221111) with a note that all flashes have to be erased before flashing it or extend linker script to fill unused flash with know value as 0xff?

Regards

Ondrej

Hello Dheerajk,

how does cymcuelftool merge two elf files?

I updated linker scripts to fill remaining flash for both cores with 0xdeadbeef to have whole secure blink flash memory defined. Cyumcuelftool reduces .fill section on 0x448 bytes.

cortex-m0 elf map file:

.fill           0x0000000010001f6c     0xdf94

arm-none-eabi-readelf -s output:

[33] .merged4          PROGBITS        10001f6c 123370 000448 00 WAX  0   0  8

Regards

Ondrej

0 Likes