Question about Secre Boot working scenario.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Question about Secre Boot working scenario.

Jump to solution
729 Views
Changhawn
Contributor III
In S32K314 platform, we are developping secure boot(Basic Secure Boot) of Application image in Bootloader.
We did below 1,2,3
 
1. Bootloader is 0x00400000, and ivt (boot_header) is located at 0x00400000.
IVT_BOOT_CFG_WORD_BOOT_SEQ (1 << 3) in the boot configuration word of ivt was not set separately.
 
 
2. Application is 0x00500000, and app_boot_header for secure boot is located at 0x00500000 with the value below.
Application has no IVT. Image signing and verification is failed By IVT header. So remove it.
 
const hseAppHeader_t __attribute__((section("._app_boot_header"))) app_header =
{
.hdrTag = 0xD5 ,
.reserved1 = {0xFF, 0xFF},
.hdrVersion = 0x60 ,
.pAppDestAddres = 0x00,
.pAppStartEntry = (uint32_t)(&__text_start),
.codeLength = (uint32_t)(0x2d0000),
.coreId = 0x00u ,
.reserved2 = {0},
};
 
3. In bootloader, Image signing & verification for secure boot of application is successful as follows. 
bool secure_boot_fw(void)
{
  hseSrvResponse_t srvResponse;
 
  memset((void *)&programmed_appdebugkey,0U,ADKP_LENGTH);
 
srvResponse = HSE_ReadAdkp((uint8_t *)&programmed_appdebugkey);
 
  /*
   * First time when ADKP is not programmed,
   * read adkp will always result in not allowed
   * If ADKP is not programmed then do so
   */
  if( (HSE_SRV_RSP_NOT_ALLOWED == srvResponse))
  {
    printf("[SEC BOOT] ADKP is not programmed\r\n");
    srvResponse = HSE_ProgramAdkp();
    if (HSE_SRV_RSP_OK != srvResponse)
    {
      printf("[SEC BOOT] Program ADKP is failed.(0x%x)\r\n", srvResponse);
      return false;
    }
  }
 
  /* Generate Tag of size 32 over the provided APPBL */
  srvResponse = HSE_SignBootImage(pAppBL, TAG_LENGTH, temp_addr_of_app_image);
  if (HSE_SRV_RSP_OK != srvResponse)
  {
    printf("[SEC BOOT] Sign Image failed.(0x%x)\r\n", srvResponse);
    return false;
  }
 
  GVP_FlashErase(pAppBL + APP_HEADER_LENGTH + AppBL_codeLength, sizeof(temp_addr_of_app_image));
  TestDelay(5000);
 
  GVP_FlashProgram(pAppBL + APP_HEADER_LENGTH + AppBL_codeLength , temp_addr_of_app_image, sizeof(temp_addr_of_app_image));
 
  /* Verify that the generated TAG is valid for the APPBL */
  srvResponse = HSE_VerifyBootImage(pAppBL);
  if (HSE_SRV_RSP_OK != srvResponse)
  {
    printf("[SEC BOOT] Image Verify failed.(0x%x)\r\n", srvResponse);
    return false;
  }
  else
  {
    printf("[SEC BOOT] Image Verify ok\r\n");
    return true;
  }
 
}
 
question)
After I've done image verification in the bootloader, I want to jump to the application. I don't know how to do it.
 
Option 1)
Set IVT_BOOT_CFG_WORD_BOOT_SEQ (1 << 3) in the boot configuration word of the bootloader ivt and reset it. Is it right?
--> C40 API does not work up to bootloader (0x400000) 256k. See Option 1 below.
 
Option 2) Force jump to the application code start address without the application IVT.
--> See option 2. Fault occurs and jump does not occur.
 
 
Option 1. after image verification, set the boot configuration word IVT_BOOT_CFG_WORD_BOOT_SEQ  (1 << 3) IVT of bootloader
 
#define BLOCK0_IVT_ADDRESS 0x00400000U
bool set_secure_boot(void)
{
  ivt_t IVT;
 
  memcpy((void *)&IVT, (void *)BLOCK0_IVT_ADDRESS, 0x100U);
 
  GVP_FlashErase(BLOCK0_IVT_ADDRESS, 0x100U);
  TestDelay(5000);
 
  IVT.bootCfgWord |= IVT_BOOT_CFG_WORD_BOOT_SEQ;
  GVP_FlashProgram(BLOCK0_IVT_ADDRESS , (uint8_t *)&IVT, 0x100U );
 
}
 
c40 api(C40_Ip_MainInterfaceSectorEraseStatus) fault is happened. 
 
Option 2. 
bool secure_boot_jump(void)
{
    hseAppHeader_t *pAppHeader = (hseAppHeader_t *)APP_ADDR;
    
    /* verify the header  */
    if (pAppHeader->hdrTag != 0xD5U || pAppHeader->hdrVersion != 0x60U)
    {
        printf("[SEC BOOT] APP Header is failed\r\n");
        return false;
    }
  
    // check the pAppStartEntry (Not NULL, check if valid)
    if (pAppHeader->pAppStartEntry == 0U || pAppHeader->pAppStartEntry == 0xFFFFFFFFU)
    {
        printf("[SEC BOOT] APP Header is failed with startEntry\r\n");
        return false;
    }
  
    typedef void (*AppEntryPoint)(void);
    AppEntryPoint AppEntry = (AppEntryPoint)pAppHeader->pAppStartEntry; //(0x00500080)
  
    /* Without Timer HAL init, application jump has some problem */
    TIMER_HAL_Deinit();
 
    /* Interrupt disable */
  __asm volatile ("cpsid i" : : : "memory");
    IntCtrl_Ip_DisableIrq(PIT0_IRQn);
    
   /* S32_SCB->VTOR = (uint32_t)(pAppHeader->pAppStartEntry); */
  
    AppEntry();
}
 
0 Kudos
Reply
1 Solution
670 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Let me try to explain: If you take a look at S32K344_Basic_SecureBoot example, it's just configuration project. It's not bootloader, it's not application, it's just configuration project. It's supposed to be executed only first time. Once BOOT_SEQ is set, this project is never executed again.

S32K344_SecureBootBlinky is protected application. If you take a look at its linker file, it starts at 0x005040C0:

lukaszadrapa_0-1747136082064.png

There's app boot header at this address:

lukaszadrapa_1-1747136118563.png

And then there's the application - correctly aligned as mentioned in my last post.

 

Small difference (I was wrong in my previous post) - BOOT_SEQ is already set in boot header in S32K344_Basic_SecureBoot project:

lukaszadrapa_2-1747136297931.png

So, you can simply load the project by debugger, debugger will manually set the program counter to entry point, secure boot is configured and, because BOOT_SEQ is already set, secure boot is active after first reset. Then the S32K344_SecureBootBlinky is started.

But you can reprogram the BOOT_SEQ by your software once the configuration is completed. It's up to you.

To implement this approach to your use-case, you should have configuration project like S32K344_Basic_SecureBoot, then you should have your bootloader which will be protected by basic secure boot (this is equal to S32K344_SecureBootBlinky) and then you should have your application.

How to start application from bootloader: just deinitialize everything and jump to entry point of application. It was discussed here many times, for example here:

https://community.nxp.com/t5/S32K/S32K312-bootloader-jump-to-application-issue/td-p/1795729

Regards,

Lukas

 

 

 

View solution in original post

3 Replies
704 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi

I don't think this approach is correct. I can see that bootloader and application is used but you are signing application only while bootloader is supposed to be run after each reset. This sounds as security risk. And when talking about security risk, our recommendation is to use advanced secure boot mode, not just simple basic secure boot mode.

First thing I can see in your description is that you placed app_boot_header at 0x500000. This is not correct. We provide Secure Boot application note including demo projects. It can be downloaded from:
https://www.nxp.com/products/S32K3
Application note can be found here:
Documentation -> Secure Files -> Secure Boot Application note v0.1.1.0 (AN744511)
Associated demo project can be downloaded here:
Design Resources -> Software -> Secure Files -> SecureBootAppNoteDemo (SW745310)

Take a look at section "5.2 Configuration". This section says that start address of the application must be aligned to 128 bytes, so app header should start at "app_start_adress - 64bytes".

My recommendation is to study following example:
c:\NXP\S32K3_HSE_DemoExamples_1_0_0\S32K3_HSE_DemoExamples\Secure_Boot\S32K344_Basic_SecureBoot\
from:
https://www.nxp.com/webapp/Download?colCode=S32K3_HSE_DemoExamples

It's minimalist example which shows the right procedure. Just notice that BOOT_SEQ is not programmed for some reasons at the end, it's up to user to modify the BOOT_SEQ at the end. And once the BOOT_SEQ is '1', be aware that application is started after next reset after verification. The configuration project won't be started anymore unless you modify BOOT_SEQ back to zero. You can try to run original example and test how it works.

So, if you want to use basic secure boot mode, it makes sense to protect bootloader only, not the application. And then bootloader should verify the application. Personally, I would use advanced secure boot mode for this.

Regards,
Lukas

0 Kudos
Reply
688 Views
Changhawn
Contributor III

Dear Lukas.

Thank u for your answer. 

I am trying to understand what you are talking about.

I am trying to implement basic secure boot to protect only the bootloader.

Question)
When our configuration have two part( bootloader(int_flash) + application),

When the image sign & verification is completed in the bootloader and BOOT_SEQ is set to 1,

After reset, the only application can be executed by the application's ivt.
Is that right?

0 Kudos
Reply
671 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Let me try to explain: If you take a look at S32K344_Basic_SecureBoot example, it's just configuration project. It's not bootloader, it's not application, it's just configuration project. It's supposed to be executed only first time. Once BOOT_SEQ is set, this project is never executed again.

S32K344_SecureBootBlinky is protected application. If you take a look at its linker file, it starts at 0x005040C0:

lukaszadrapa_0-1747136082064.png

There's app boot header at this address:

lukaszadrapa_1-1747136118563.png

And then there's the application - correctly aligned as mentioned in my last post.

 

Small difference (I was wrong in my previous post) - BOOT_SEQ is already set in boot header in S32K344_Basic_SecureBoot project:

lukaszadrapa_2-1747136297931.png

So, you can simply load the project by debugger, debugger will manually set the program counter to entry point, secure boot is configured and, because BOOT_SEQ is already set, secure boot is active after first reset. Then the S32K344_SecureBootBlinky is started.

But you can reprogram the BOOT_SEQ by your software once the configuration is completed. It's up to you.

To implement this approach to your use-case, you should have configuration project like S32K344_Basic_SecureBoot, then you should have your bootloader which will be protected by basic secure boot (this is equal to S32K344_SecureBootBlinky) and then you should have your application.

How to start application from bootloader: just deinitialize everything and jump to entry point of application. It was discussed here many times, for example here:

https://community.nxp.com/t5/S32K/S32K312-bootloader-jump-to-application-issue/td-p/1795729

Regards,

Lukas