This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiler get stuck in side nrf_crypto_hash_update() function

Hi i am using nordic nrf52840 chip. and SDK17.1 i am using.

in that under secure bootloader code i am trying to use the nrf_crypto_hash_update() function to calculate the hash of my application code.

But when compiler reached to this function then it got stuck somewhere. 

Any idea y this happened. is i need to enable something in the code for hash calculation...?

Regards

Rohit Saini

Parents Reply Children
  • Are you calling it in a critical region? Can you post the code here?

    Where do you place this function in the secure bootloader, and is this the same place where you do it in the open bootloader?

  • IN open bootloader its in main only but in little different way.

    int main(void)
    {
    uint32_t ret_val;

    bsp_board_init(BSP_INIT_LEDS);


    {
    for (int i = 0; i < 6; i++)
    {
    //bsp_board_led_invert(i);
    nrf_gpio_pin_toggle(LED_3);
    nrf_delay_ms(500);
    }
    }

    // Must happen before flash protection is applied, since it edits a protected page.
    nrf_bootloader_mbr_addrs_populate();

    // Protect MBR and bootloader and application code from being overwritten.
    ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(AP_START_ADDRESS, 0x4000);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(BL2_START_ADDRESS, (NRF_MBR_PARAMS_PAGE_ADDRESS - 0xF8000)); //ROHIT
    APP_ERROR_CHECK(ret_val);

    NRF_LOG_INFO("Open USB bootloader started");
    //NRF_LOG_FLUSH();

    if (IsSignatureVerified(BOOT2) == true)
    {
    #if 1
    //Jump_To_App();
    Jump_To_Bootloader2();
    #endif
    }

  • R_S said:
    IN open bootloader its in main only

    Does that mean the secure bootloader is performing the hash computation from other places as well?

    Also, please do not copy-and-paste large code snippets into your post. It makes it hard to read. Instead you can use the formatting tools to insert the code, or upload the c file as an attachment.

  • I am calling this function in the starting only. and before that its not called.

    in later stage for secure boot code its called under "nrf_crypto_hash_calculate()" function only. 

    But that should not effect right...?

  • I did a simple test where I validated the signature of the main application image, but I did not manage to reproduce the problem you saw.

    Here is my test function:

    #include "nrf_crypto.h"
    #include "nrf_crypto_shared.h"
    
    #define APP_START 0x27000
    #define APP_SIZE  99816
    
    /* Application signature copied from pkg_info.txt in \examples\dfu\secure_bootloader\key */
    #define APP_SIGN                                                                                   \
        {                                                                                              \
            0x17, 0x1a, 0x3a, 0x99, 0x45, 0xdd, 0x7b, 0x24, 0xc9, 0x7b, 0x0e, 0x0a, 0xf0, 0x19, 0x3d,  \
                0x97, 0x28, 0xf7, 0xed, 0x72, 0x28, 0xd1, 0x25, 0xd6, 0x84, 0x86, 0xf1, 0x04, 0xd6,    \
                0x22, 0x12, 0xff, 0xf7, 0x39, 0xf1, 0x6e, 0xa0, 0x5a, 0xc0, 0xef, 0xc8, 0xa0, 0x30,    \
                0xb9, 0x50, 0xa9, 0x83, 0x6d, 0x34, 0x0d, 0x91, 0x81, 0xd7, 0x49, 0xfc, 0x27, 0x43,    \
                0x7e, 0x0b, 0x7c, 0xbb, 0x9c, 0x29, 0xe3                                               \
        }
    
    static nrf_crypto_hash_sha256_digest_t              m_sig_hash;
    /** @brief Structure to hold a signature
     */
    static nrf_crypto_ecdsa_secp256r1_signature_t       m_signature;
    
    static nrf_crypto_ecc_public_key_t                  m_public_key;
    
    __ALIGN(4) extern const uint8_t pk[64];
    
    void signature_validate_test(void)
    {
        ret_code_t err_code;
        uint8_t    pk_copy[sizeof(pk)];
        size_t     hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
        size_t     data_len = APP_SIZE;
        uint8_t    app_signature[] = APP_SIGN;
    
        nrf_crypto_hash_context_t         hash_context   = {0};
        nrf_crypto_ecdsa_verify_context_t verify_context = {0};
       
        NRF_LOG_INFO("Starting signature validation test");
    
        err_code = nrf_crypto_init();
        ASSERT(err_code == NRF_SUCCESS);
        UNUSED_PARAMETER(err_code);
    
        // Convert public key to big-endian format for use in nrf_crypto.
        nrf_crypto_internal_double_swap_endian(pk_copy, pk, sizeof(pk) / 2);
    
        err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
                                                      &m_public_key,
                                                      pk_copy,
                                                      sizeof(pk));
        ASSERT(err_code == NRF_SUCCESS);
        UNUSED_PARAMETER(err_code);
    
        NRF_LOG_INFO("Calculating hash (len: %d)", data_len);
        err_code = nrf_crypto_hash_calculate(&hash_context,
                                             &g_nrf_crypto_hash_sha256_info,
                                             (uint8_t *)APP_START,
                                             data_len,
                                             m_sig_hash,
                                             &hash_len);
    
        NRF_LOG_INFO("nrf_crypto_hash_calculate() return value: 0x%x", err_code);
    
        memcpy(m_signature, app_signature, NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE);
    
        // Calculate the signature.
        NRF_LOG_INFO("Verify signature");
    
        // The signature is in little-endian format. Change it to big-endian format for nrf_crypto use.
        nrf_crypto_internal_double_swap_endian_in_place(m_signature, sizeof(m_signature) / 2);
    
        err_code = nrf_crypto_ecdsa_verify(&verify_context,
                                           &m_public_key,
                                           m_sig_hash,
                                           hash_len,
                                           m_signature,
                                           sizeof(m_signature));
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code);
            NRF_LOG_DEBUG("Signature:");
            NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature));
            NRF_LOG_DEBUG("Hash:");
            NRF_LOG_HEXDUMP_DEBUG(m_sig_hash, hash_len);
            NRF_LOG_DEBUG("Public Key:");
            NRF_LOG_HEXDUMP_DEBUG(pk, sizeof(pk));
            NRF_LOG_FLUSH();
            return;
        }
    
        NRF_LOG_INFO("Image verified");
    
    }
    
    /**@brief Function for application main entry. */
    int main(void)
    {
        uint32_t ret_val;
    
        // Must happen before flash protection is applied, since it edits a protected page.
        nrf_bootloader_mbr_addrs_populate();
    
        // Protect MBR and bootloader code from being overwritten.
        ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE);
        APP_ERROR_CHECK(ret_val);
        ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE);
        APP_ERROR_CHECK(ret_val);
    
        (void) NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get);
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("Inside main");
        signature_validate_test();
        ...

    and full project:

    nRF5_SDK17.1.0_dfu.zip

    Which variant of the cc310 are you including in your project? And have you verified that the Cryptocell interrupt actually gets enabled at the line shown in the screenshot below?

Related