This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] CC1312R7: Different size, Serial tracing and encrypted MCUBoot tutorial

Part Number: CC1312R7
Other Parts Discussed in Thread: SYSCONFIG, , UNIFLASH

Recently I had to go through a hard process of searching and trying to make first a different size program, then add serial tracing and last be able to encrypt it.

The idea of this tutorial is to give anyone looking to do the same thing the necessary steps to be able to make encryption work, thanks to Arthur R. and Lucas Holzen for the provided help.

I'm aware that some steps would need more explanation but given that this is a fairly complex topic I take for granted that anyone willing to do this has knowledge enough to solve this details(example: how to link the tinycript library into MCUBoot).

  1. Adding tracing to the program: following the steps provided in this thread by Arthur (warning program won’t fit into the example Bootloader slot):

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1276823/cc1312r7-update-throught-serial-port-modify-bim-or-modify-bootloader

quoting from Arthur:

“For logging, you need to disable the EXCLUDE_TRACE symbol, by for instance appending "x" to it in the project settings:”

After that, you need to copy the itm_private.h, trace.c and trace.h files from SDK_PATH\source\third_party\mcuboot\boot\ti\source\mcuboot_app\mcuboot_config to the mcuboot_config folder of the mcuboot_app project.

Last, add the Power driver to SysConfig

Then if you are working with the CC1312R7 change debug output to

1 - ITM_3000000 to ITM_115200 in trace.c to change baud speed to 115200 (in my case to have the same speed as main program). 

2 - IOCPortConfigureSet(IOID_13, IOC_PORT_MCU_SWV, IOC_STD_OUTPUT) to IOCPortConfigureSet(IOID_3, IOC_PORT_MCU_SWV, IOC_STD_OUTPUT); in trace.c to output serial trace in normal serial port.

Congratulations, serial tracing is enabled but now the program doesn’t fit into the slot, let's change that.

2. Change Slot size:Default slots in the example don’t leave space for user save data for example to NVS use and Bootloader Space is a bit small for my liking, so I had to change that as well.

  1. Decide the memory organization: First slot program size, this will be the maximum program size available to you for updating the program in the future, in my case it was (0x40000) (256Kb), which left me space to the new firmware (another 0x40000) , NVS space (0x20000)(128Kb) and finally bootloader (0x10000)(64Kb).

  2. With the calculated values go to flash_map_backend.h and change the values in (my case DeviceFamily_CC13X2X7)

#elif defined(DeviceFamily_CC13X2X7) || defined(DeviceFamily_CC26X2X7)
    #define BOOTLOADER_BASE_ADDRESS             0x000A0000
    #define BOOT_BOOTLOADER_SIZE                0x00010000-0x58

    #define BOOT_PRIMARY_1_BASE_ADDRESS         0x00000000
    #define BOOT_PRIMARY_1_SIZE                 0x00040000


    #define BOOT_SECONDARY_1_BASE_ADDRESS       0x00040000
    #define BOOT_SECONDARY_1_SIZE               0x00040000

For some reason Bootloader size has to be 0x58 smaller than the assigned slot.

3. Change Address of Flash Vector Table in sysconfig/Device configuration (without doing this the program works in debug but not downloading it with uniflash)

4. Modify mcuboot_config.h to use MCUBOOT_OVERWRITE_ONLY , if you use for example MCUBOOT_DIRECT_XIP you won't be able to use encryption and you will have to specify start flash address to cmd and sysconfig for each sector (I wouldn’t recommend it because it makes necessary to compile the program for sector 1 or 2 with different parameters).

5. Now we have to change the .cmd to the size of the slot, in this case (mcuboot_cc13x2x7_cc26x2x7.cmd) to the new start address and size ( I also added some space for the new FW and NVS use).

#define NEW_FW_BASE             0x40000
#define NEW_FW_SIZE		        0x40000

#define FLASH_BASE              0xA0000
#define FLASH_SIZE              0x10000
#define RAM_BASE                0x20000000
#define RAM_SIZE                0x24000
#define GPRAM_BASE              0x11000000
#define GPRAM_SIZE              0x2000


/* System memory map */

MEMORY
{
    /* Application stored in and executes from internal flash */
    FLASH (RX) : origin = FLASH_BASE, length = FLASH_SIZE

    NEW_FW (RWX) : origin = NEW_FW_BASE, length = NEW_FW_SIZE
    /* Application uses internal RAM for data */
    SRAM (RWX) : origin = RAM_BASE, length = RAM_SIZE
    /* Application can use GPRAM region as RAM if cache is disabled in the CCFG
    (DEFAULT_CCFG_SIZE_AND_DIS_FLAGS.SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM = 0) */
    GPRAM (RWX): origin = GPRAM_BASE, length = GPRAM_SIZE
}

6.In the application side we must do some changes as well to the .cmd (I will use the blinky example for this).

//size of the programs

#define PROGRAM_SIZE 0x40000
#define HDR_SIZE 0x80


	#define FLASH_BASE              HDR_SIZE
	#define FLASH_SIZE              PROGRAM_SIZE-HDR_SIZE
	#define RAM_BASE                0x20000000
	#define RAM_SIZE                0x24000
	#define GPRAM_BASE              0x11000000
	#define GPRAM_SIZE              0x2000


	/* Export the header address to the blinky app */
	MCUBOOT_HDR_BASE = HDR_SIZE;

7.In the post-process step in build change: 

sign --header-size 0x80 --align 4 --slot-size 0x56000 --version 1.0.0 --pad-header --pad      
 to 

sign --header-size 0x80 --align 4 --slot-size 0x40000 --version 1.0.0 --pad-header --pad 

8.Now you should be able to load the blinky with MCU Bootloader(To check that everything is working to this point).

To do so:

1-Open uniflash.

2-Go to settings and select: Erase All Unprotected Sectors. (To have an empty starting point)

3-Load the generated .Hex file of MCUBoot (Not the blinky!).

4-Go to settings and select: Necessary Sectors Only (Retain untouched content within sector)

5-Load the generated .bin file of blinky program in 0x40000(in my case).

6-Open a serial terminal to the debug port at the selected itm speed in trace.c, in my case 115200 (to have the same as in my main program).

6-Reset the device.

If everything went fine the board should blink red, then 3 times green (good program found in secondary sector) then starts blinking green and red.

In the serial terminal you should get a log with a lot of [01], what I do is to copy it to notepad++ and substitute it to nothing which gives a more readable text (if anyone knows how to get rid of this [01] it would be really appreciated).

3-How to decrypt the application in MCUBoot(EC256) and encrypt the application 

Following the instructions from Lucas Holzen and with a lot of research I was able to make encryption work but there were some crucial steps to be found.

1-Copy  tiny crypt Ti implementation from to your MCUBoot folder and link it: cc13xx_cc26xx_sdk\source\ti\mesh\zephyr\subsys\bluetooth\mesh\tinycrypt

2-Implement a CSPRNG function in ecc_platform_specific.c:

void default_CSPRNG(uint8_t *dest, unsigned int size) {

    TRNG_Params trngParams;
    TRNG_Handle trngHandle;

    // Initialize TRNG
    TRNG_Params_init(&trngParams);
    trngHandle = TRNG_open(0, &trngParams);

    if (trngHandle == NULL) {
        // Error in initialization
        return;
    }

    // Generate random numbers
    TRNG_getRandomBytes(trngHandle, dest, size);

    // Close TRNG
    TRNG_close(trngHandle);
}

Thanks ChatGPT Blush(yes I'm trying to write some code with chat gpt to see the outcomes and so far is not bad).

3-Add TRNG support in sysconfig.

4-Modify mcuboot_config.h:

commenting out:

MCUBOOT_USE_TI_CRYPTO
 

And including

#define MCUBOOT_OVERWRITE_ONLY
#define MCUBOOT_ENC_IMAGES 1
#define MCUBOOT_ENCRYPT_EC256
#define MCUBOOT_USE_TINYCRYPT 1
#define MCUBOOT_SIGN_EC256

5-Change tc_ctr_mode function.

rc = tc_ctr_mode(out, inlen, in, inlen, counter, &blk_off, ctx); 
  to 

rc = tc_ctr_mode(out, inlen, in, inlen, counter, ctx); 

in aes_ctr.h, this removes the offset which as far as I looked was not used and is the implementation used in Ti Tinicrypt.

6-Uncomment the requested functions in the program which will give error.

7-Try to compile it, it should work now.

8-In the application program side now use –encrypted command with the desired certificate(first see part 4) (Not tested with the example certificate):

${COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR}/tools/common/mcuboot/imgtool                 sign --header-size 0x80 --align 4 --slot-size 0x40000 --version 1.1.1 --pad-header --pad    --key ${COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR}/source/third_party/mcuboot/root-ec-p256.pem           --encrypt ${COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR}/source/third_party/mcuboot/root-ec-p256.pem              ${ProjName}-noheader.bin ${ProjName}_Encripted.bin

Congratulations now the bootloader has the decryption capabilities and we know how to encrypt the program but how do we generate keys and implement them? 

 4- generate your own certificates and implement keys.

1.Install python 3 to run the imgtool program which we will use.

2. Go to SDK_PATH\source\third_party\mcuboot\source\scrips

3. Open a terminal there.

4. To generate a certificate use:

python imgtool.py keygen -k Test_certificate.pem -t ecdsa-p256

 this will create Test_certificate.pem 

5. I will create another one to sign the header:

 

python imgtool.py keygen -k Test_certificate_header.pem -t ecdsa-p256


6.Now the key point: application signing requires the PUBLIC keys, encryption requires the PRIVATE keys(this point drove me crazy for a week).

7. To get the public keys for signing use: 

python imgtool.py getpub -k Test_certificate_header.pem -l c

And copy/paste them to keys.c in line 110 of MCUBoot (remember to include the length! ! and erase or comment the old keys).

8. To get the private keys for encryption use: 

python imgtool.py getpriv --minimal -k Test_certificate.pem

 And copy/paste them to keys.c in line 271 (remember to include the length! and erase or comment the old keys).

9. Now we must create the application image with this certificates, if you were in the default folder from the SDK modify the post build steps with:

${COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR}/tools/common/mcuboot/imgtool                 sign --header-size 0x80 --align 4 --slot-size 0x40000 --version 1.1.1 --pad-header --pad    --key ${COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR}/source/third_party/mcuboot/ scrips/ Test_certificate_header.pem  --encrypt ${COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR}/source/third_party/mcuboot/scrips/ Test_certificate.pem  ${ProjName}-noheader.bin ${ProjName}.bin

 

With this you should be able to make encryption work, program load is done the same way as without encryption but consider that it will take longer to boot because of deciphering.

Many thanks to Arthur R. and Lucas Holzen for the provided help, if there is any error or clarification needed, feedback will be really appreciated.

.