iMX8M Mini EVK, HAB and extending root of trust

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

iMX8M Mini EVK, HAB and extending root of trust

4,244 Views
NeilShipp-MSFT
Contributor II

I'm attempting to extend the root of trust for HAB on the iMX8M Mini.  I can create a signed flash.bin file with SPL, ATF, OpTEE, and UBoot whose signature is checked and loaded successfully.  hab_status shows no events in the hab.  However I cannot create a signed image that extends the root of trust.  If I load the image to ${loadaddr} and run hab_auth_img, I get the following output:

u-boot=> hab_auth_img 0x40480000 0x2960 0x1000
hab fuse not enabled

Authenticate image from DDR location 0x40480000...

Secure boot disabled

HAB Configuration: 0xf0, HAB State: 0x66

--------- HAB Event 1 -----------------
event data:
        0xdb 0x00 0x24 0x43 0x33 0x30 0xee 0x1d
        0x00 0x08 0x00 0x02 0x00 0x00 0x00 0x00
        0x55 0x55 0x00 0x02 0x00 0x00 0x00 0x00
        0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
        0x00 0x00 0x00 0x06

STS = HAB_FAILURE (0x33)
RSN = HAB_ENG_FAIL (0x30)
CTX = HAB_CTX_EXIT (0xEE)
ENG = HAB_ENG_CAAM (0x1D)

To simplify the test, I've created an empty 4kbyte image file of just zeros and

appended a simple IVT that points at the start of the memory block where it's loaded, the ivt self pointer and the csf pointer:

:/mnt/d/imx8/imx8mm-hab$ hexdump blank-pad-ivt.bin
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0001000 00d1 4120 0000 4048 0000 0000 0000 0000
0001010 0000 0000 1000 4048 1020 4048 0000 0000
0001020

I modified the csf file I used to generate the fit blob in the flash.bin file and generated and appended the binary to the above file.

:/mnt/d/imx8/imx8mm-hab$ cat csf_blank.txt
[Header]
    Version = 4.3
    Hash Algorithm = sha256
    Engine = CAAM
    Engine Configuration = 0
    Certificate Format = X509
    Signature Format = CMS

[Install SRK]
    # Index of the key location in the SRK table to be installed
    File = "../crts/SRK_1_2_3_4_table.bin"
    Source index = 0

[Install CSFK]
    # Key used to authenticate the CSF data
    File = "../crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"

[Authenticate CSF]

[Install Key]
    # Key slot index used to authenticate the key to be installed
    Verification index = 0
    # Target key slot in HAB key store where key will be installed
    Target index = 2
    # Key to install
    File = "../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"

[Authenticate Data]
    # Key slot index used to authenticate the image data
    Verification index = 2
    # Authenticate Start Address, Offset, Length and file

    Blocks = 0x40480000 0x0 0x1020 "blank-pad-ivt.bin"

I'm using the 4.14.98_2.0.0ga U-Boot, and have used the example csf templates under uboot/doc/imx/habv4/csf_examples/mx8m_mx8mm to generate the initial signed flash.bin.  I'm using a set of 4096 bit keys and the csf files have been updated to reflect that.

I read through the HabV4 documentation in the cst 3.1.0.tar file and thought that it's possible that the auth check of the fit blob in the flash.bin file after the initial auth check of SPL was causing issues, so I tried adding an Unlock command to the csf_fit.txt file to leave it unlocked for my image check.  I had no success.

[Unlock]
    # Leave Job Ring and DECO master ID registers Unlocked
    Engine = CAAM
    Features = MID

What am I doing wrong?  Any help would be appreciated. 

I tried modifying the data in the memory block to invalidate the signature, and when I do that I get more HAB events about invalid assertions so it appears the block is being validated.  So my problem appears to be that the data and signatures are valid but the CAAM context exit call is failing.

Tags (2)
0 Kudos
12 Replies

2,931 Views
philiph
Contributor I

I managed to get this working by booting the processor to a signed SPL image. The SPL then loads a FIT image, so I sign the FIT image. This contains uboot, op-tee, devicetree.dtb and ArmTrustedFW(bl31). The FIT subsequently validates ok, so you have ROT verified up until this point.  The FIT configurations section in the dts looks like 

configurations {
   default = "conf@1";
   conf@1 {
      description = "Boot Linux kernel with FDT blob";
      firmware = "atf@1";
      loadables = "tee@1", "uboot@1", "fdt@1";
      fdt = "fdt@1";
   };
};

So this tells the SPL to copy uboot, devtree and tee to the relevant destination address and then run ATF (Which then actually boots the TEE and Uboot)

Optee is loaded at 0xbe000000 and is stock from imx-optee-os - i.MX optee os  at branch rel_imx_4.14.78_1.0.0_ga (Though I now notice theres a newer rel_imx_4.14.98_2.0.0_ga branch which i've not tried)

0 Kudos

2,931 Views
NeilShipp-MSFT
Contributor II

Yuri, thank you for the links, but I was already aware of those and had used them to get to the point I am now.

Philip, this is the point where I am.  I have SPL signed and authenticated.  I have a FIT image with UBoot, Tee, ATF and FDT signed and authenticated.  It's when I try to load a third image, a UEFI FIT image in my case, that the HAB check fails. 

I have OpTEE built with CFG_IMXCRYPT turned on, so when ATF loads OpTEE, it goes in and runs the OpTEE CAAM driver initialization code as part of using the cryptographic hardware accelleration.  As part of hal_cfg_get_conf() in hal_cfg.c, it selects a CAAM job ring to use:

jr_cfg->base = ctrl_base;

jr_cfg->offset = (CFG_JR_INDEX + 1) * JRx_BLOCK_SIZE;

jr_cfg->nb_jobs = NB_JOBS_QUEUE;

// Add index of the first SPI interrupt

jr_cfg->it_num = CFG_JR_IRQ + 32;

 

#ifdef CFG_WITH_HAB

if (imx_is_device_closed()) {

jr_cfg->offset = (CFG_JR_INDEX_HAB + 1) * JRx_BLOCK_SIZE;

jr_cfg->it_num = CFG_JR_IRQ_HAB + 32;

}

#endif

When I remove the check for imx_is_device_closed() in the above code, the signature checks on the loaded but not yet executed UEFI image work correctly.  It appears that the OpTEE CAAM initialization interferes with HAB by attempting to use the same job ring and leaving it in a state that HAB doesn't like when the device is unfused.

I think I have also found a code defect in hal_cfg_setup_nsjobring() as well.  It attempts to setup a job-ring to use in non-secure world and actively avoids the job ring that was selected in hal_cfg_get_conf().  But the problem is that it was not updated in the commit that added the #ifdef CFG_WITH_HAB code, so it will avoid the wrong job ring number if the secure job ring CFG_JR_INDEX_HAB (1) is being used.

/* Configure the other Job ring to be Non-Secure */

do {

#ifdef CFG_IMXCRYPT

if (jrnum != (CFG_JR_INDEX + 1)) {

jr_offset = jrnum * JRx_BLOCK_SIZE;

status = hal_jr_setowner(ctrl_base, jr_offset, JROWN_ARM_NS);

...

} while (--jrnum);

Neil Shipp

0 Kudos

2,931 Views
Yuri
NXP Employee
NXP Employee

Hello,

 

 Please provide more details regarding the issue. How it can be reproduced on the

MX8M Mini EVK

Regards,

Yuri.

0 Kudos

2,931 Views
NeilShipp-MSFT
Contributor II

I'm finding that the issue is related to having CFG_IMXCRYPT turned on when building OpTEE and including it in the boot image.  If I build OpTEE with CFG_IMXCRYPT unset, the HAB check of the my boot kernel succeeds with no errors in the HAB log. If I build OpTEE with CFG_IMXCRYPT turned on, I see the failure in the CAAM CTX_EXIT.  Looking through the OpTEE code, I noticed there is a CFG_WITH_HAB compilation definition available.  I tried building with that flag set, but I still see the original problem.  It appears that the CAAM driver in OpTEE is putting the CAAM module into state where HAB can no-longer be used.

What do you need to reproduce this issue?  I'm not using a yocto environment as I'm working on a Windows IoT build.

0 Kudos

2,931 Views
NeilShipp-MSFT
Contributor II

Can the HAB and OpTee use the same job ring in the CAAM?  In OpTEE/core/drivers/caam/hal/common/hal_cfg.c in hal_cfg_get_cfg() at line 234 it has the code:

jr_cfg->offset  = (CFG_JR_INDEX + 1) * JRx_BLOCK_SIZE;

...
jr_cfg->it_num  = CFG_JR_IRQ + 32;

#ifdef CFG_WITH_HAB
 if (imx_is_device_closed()) {
  jr_cfg->offset = (CFG_JR_INDEX_HAB + 1) * JRx_BLOCK_SIZE;
  jr_cfg->it_num = CFG_JR_IRQ_HAB + 32;
 }
#endif

The way I read this is that if the device is closed, the OpTEE job ring will use jr1 (CFG_JR_INDEX_HAB), otherwise jr0 (CFG_JR_INDEX).  So if I'm testing the HAB on the device, but have not yet blown the HAB fuses to close it, it's going to initialize and use jr0.  I find that if I forcibly tell it to use jr1, the code that checks the hab_auth_img call succeeds in U-Boot.  Should the check above be removed and always use jr1 if CFG_WITH_HAB is defined?

0 Kudos

2,931 Views
Yuri
NXP Employee
NXP Employee

 

Hello,

 

 Have You followed The following:

1) recommendations of “i.MX_Linux_User's_Guide.pdf” regarding Optee;

2) section 5.6.10 (OP-TEE enablement) of “i.MX_Yocto_Project_User's_Guide.pdf”;

3) Chapter 5 (Configuring Optee) in “i.MX_Porting_Guide.pdf”?

 

< https://www.nxp.com/webapp/Download?colCode=imx-yocto-L4.14.98_2.0.0_ga >

 

Have a great day,

Yuri

 

 

-------------------------------------------------------------------------------

Note:

- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

 

- We are following threads for 7 weeks after the last post, later replies are ignored

Please open a new thread and refer to the closed one, if you have a related question at a later point in time.

0 Kudos

2,931 Views
NeilShipp-MSFT
Contributor II

I have looked at the linked documentation and it does not cover the scenario of using HAB along with OpTEE.

The "i.MX_Linux_User's_Guide.pdf" document only mentions how to include OpTee for the iMX8QuadMax and iMX8QuadXPlus SOCs in section 4.5.13 "How to build imx-boot image by using imx-mkimage".  It is not mentioned for the iMX8M nor iMX8M Mini.  In section 4.1.1 Bootloader, "TEE OS" is mentioned as loaded by BL31 on the iMX8M Quad and Mini.  I don't see any recommendations regarding OpTee in that document other than in the Security chapter: "Using the i.MX CryptoDev security driver causes the system to run much faster than without it.".  I don't see any mention of high assurance boot in that document other than including the SECO firmware during mkimage for the iMX8Quad SOCs.

For the i.MX Yocto project users guide, section 5.6.10 is very short and only really mentions turning off OpTEE since OpTEE is enabled in the yocto build by default.

Finally, Chapter 5 of the i.MX porting guide, mentions building OpTee, but does not mention HAB nor the CFG_IMXCRYPT option.

I am building OpTee with CFG_IMXCRYPT turned on which it is not by default on iMX8MQ and Mini platforms so that we can use the hardware accelerated CAAM support in our TA applications.  This will be used in devices with HAB turned on.  However during development we don't have the devices fused to enforce secure boot (closed), and when configured as such, the secure boot path fails due to errors in the HAB log.  From the code it looks like if I close the device it will use a code path that uses the job ring 1 instead of job ring 0 of the CAAM module and should work with our constraints.  I am wondering what the intention of the original developer was who decided that only if the device is closed will the OpTEE CAAM driver use jr1 over jr0.

0 Kudos

2,931 Views
Yuri
NXP Employee
NXP Employee

Hello,

     please check  if the latest OP-TEE L4.14.98_2.0.0_ga release is used.

Also:

"TEE-371 Fix HAB booting TEE CAAM enabled"

https://source.codeaurora.org/external/imx/imx-optee-os/commit/?h=imx_4.14.98_2.0.0_ga&id=ffc928d1b0...

Regards,

Yuri.

0 Kudos

2,931 Views
NeilShipp-MSFT
Contributor II

Hello Yuri,

Yes, I'm using the latest 4.14.98_2.0.0_ga release.

Neil.

0 Kudos

2,931 Views
Yuri
NXP Employee
NXP Employee

Hello,

  Please try  to apply patch below in L4.14.98_2.0.0_GA release? This should fix the issue.

 

diff --git a/core/drivers/caam/hal/common/hal_cfg.c b/core/drivers/caam/hal/common/hal_cfg.c
index eff03b22..ae0c38c7 100644
--- a/core/drivers/caam/hal/common/hal_cfg.c
+++ b/core/drivers/caam/hal/common/hal_cfg.c
@@ -51,8 +51,8 @@
 /**
  * @brief   Define the TEE Job Ring to be used
  */
-#define CFG_JR_INDEX           0
-#define CFG_JR_IRQ                     105
+#define CFG_JR_INDEX           1
+#define CFG_JR_IRQ             106
 
 #ifdef CFG_WITH_HAB
 #define CFG_JR_INDEX_HAB       1



Regards,

Yuri.

0 Kudos

2,931 Views
Yuri
NXP Employee
NXP Employee

Hello,

   seems that HAB failure event is only happening in open devices.

Regards,

Yuri.

0 Kudos