Verdin AM62 check secure boot fuse writing

Hi,

I am using the “0071 Verdin AM62 Solo 512MB” V1.1B (also have V1.1C modules) and am trying to enable the secure boot feature, i contacted TI and got the necessary documentation and toolings but according to the documentation from TI the AM62 chip outputs its SoC ID with secure boot info over a certain UART port when booting in ‘UART mode’. I cannot find any documentation regarding this boot mode with the verdin module or the UART port which should output this data.
According to the TI manual i was able to flash the fuses but i want to check this with the modules output, however i cannot find the matching boot method/uart port or whatnot.
Can anyone help me with this.

Kind regards,
Richard

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello Richard,

Thank you for reaching out with your question about enabling secure boot on the Verdin AM62 module. I understand you’re looking to verify the secure boot feature by accessing the SoC ID and secure boot information via UART.

For the Verdin AM62 module, the UART_A port is typically used for serial communication. You can connect this port to your development PC to receive output from the module. To enter the UART mode required for secure boot verification, you may need to adjust the boot settings on the module. This often involves setting specific boot pins or using a bootloader command to switch to UART mode.

Here are some steps you can follow:

  1. Identify the UART Port: Use the UART_A port on the Verdin AM62 module for serial communication. Ensure it is properly connected to your development PC.

  2. Configure Boot Settings: Check the TI documentation for specific instructions on entering UART mode. This may involve setting certain boot pins or using commands in the bootloader to enable UART mode.

  3. Monitor UART Output: Use a terminal program such as minicom or screen on Linux, or PuTTY on Windows, to monitor the UART output. This will allow you to see the SoC ID and secure boot information as the module boots.

If you need further details, I recommend reviewing the technical documentation provided by TI and Toradex for the Verdin AM62 module. This will ensure you have the correct setup for secure boot verification.

I hope this helps you proceed with your secure boot setup. If you have any more questions, feel free to ask.

Best regards,
Toradex AI Assistant.

Please, also check if these links can help you solve your problem:

Bluetooth disconnection from external device crashes bluetooth module/driver on a Verdin AM62 board.

Greetings @RiBe_Act,

We’re not familar with whatever this “UART mode” is that you are describing. However, if your goal is to check whether the module was properly closed via secure boot, then there is another way.

When booting your AM62 you should see some boot logs like so on the serial debug:

U-Boot 2024.04-ti-gffbbc1dd68f4 (Jan 01 1970 - 00:00:00 +0000)

SoC:   AM62X SR1.0 HS-SE
DRAM:  2 GiB
Core:  145 devices, 31 uclasses, devicetree: separate
MMC:   mmc@fa10000: 0, mmc@fa00000: 1
Loading Environment from MMC... OK
In:    serial@2800000
Out:   serial@2800000
Err:   serial@2800000
Model: Toradex 0076 Verdin AM62 Quad 2GB WB IT V1.2A
Serial#: 15479391
Carrier: Toradex Verdin Development Board V1.1C, Serial# 10996014

Pay attention specifically to the SoC: line. If the line has HS-SE like in the example boot log above, then this indicates the device is fused and closed. If it instead has HS-FS, then the module has not been closed yet.

Let me know if this helps or not with what you are trying to do.

Best Regards,
Jeremias

Hi Jeremias,

Thank you for the response.
I got the UART mode data from the boot options from the TI AM62x reference manual (https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/spruiv7b-noRegisters.pdf, link to reference manual) and the OTP writer manual refers to the same thing, so from there i went searching.

I am having some trouble following all of the documentation regarding where the tiboot.bin firmware needs to come from, does Yocto build this for me since the “/deploy/images/verdin-am62/” folder contains several tiboot .bin files?

After image creation i now have about 6 different tiboot_x.bin files which match the naming of the TI OTP writer manual for the writing of the fuses, do i need to use 1 one these files for the fuse writing or do i need to generate these myself by following the TI OTP write manual?

After image creation i now have about 6 different tiboot_x.bin files which match the naming of the TI OTP writer manual for the writing of the fuses, do i need to use 1 one these files for the fuse writing or do i need to generate these myself by following the TI OTP write manual?

There’s probably some misunderstanding here. Let me try to clear this up. I assume you’re talking about the tiboot3.binthat you build with the OTP keywriter tool. That then gets loaded to the device. This specific tiboot3.bin gets created by the OTP keywriter tool.

What have you done so far?

Have you already tried to install and run the keywriter tool?

Best Regards,
Jeremias

Hi Jeramias,

ok, so i have to build that using the OTP writer tool and the files being build by Yocto are not to be used for that function, thanks for clarifying.

I already tried to run the OTP writer tool by following the TI manual and got a successful feedback message from the DFU UTIL tooling, see example from manual below:

But in my work process i did this step before i wrote my secure boot image to flash so i expected the module to be bricked before i even got the change to write my new image (i was too enthusiastic about that part), also for this step i used the dummy keys (as per TI manual step in the manual and not the keys which i generated for the final secure boot build as per TI documentation.


However the module still presents as a HS-FS device, could this somehow be due to that the default UBoot version does not support this and this becomes available after the secure boot image updates the UBoot version?

Afterwards i was able to flash my secure boot build (using toradex easy installer with a flash drive), which was build using the final set of keys and not the TI dummy keys, and this boots correctly, so somewhere i messed up the process and the module is not closed yet.

In my next test i will follow the following procedure, if you could check and correct me if i am making a mistake here/missing a step i would appreciate.

  1. Generate tiboot3.bin file with OTP keywriter tooling using final keys.
  2. Rebuild complete Yocto project with toradex-signed bbclass (ECoT enabled) and final keys.
  3. Flash this image to the verdin AM62 using toradex easy installer and usb flash drive containing secure boot image.
  4. Reboot module in recovery mode (necessary for tiboot.bin firmware update).
  5. Run USB DFU UTIL to upload tiboot3.bin file to module.
  6. Reboot module.

Then my module should be correctly flashed and closed, correct?

One other question i had was, if i want to use the backup key (BMPK) stored in the module in the case where my primary key (SMPK) is compromised do i need to add the BMPK to the Yocto build but rename this as the ‘custMpk’ or do i need to tell Yocto in another way to use the backup key for the image?
I think this is only relevant for the UBoot build am i right, in the case where a compromise has happened i can replace the generated FIT and OSTREE image keys with new ones and include those in the build as long as the UBoot keys are the same as in the modules fuses.

What might help is the following document:
Verdin_AM62_V1.2_Fusing_Procedure.pdf (1.7 MB)

This is an internal document of ours, that goes into detail regarding the fusing process on the Verdin AM62. You can use it as a reference against your own process.

One other question i had was, if i want to use the backup key (BMPK) stored in the module in the case where my primary key (SMPK) is compromised do i need to add the BMPK to the Yocto build but rename this as the ‘custMpk’ or do i need to tell Yocto in another way to use the backup key for the image?

Regarding this, so I’ve not yet had to use the backup-key for the AM62 secure boot process. Searching on the TI forums leads me to this: PROCESSOR-SDK-AM62X: Secure boot: BMPK use case and OTA applicability - Processors forum - Processors - TI E2E support forums

The chain of links eventually then leads to this: [FAQ] AM6442/AM243: How to use the TISCI APIs (READ_KEYCNT_KEYREV & WRITE_KEYREV) to activate the backup key set - Processors forum - Processors - TI E2E support forums

I know this FAQ post refers to other SoCs and not the AM62 specifically, but other threads about the AM62 referred to this as well. So I assume it’s applicable.

I think this is only relevant for the UBoot build am i right, in the case where a compromise has happened i can replace the generated FIT and OSTREE image keys with new ones and include those in the build as long as the UBoot keys are the same as in the modules fuses.

In theory yes. The initial part of the chain of trust is between the hardware (fuses) and the bootloader (U-Boot).

Best Regards,
Jeremias

Hi Jeremias,

Thank you for the extended documentation.
I noticed this manual is for module version 1.2 and does not work for my modules (V1.1B and V1.1C) is it still possible to enable secure boot on these module versions?

I noticed this manual is for module version 1.2 and does not work for my modules (V1.1B and V1.1C) is it still possible to enable secure boot on these module versions?

It should still be possible. The main difference between the 1.1 and 1.2 is that the 1.2 has a LDO that allows easier toggling of the VPP signal required for the fusing to be successful. That’s what the patch for the OTP keywriter is for in the documentation.

SInce the 1.1 does not have this LDO the patch won’t do anything for the VPP signal. This means you’ll need some other way to set this signal during the fusing process. Other than this detail, most of the instructions should still apply for the 1.1. The important part is this VPP signal though.

Best Regards,
Jeremias

Ok, Thanks for the confirmation.
After some tests i see that when i try to write the fuses by loading the OTP writer tooling i am not getting any feedback from the serial console which according to the documentation i should get.

Even if i apply the VPP incorrect i should get something from the console but i get no output, any idea what could be wrong?

Even if i apply the VPP incorrect i should get something from the console but i get no output, any idea what could be wrong?

That is odd, you should indeed have output of some kind on the serial console. You are sure the device has been booted in recovery mode?

Is there any logs/output from running dfu-util?

Also how exactly are you applying VPP? I’ve heard the process of when to apply VPP is quite specific. There’s actually quite a thread on our GIthub from another customer who had issues trying to apply VPP correctly: Fail to burn fuses and initiate the secure boot (Mallow board V1.1A, AM62) · Issue #85 · toradex/meta-toradex-security · GitHub

Best Regards,
Jeremias

For reference i am using the Mallow V1.1A development board for these tests.
According to the schematics there is no outward pin/pad/header connected to the SODIMM VPP pin so i soldered a wire to the matching SODIMM VPP pins capacitor (C98, high side) to be able to supply that pin.

I wasn’t aware the VPP pin needs to be triggered by software so i manually added 1.8V to that line after the system was done booting.

My dfu-util output shows the following:

And after i try to upload the tiboot3.bin file i get the following output:

During this time there is no output on the serial console (which i set to baudrate 115200 bps, same as default console settings).

Let’s try a sanity test. Let’s see if you are creating the OTP Keywriter binary correct and it’s being loaded. Try to modify the main keywriter application code, to print some messages to the serial console. Then try to load this and see if your messages are being printed to the serial console.

If your messages are not being printed and seen, then this would suggest something is wrong with the creation of the binary or the loading of it.

Best Regards,
Jeremias

I changed the main.c file of the OTP keywriter build to start with a serial console message (see below) but it does not put anything on the console during dfu-util upload.
main.c code:
/*
* Copyright (C) 2023 Texas Instruments Incorporated
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdlib.h>
#include "ti_drivers_config.h"
#include "ti_drivers_open_close.h"
#include "main.h"

/* call this API to stop the booting process and spin, do that you can connect
 * debugger, load symbols and then make the 'loop' variable as 0 to continue execution
 * with debugger connected.
 */
void loop_forever()
{
    volatile uint32_t loop = 1;
    while(loop)
        ;
}

int main()
{
    DebugP_log("\r\n");
    DebugP_log("Test output Richard\r\n");

    System_init();
    Drivers_open();

    DebugP_log("\r\n");
    DebugP_log("Starting Keywriting\r\n");

    keywriter_setVpp();
    DebugP_log("Enabled VPP\r\n");

	keywriter_processKeyConfig();
    DebugP_log("Done Keywriting\r\n");

    keywriter_clearVpp();
    DebugP_log("Disabled VPP\r\n");

    Drivers_close();
    System_deinit();

	loop_forever();

    return 0;
}

After cleaning and compilation i do get a warning about the “keywriter_clearVpp” function not being declared but the compilation finished sucessfully:

compile output:
sudo make -sj PROFILE=debug
Generating SysConfig files …
Running script…
Validating…
Generating Code (example.syscfg)…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_dpl_config.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_dpl_config.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_drivers_config.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_drivers_config.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_drivers_open_close.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_drivers_open_close.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_pinmux_config.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_power_clock_config.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_board_config.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_board_config.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_board_open_close.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_board_open_close.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_config.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_config.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_open_close.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_open_close.h…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_soc.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_lwipif.c…
Writing /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/generated/ti_enet_lwipif.h…
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: …/main.c
…/main.c:66:5: warning: call to undeclared function ‘keywriter_clearVpp’; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
keywriter_clearVpp();
^
1 warning generated.
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: …/keywriter_utils.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: …/board.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_drivers_config.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_drivers_open_close.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_board_config.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_board_open_close.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_dpl_config.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_pinmux_config.c
Compiling: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out: generated/ti_power_clock_config.c
.
Linking: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out …
Linking: am62x:r5fss0-0:nortos:ti-arm-clang sbl_keywriter.debug.out Done !!!
.
Boot image: am62x:r5fss0-0:nortos:ti-arm-clang /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/sbl_keywriter.debug.tiimage …
Boot image: am62x:r5fss0-0:nortos:ti-arm-clang /home/ti/source/security/sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang/sbl_keywriter.debug.tiimage Done !!!

I re ran dfu util -l before uploading and got the following output:

After that i tried the upload command which gives me the following output:

Does there need to be some specific firmware installed before this step can be done or does the recovery mode take care of all that?

Does there need to be some specific firmware installed before this step can be done or does the recovery mode take care of all that?

It shouldn’t the device just needs to be powered on in recovery-mode, then dfu-util should be able to work. We use dfu-util when loading Toradex Easy Installer back onto the module, so if you’ve done this before then it should work for this.

As for your test 2 comments.

First of all, I think your log messages need to come after the System_init(); and Drivers_open(); lines or it might not work correctly.

Secondly, what version of the mcu_plus_sdk_am62x* did you download from TI? One of my colleagues who fused the AM62 before, commented that some versions of this did not seem to work and produced no output on the serial console. Which sounds similar to what is happening to you here.

For reference my colleague tried mcu_plus_sdk_am62x_10_00_00_14, this is the version the TI documentation references. However, when my colleague tried to use this they got no output on serial console and it seemed like the fusing did not work.

They then tried mcu_plus_sdk_am62x_09_01_00_43 and eventually got this version to work. Though this version is restricted access so you need to request access to it from TI themselves. Not sure if you’ve already done this.

In any case, could you share what version you are using here?

Best Regards,
Jeremias

I am currently using that same version “mcu_plus_sdk_am62x_10_00_00_14” so that could be an issue if it did not work for your colleague.
I do have access to the TI secure resources so i’ll try a fresh install of the environment with another version.

I’ll get back to you once i have the environment setup again and let you know the results.

Regards,
Richard

Please let us know whether the restricted version ends up working for you or not. Also let us know what specific version you ended up using whether it worked or not. It would be a good data point for us to know what versions work for this process.

Best Regards,
Jeremias

Hi Jeremias,

I was able to flash the fuse keys using a different version (this one did present me with the expected serial console output).
Version info:

  • mcu_plus_sdk_am62x_09_02_01_06
  • CCS12.7.0.00007
  • sysconfig-1.20.0_3587

After some incorrect VPP actions i got the following output:
Incorrect VPP usage
Starting Keywriting

Retry
Starting Keywriting

Retry
Starting Keywriting

Retry
Starting Keywriting

Enabled VPP

keys Certificate found: 0x43c15e00

Keywriter Debug Response:0x2000800

Error occured…

Correct VPP usage (with external power supply for 1.8V) enabling
Starting Keywriting

Enabled VPP

keys Certificate found: 0x43c15e00

Keywriter Debug Response:0x0

Success Programming Keys

However now after a reboot my module doesn’t do anything anymore (no serial console output whatsoever) so i assume i made a mistake in my process using the keys somewhere or my yocto build was somehow incorrect.
Am i correct to assume in the case where incorrect keys are used in the build the module will not present any output whatsoever (since uBoot is incorrectly signed) or should it still present some output?

Kind regards,
Richard

I was able to flash the fuse keys using a different version (this one did present me with the expected serial console output).

That’s good to hear, glad you were able to successfully perform the fusing operation. It’s also a nice data-point for us to know that the version of SDK here really does matter it seems.

Am i correct to assume in the case where incorrect keys are used in the build the module will not present any output whatsoever (since uBoot is incorrectly signed) or should it still present some output?

This is what I would assume as well. Admittedly, no one here has tried to boot an improperly signed image on a fused AM62, since there’s no good way to recover from this. Though I imagine what you are seeing would be an expected result.

At least in my personal experience, something very similar happens on the i.MX SoCs when you try to boot an improperly signed image. No output and the device seems like it’s not “doing anything”. So I imagine the AM62, despite being TI and not NXP, would behave similarly.

Best Regards,
Jeremias

Hi Jeremias,

During these tests i found some irregularities in the fusing documentation regarding the TI AM62 module, perhaps you can help me clarify and find the problem.
On the META page for the TI module is states that the following keys need to be used:

However in the manual you provided " Verdin_AM62_V1.2_Fusing_Procedure.pdf (1.7 MB)"

It states i also need a create a set of “AES keys”

Another thing i noticed in the procedure was that after i flashed my secure signed image (via easy installer) according to the documentation i should get an error saying it can’t boot but this was not the case for me and my image booted correctly.

Which documentation do i need to follow for the correct procedure and or is the fact i did not get this output an indicator of what i did wrong in the process?

And can i check in the yocto build logs if the images are being signed, if so at which log would i need to look?