Possible Bootloader decryption bug on RT685 when using Encrypted + Signed type.

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

Possible Bootloader decryption bug on RT685 when using Encrypted + Signed type.

1,856 Views
scott-kooy
Contributor III

We have been trying to use "Encrypted + Signed" type for our multi-image.  We use elftosb.exe tool with the following command line: -f rt6xx -J "%SPT_WORKSPACE%\gen_sb\mbi_config.json" to generate the image.  

The mbi_loader.json file is here:

{
"family": "rt6xx",
"inputImageFile": "C:/nxp_files/extram_loader.bin",
"multicoreImages": [
{"address": "0x08000000", "file": "C:/nxp_files/RT685EVK.bin"}
],
"imageLinkAddress": "0x80000",
"outputImageExecutionTarget": "RAM",
"outputImageAuthenticationType": "Encrypted + Signed",
"enableTrustZone": false,
"trustZonePresetFile": "",
"enableHwUserModeKeys": false,
"imageBuildNumber": "1",
"rootCertificate0File": "C:/Users/A9DQSZZ/secure_provisioning0/crts/ROT1_sha256_2048_65537_v3_ca_crt.der",
"rootCertificate1File": "C:/Users/A9DQSZZ/secure_provisioning0/crts/ROT2_sha256_2048_65537_v3_ca_crt.der",
"rootCertificate2File": "C:/Users/A9DQSZZ/secure_provisioning0/crts/ROT3_sha256_2048_65537_v3_ca_crt.der",
"rootCertificate3File": "C:/Users/A9DQSZZ/secure_provisioning0/crts/ROT4_sha256_2048_65537_v3_ca_crt.der",
"mainCertChainId": 0,
"mainCertPrivateKeyFile": "C:/Users/A9DQSZZ/secure_provisioning0/keys/ROT1_sha256_2048_65537_v3_ca_key.pem",
"masterBootOutputFile": "C:/Users/A9DQSZZ/secure_provisioning0/bootable_images/extram_loader.bin",
"deviceKeySource": "OTP",
"useKeyStore": false,
"keyStoreFile": "",
"outputImageEncryptionKeyFile": "C:/Users/A9DQSZZ/secure_provisioning0/gen_sb/userkey.txt"
}

This creates an image that we checked with openssl to make sure we could decrypt it.  The openssl tool completely decrypted the image encrypted by elftosb.exe.  

We take this image and write it to flash using the Secure Provisioning Tool.  

This app runs successfully when using "CRC" or "Signed" type, but will not run as "Encrypted + Signed".  So we put a breakpoint at the start of mpi_loader.  At this point the bootloader should have copied the image to on-chip RAM and decrypted the entire image.  What we are finding is that the image is decrypted, but only to a certain address.  This address changes with every build and always ends on a 16 byte boundary.  The rest of the image is not decrypted correctly, but it DOES NOT match the encrypted image that is stored to flash.  The cert table, encrypted header, IV are all correct at the end, and if we go past the breakpoint, it does run mpi_loader successfully and even start the app, but of course crashes eventually because not all of the app was decrypted correctly.

This seems like a bug in the bootloader.  It should decrypt the entire image.

I don't think it has anything to do with muli-images, because when decryption happens, the entire combined image is decrypted.  

Our combined image is  approx 1,268,000 bytes long.  I was able to run a very short app (120,000 bytes long) successfully.

 

0 Kudos
7 Replies

1,834 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @scott-kooy ,

   Thanks a lot for your effort about the RT600 encrypted+signed.

Do you use this mode?

kerryzhou_0-1634268134749.png

 

Your mentioned: mpi_loader, is it your app?

You also mentioned:

What we are finding is that the image is decrypted, but only to a certain address.  This address changes with every build and always ends on a 16 byte boundary.  The rest of the image is not decrypted correctly, but it DOES NOT match the encrypted image that is stored to flash.  

Could you please also give me the your test example pictues? Eg, the image is decrypted, but just some range, the detail test result will more clear about the issues.

You mentione  cert table, encrypted header, IV are all correct at the end, so FCB, IVT all correct, just the app code decrypt meet issues, right? 

Do you test the SDK simple project, eg, helloworld, whether that works or not?

Best Regards,

Kerry

0 Kudos

1,827 Views
scott-kooy
Contributor III

We are not using the OTFAD mode.  We are using "Encrypted + Signed" mode  which is NOT supported by the Secure Provisioning Tool, but IS supported by elftosb.exe.   We use this mode because we are using external PSRAM.   

As you can see from these lines in the json config file (provided with my last post):

"outputImageExecutionTarget": "RAM",

Indicates that our image will be copied to On Chip RAM from Flash by the bootloader.

"outputImageAuthenticationType": "Encrypted + Signed",

Indicates that our image will also be decrypted entirely in RAM...not On The Fly.

"inputImageFile": "C:/nxp_files/extram_loader.bin",
"multicoreImages": [
{"address": "0x08000000", "file": "C:/nxp_files/RT685EVK.bin"}
],

Indicates that our final image is a combination of two images: the extram_loader.bin and RT685EVK.bin (our application image).  The extram_loader is the image created by NXP's sample project, evkmimxrt685_mpi_loader_extram_loader.  Once the combined image is copied to On Chip RAM and decrypted by the bootloader, the extram_loader runs and copies the RT685EVK.bin (our app) to external PSRAM, and then executes it from PSRAM.  So we are not using OTFAD mode since that mode is only allowed when running XIP out of Flash, as far as we know. (is that true?  If there is a way to use OTFAD mode when running out of external RAM, that would be good to know.)

So all that seems to work for a small application. In the beginning to test the "Encrypted + Signed" mode, I created a very small app to just flash some leds, and this was decrypted correctly by the bootloader, and the app executed perfectly.  But when we tried our actual app which is much larger (1200KB vs. 120KB), we discovered that the combined image was correctly copied to On Chip RAM by the bootloader,  but the image was NOT decrypted correctly. 

We put a breakpoint at the beginning of the extram_loader, so that we could see what was done in the On Chip RAM.  We saw that the image was correctly decrypted up to an arbitrary address.  This address changed anytime we rebuilt the combined image (note that each build uses a different AES256 Init Vector), but the address always was on a 16 byte boundary.  After this address, the decryption was incorrect, until the cert table.  Again, the values after this address did NOT MATCH the values of the original encrypted combined image (image programmed into Flash), so it looks like the bootloader attempted to decrypt those values, but somehow came up with the wrong decrypted values. 

So it looks like the bootloader attempts to decrypt the entire image.  But there is always a point were the decryption fails and the decryption results are incorrect until the cert table.  

You asked for a picture of this:

In the attached, you see on the left is the exported memory from OCRAM which should be completely decrypted.  In the center is the image before encryption.  These two should match, and they match up to 0x6A210, but afterwards they do not.  On the right is the encrypted image.  Note that the OCRAM DOES NOT match the encrypted image after 0x6A210.  If the decryption was just ending prematurely, then the OCRAM should match the encrypted image after 0x6A210, but this is not the case.

Just the image has decryption issues.  The cert table and everything after are not encrypted, so no decryption is needed

I did not test hello world program because I already tested a small app which was decrypted correctly and executed as expected.

Thanks.  Hope that answers all you questions.

 

0 Kudos

1,815 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @scott-kooy ,

  Your test experience is very interesting from your project actual app.

   So, you are using the HAB encrypted + signed mode on the MIMXRT685 chip.

   You are right, if you need the app run in the internal RAM, you need to use the HAB encrypted+signed mode instead of the OTFAD, which is used for the external flash, running code directly on the external flash.

   Now, your situation include two apps.

1. extram_loader: from  evkmimxrt685_mpi_loader_extram_loader,

   The code put in the external flash(0X0800 0000), but it is the internal RAM app.

   So, after chip boot, will run extram_loader in the internal RAM at first.

2.  RT685EVK.bin

  It will be put to the external PSRAM, and is copied by the on chip RAM code extram_loader.bin.

  Whether it is also downloaded to the external FLASH at first?

 

I checked your picture:

2.jpg

Whether the code above 0x6A210,  what's the detail code now?RT685EVK.bin or extram_loader:

Could you please help to check, 0x6A210 is the real RAM address? When you use the internal RAM, do you use it from 0x0? or 0x00080000? I suggest you try load from 0x00080000. RT600 is the same as RT500:

kerryzhou_0-1634526091715.png

Whether if you do it like this, you still have decryption issues or not?

Any updated information, please kindly let me know.

Best Regards,

Kerry

 

0 Kudos

1,809 Views
scott-kooy
Contributor III

 You asked, Whether it is also downloaded to the external FLASH at first?

-Yes NXP's elftosb.exe combines our two images (extram_loader.bin and RT685EVK.bin) into one image and we use the Secure PRovisioning Tool's write_image_win.bat to load the combined image into external Flexspi flash at 0x8001000. 

 You asked, When you use the internal RAM, do you use it from 0x0? or 0x00080000? I suggest you try load from 0x00080000. 

The extram_loader is linked at the 0x80000 base address.  So yes, when the RT685 is reset the bootloader copies this image from external flash into on-chip RAM at 0x80000, and then the extram_loader executes from there.  Please see the line in the JSON file I provided in the original post: 

"imageLinkAddress": "0x80000",

 

You asked, Could you please help to check, 0x6A210 is the real RAM address?

This is not the RAM address.  The RAM address would be the 0x80000 (load address)+ 0x6A210 = 0xEA210.  In that picture I sent, the Left column shows the exported RAM from 0x80000.  So actual RAM address 0x80000 would be 0x00000 on that exported file.  It is much easier to compare to the unencrypted and encrypted file with the same offsets. Does that make sense?

Is there source code available for the bootloader on the RT685S (version 3.0)?  That would be very helpful.

Thanks.

0 Kudos

1,803 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @scott-kooy ,

  Thanks for your updated information.

1. When you use the elftosb do the encrypted+signed type

  Do you refer to some NXP document? Do you write the JSON file by yourself?

  As I want to know your more detail steps, and I will also check with internal side, whether there has some limit to  none XIP encrypted+signed mode, I find the SPT tool just support signed.

kerryzhou_0-1634613758509.png

If you can, please provide more detail steps to generate the encrypted+signed image on your side.

include the elftosb command, and the related bd file you used.

 

2. About the decryption code in RAM, could you please tell me how do you readout it? in debug mode or other mode to readout the RAM code which is decrpted?

I also checked 0X80000+0X6A210=0XEA210, didn't find any special point, so maybe need your more detail steps how to use the elftosb to generate the encrypted +signed data on your side, and download to the flash(you use SPT download).

Do you also check the related code function in the 0XEA210?

I also have a question, if you use the very simple code, which didn't reproduce the issues, then you can add lot of constant data to fill the app larger than 0XEA210, whether it still in the same area which decrypt the code wrong?

 

3. About your mentioned bootlaoder, I find our SDK already contains one ota_bootloader, which will be useful to you, the code path is:

SDK_2_10_1_EVK-MIMXRT685\boards\evkmimxrt685\bootloader_examples

0 Kudos

1,759 Views
scott-kooy
Contributor III

Since the bootloader decryption does not seem to work, we have decided to encrypt our application ourself using openssl.  Then decrypt the application in the extram_loader.  So the extram_loader first copies the encrypted app to PSRAM.  Then it decrypts the entire app in place with the HASHCRYPT_AES_CryptCtr call.  Note that we had problems with that as well.  For some reason, the block size had to be 16 bytes or there would be corruption in the middle of the decrypted file. 

So we used "Signed" instead of "Signed + Encrypted" for "outputImageAuthenticationType", and as said before we used the extram_loader image and the encrypted app image as inputs into elftosb.exe.

In general it was a long and involved process to get this security to work for us, and we still need to plan the OTP fuses, etc.

0 Kudos

1,747 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @scott-kooy 

     I am considering, whether you can use one simple project, then fill the memory larger than your issue size, eg larger than 0XEA210, then try to reproduce the issues on the NXP MIMXRT685-EVK board?

   Just let me reproduce the issues with the simple app, then I can check with our internal expert, and help to find the root issues.

   Now, you use "Signed" instead of "Signed + Encrypted", whether this also have issues or not?

 

Best Regards,

kerry

0 Kudos