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.

MCU-PLUS-SDK-AM243X: app image authentication by Bootloader_socAuthImage()

Part Number: MCU-PLUS-SDK-AM243X
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi,

I'm back to the loaded appimage authentication.

I'm loading an *.hs_fs appimage to address 0x5DC000. The appimage is running OK.

I'd like to authenticate the appimage.

Step A : setting the ospi flash controller to DAC mode by:

  int i_dac_mode= OSPI_enableDacMode(gFlashHandle[CONFIG_FLASH0]);

  I see that i_dac_mode = SystemP_SUCCESS;

Step B:

 uint32_t ul_ospi_auth_adr = 0x060000000 + 0x5DC000;
 int i_auth = Bootloader_socAuthImage(ul_ospi_auth_adr);

 I see that i_auth != SystemP_SUCCESS;

i_auth = -1;

Is my address calculation correct ?

Is there any step I'm missing ?

Please advice on how to proceed ?

Thanks,

Eli

  • Hi Eli,

     uint32_t ul_ospi_auth_adr = 0x060000000 + 0x5DC000;
     int i_auth = Bootloader_socAuthImage(ul_ospi_auth_adr);

    May I know why you are doing this manually?

    The Bootloader_socAuthImage is already called as part of the Bootloader_parseMultiCoreAppImage which I assume you are using to parse the appimage. Were you skipping this Bootloader_socAuthImage call till now to successfully boot your signed appimage?

    Regards,

    Prashant

  • Hi Prashant,

    The reason I do it in the code is that I have to decide which app to load .

    I have two apps , one is the main app and the second is an ftp loader.

    When the ftp loader fails to load the main app or the main app is corrupted - the sbl must display an error and load the ftp loader - which is always in the flash.

    Please write a short example of how to use the Bootloader_socAuthImage(..) function.

    Thanks,

    Regards,

    Eli

  • Hi Prashant,

    I've checked - Yes I'm skipping the authentication test now.

    Please advice.

    Thanks,

    Regards,

    Eli

  • Hi Eli,

    The reason I do it in the code is that I have to decide which app to load .

    I have two apps , one is the main app and the second is an ftp loader.

    Still, once you have selected an image to boot, you would then call the Bootloader_parseMultiCoreAppImage for the selected image. This will include authentication of the image also unless manually commented out.

    In any case, you could use the following definition to authenticate an image

    int32_t App_authenticateAppImage(Bootloader_Handle bootHandle) {
        int32_t status = SystemP_FAILURE;
        
        uint32_t certLoadAddr = 0x60000000;
        uint32_t offset = 0xFFFFFFFF;
    
        Bootloader_Config* config = (Bootloader_Config*)bootHandle;
        offset = ((Bootloader_FlashArgs*)(config->args))->appImageOffset;
    
        certLoadAddr = certLoadAddr + offset;
        DebugP_log("Certificate address: 0x%x\r\n", certLoadAddr);
    
        status = Bootloader_socAuthImage(certLoadAddr);
    
        if(status == SystemP_SUCCESS) {
            DebugP_log("Authentication passed\r\n");
        } else {
            DebugP_log("Authentication failed\r\n");
        }
    
        return status;
    }

    Regards,

    Prashant

  • Hi Prashant,

    Thanks for the code.

    I'll test it and let you know.

    Regards,

    Eli

  • Hi Prashant,

    Seems to work !

    Thanks,

    Regards,

    Eli

  • Hi Prashant,

    Sorry but I was checking only on CLANG SBL demo project - then all works.

    When I test the code  on my GCC app it fails as before.

    I've added BootLoader check on sysconfig , 

      Here is my function - which is the same for both projects:

    int OspiFlashAppAuthenticate(uint32_t in_ul_app_body_addr)
    {
    int i_auth = -1;
    Bootloader_Params bootParams;
    Bootloader_Handle bootHandle;

    int i_dac_mode= OSPI_enableDacMode(gFlashHandle[CONFIG_FLASH0]);
    if(i_dac_mode == SystemP_SUCCESS)
    {
    OSAL_Serial_PRINT_F("flash in DAC mode \r\n");
    }
    else
    {
    OSAL_Serial_PRINT_F("FLASH FAILED DAC MODE \r\n");
    return i_dac_mode;
    }

    OSAL_Serial_PRINT_F("starting app authentication \r\n");

    extern Bootloader_Config gBootloaderConfig[];
    Bootloader_FlashArgs* flash_args = (Bootloader_FlashArgs *)gBootloaderConfig[CONFIG_BOOTLOADER_FLASH0].args;
    flash_args->appImageOffset = 0x80000;

    bootHandle = Bootloader_open(CONFIG_BOOTLOADER_FLASH0, &bootParams);
    i_auth = App_authenticateAppImage(bootHandle);

    if(i_auth == SystemP_SUCCESS)
    {
    OSAL_Serial_PRINT_F("app authenticated %lu \r\n", in_ul_app_body_addr);
    }
    else
    {
    OSAL_Serial_PRINT_F("APP AUTHENTICATION FAILED %d %lu \r\n", i_auth ,in_ul_app_body_addr);
    }

    return i_auth;
    }//OspiFlashAppAuthenticate

    and I'm using the function you've suggested

    int32_t App_authenticateAppImage(Bootloader_Handle bootHandle)
    {
    int32_t status = SystemP_FAILURE;

    uint32_t certLoadAddr = 0x60000000;
    uint32_t offset = 0xFFFFFFFF;

    Bootloader_Config* config = (Bootloader_Config*)bootHandle;
    offset = ((Bootloader_FlashArgs*)(config->args))->appImageOffset;

    certLoadAddr = certLoadAddr + offset;
    DebugP_log("Certificate address: 0x%x\r\n", certLoadAddr);

    status = Bootloader_socAuthImage(certLoadAddr);

    if(status == SystemP_SUCCESS) {
    DebugP_log("Authentication passed\r\n");
    } else {
    DebugP_log("Authentication failed\r\n");
    }

    return status;
    }

     

    It always gets into DAC mode but  the App_authenticateAppImage(bootHandle); fails 

    What else should I check ?

    Thanks,

    Regards,

    Eli

  • Hi Prashant,

    The reason I need to implement this authentication test in my big app is that after upgrading to a new app with FTP I have to test it before jumping to it . If it's not OK  - I stay with the old app for another FTP session.

    Please advice on how to proceed.

    Thanks,

    Regards,

    Eli

  • Hi Eli,

    The reason I need to implement this authentication test in my big app is that after upgrading to a new app with FTP I have to test it before jumping to it . If it's not OK  - I stay with the old app for another FTP session.

    I am trying to understand the flow here. So, you have something called a FTP loader which basically receives an application image over FTP and flashes to OSPI. Is that correct?

    If yes, I believe you want to make sure the application image is received and flashed correctly and is not corrupted. For this purpose, you are authenticating the image flashed in OSPI to check its integrity. Is that correct?

    Also, the FTP loader receives the application image and flashes it to 0x80000?

    Regards,

    Prashant

  • Hi Prashant,

    Yes you've got everything correct !

    So please help me to proceed why is it always fails in the "FTP_Loader app" but works correctly in the sbl app.

    Thanks,

    Regards,

    Eli

     

  • Hi Eli,

    The authentication is done by the SYSFW. So, you would need to enable and share the SYSFW logs to see why the authentication is failing.

    You may enable the SYSFW logs with the following steps:

    The Sysfw logs can be enabled as follows:

    • Change "#undef SYSFW_TRACE_ENABLE" to "#define SYSFW_TRACE_ENABLE" in source/drivers/sciclient/sciclient_default_boardcfg/am243x/sciclient_defaultBoardcfg.c.
    • Build the board configurations with: make -s -C tools/sysfw/boardcfg
    • Add another UART instance in the SBL's Sysconfig for MAIN_UART1.
    • Build the SBL.

    If the above steps are followed correctly, you should see SYSFW logs on MAIN_UART1.

    Regards,

    Prashant

  • Hi Prashant,

    I'll try that.

    Thanks,

    Regards,

    Eli

  • Hi Prashant,

    I see that  SYSFW_TRACE_ENABLE not supported by the mcu_plus_sdk_am243x_08_06_00_43.

    We use GCC as a compiler suit for all our applications and we've got an assistance from TI team, to make the mcu_plus_sdk_am243x_08_06_00_43  to use GCC and compile with our app.

    Our "FTP_Loader"  app is based on TI tcp_server example, using the GCC versions of the mcu_plus_sdk_am243x_08_06_00_43.

     

    When you say SYSFW - does it mean that cortex M4 is running ?  Does it mean that only SBL example will authenticate ?

    Suppose I'll make adaptations  to the ind_comms_sdk_am243x_09_01_00_03 for GCC  and use the "tcp_server" like example,

    would I'll be able to add the authentication utility to it ? 

    Is there an alternative way to authenticate the hs_fs file , like CRC ?

    Please advice.

    Thanks,

    Regards,

    Eli

  • Hi Eli,

    I see that  SYSFW_TRACE_ENABLE not supported by the mcu_plus_sdk_am243x_08_06_00_43.

    You are indeed right. It looks like the SYSFW_TRACE_ENABLE macro support was added in the later SDK versions.

    For the version you are using, you may replace the content of "source/drivers/sciclient/sciclient_default_boardcfg/am243x/sciclient_defaultBoardcfg.c" with the following and then follow the steps as I described previously to enable SYSFW logs.

    /*
     * K3 System Firmware Board Config Data
     * Auto generated from K3 Resource Partitioning tool
     *
     * Copyright (c) 2018-2023, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     */
    /**
     *  \file sciclient_defaultBoardcfg.c
     *
     *  \brief File containing the boardcfg default data structure to
     *      send TISCI_MSG_BOARD_CONFIG message.
     *
     */
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <drivers/sciclient.h>
    #include <drivers/sciclient/include/tisci/am64x_am243x/tisci_hosts.h>
    #include <drivers/sciclient/include/tisci/am64x_am243x/tisci_boardcfg_constraints.h>
    #include <drivers/sciclient/include/tisci/am64x_am243x/tisci_devices.h>
    
    #undef SYSFW_TRACE_ENABLE
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    const struct tisci_boardcfg gBoardConfigLow
    __attribute__(( aligned(128))) =
    {
        /* tisci_boardcfg_abi_rev */
        .rev = {
            .tisci_boardcfg_abi_maj = TISCI_BOARDCFG_ABI_MAJ_VALUE,
            .tisci_boardcfg_abi_min = TISCI_BOARDCFG_ABI_MIN_VALUE,
        },
    
        /* tisci_boardcfg_control */
        .control = {
            .subhdr = {
                .magic = TISCI_BOARDCFG_CONTROL_MAGIC_NUM,
                .size = (uint16_t) sizeof(struct tisci_boardcfg_control),
            },
    
            /* Enable/disable support for System Firmware main isolation.
             * If disabled, main isolation SCI message will be rejected with NAK.
             */
            .main_isolation_enable = 0x5A,
            /* Host-ID allowed to send SCI-message for main isolation.
             * If mismatch, SCI message will be rejected with NAK.
             */
            .main_isolation_hostid = TISCI_HOST_ID_MAIN_0_R5_0,
        },
    
        /* tisci_boardcfg_sec_proxy */
        .secproxy = {
            .subhdr = {
                .magic = TISCI_BOARDCFG_SECPROXY_MAGIC_NUM,
                .size = (uint16_t) sizeof(struct tisci_boardcfg_secproxy),
            },
            /* Memory allocation for messages scaling factor. In current design,
             * only value of “1” is supported. For future design, a value of “2”
             * would double all memory allocations and credits, “3” would triple,
             * and so on.
             */
            .scaling_factor = 0x1,
            /* Memory allocation for messages profile number. In current design,
             * only a value of “1” is supported. “0” is always invalid due to
             * fault tolerance.
             */
            .scaling_profile = 0x1,
            /* Do not configure main nav secure proxy. This removes all MSMC memory
             * demands from System Firmware but limits MPU channels to one set of
             * secure and one set of insecure. In current design, supports only “0”.
             */
            .disable_main_nav_secure_proxy = 0,
        },
    
        /* tisci_boardcfg_msmc */
        .msmc = {
            .subhdr = {
                .magic = TISCI_BOARDCFG_MSMC_MAGIC_NUM,
                .size = (uint16_t) sizeof(struct tisci_boardcfg_msmc),
            },
            /* If the whole memory is X MB the value you write to this field is n.
             * The value of n sets the cache size as n * X/32. The value of n should
             * be given in steps of 4, which makes the size of cache to be
             * configured in steps on X/8 MB.
             */
            .msmc_cache_size = 0x20,
        },
    
        /* tisci_boardcfg_dbg_cfg */
        .debug_cfg = {
            .subhdr = {
                .magic = TISCI_BOARDCFG_DBG_CFG_MAGIC_NUM,
                .size = (uint16_t) sizeof(struct tisci_boardcfg_dbg_cfg),
            },
            /* This enables the trace for DMSC logging. Should be used only for
             * debug. Profiling should not be done with this enabled.
             */
            #ifdef SYSFW_TRACE_ENABLE
            .trace_dst_enables = (TISCI_BOARDCFG_TRACE_DST_UART0 |
                                  TISCI_BOARDCFG_TRACE_DST_ITM |
                                  TISCI_BOARDCFG_TRACE_DST_MEM),
            .trace_src_enables = (TISCI_BOARDCFG_TRACE_SRC_PM |
                                  TISCI_BOARDCFG_TRACE_SRC_RM |
                                  TISCI_BOARDCFG_TRACE_SRC_SEC |
                                  TISCI_BOARDCFG_TRACE_SRC_BASE |
                                  TISCI_BOARDCFG_TRACE_SRC_USER |
                                  TISCI_BOARDCFG_TRACE_SRC_SUPR)
            #else
            .trace_dst_enables = 0,
            .trace_src_enables = 0
            #endif
        },
    };
    

    When you say SYSFW - does it mean that cortex M4 is running ?  Does it mean that only SBL example will authenticate ?

    The SYSFW is always running on the DMSC core (a Cortex-M core in secure domain). The authentication of a signed image can be done at any stage of the boot flow.

    would I'll be able to add the authentication utility to it ? 

    Yes.

    Is there an alternative way to authenticate the hs_fs file , like CRC ?

    Last I remember, you already have a CRC based implementation to do integrity check of an image?

    Regards,

    Prashant

  • Hi Prashant,

    I'll replace the file in mcu_plus_sdk_am243x_08_06_00_43 with the one one you've sent and activate the trace.

    Is there already a calculated CRC somewhere in the *.hs_fs  file ?  (Just in case)

    Thanks,

    Regards,

    Eli 

  • Hi Eli,

    Is there already a calculated CRC somewhere in the *.hs_fs  file ?  (Just in case)

    No. The *.hs_fs is basically a concatenation of X.509 certificate (X bytes) + Raw Appimage (Y bytes). The certificate contains the SHA512 hash of Raw Appimage.

    You could theoretically extract the SHA512 hash from the certificate and check against the run time calculated SHA512 hash of the Raw Appimage. But, all this is not so straightforward to implement than the basic CRC based integrity check mechanism.

    If your only purpose is the integrity check of the received image, you could do so with the following steps leveraging your already implemented CRC mechanism.

    • Think of the *.hs_fs file as a binary blob (Y).
    • Calculate the CRC on the host machine and prepend (X) it to the *.hs_fs file (Y) giving you (X+Y).
    • Receive the (X+Y) and flash Y to the OSPI.
    • Calculate the CRC of the flashed image Y and compare it with the received CRC X.

    Regards,

    Prashant

  • Hi Prashant,

    Your CRC calculation suggestion is very good, moreover - I'm familiar with that approach.

    I'll try the authentication utility first and keep the CRC approach as a fall back.

    Thanks,

    Regards,

    Eli