Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to generate firmware's hash.

Hello Everyone, 

I am a beginner

I am working on a project which requires authentication of the firmware , for this purpose i want to generate the hash of the firmware .

So while searching i cam across this function--> nrf_crypto_hash_calculate()  which uses source address and length, can anyone help me were i can find my firmware start and size of it,

nrf_crypto_hash_calculate(&hash_context,
&g_nrf_crypto_hash_sha256_info,
(uint8_t*)src_addr,
data_len,
m_fw_hash,
&hash_len);


  • Hi,

    You can use the CODE_START and CODE_SIZE symbols defined in components\libraries\util\app_util.h for this purpose.

    Best regards,
    Jørgen

  • Hii, so i was trying to run the function like this     
                nrf_crypto_hash_calculate(&hash_context, &g_nrf_crypto_hash_sha256_info,  (uint8_t*)CODE_START,
                              CODE_SIZE, firmware_hash, &hash_len);

     but its going into SaSi_HalWaitInterrupt after nrf_crypto_hash_update and not coming back , i think the issue is CODE_START is uint32_t pointer , and also CODE_SIZE will change for
    uint8_t expected by nrf_crypto_hash_calculate() or is there anything i am missing.

    what do you suggest.

    Thanks and Regard,
    Andhakanoon
                                                                                    

  • Hi,

    It looks similar to how we do it in our DFU bootloader for verification of hash of received image, but you may try to store the values of the symbols into uint32_t variables before passing to the function:

    // Function to check the hash received in the init command against the received firmware.
    // little_endian specifies the endianness of @p p_hash.
    static bool nrf_dfu_validation_hash_ok(uint8_t const * p_hash, uint32_t src_addr, uint32_t data_len, bool little_endian)
    {
        ret_code_t err_code;
        bool       result   = true;
        uint8_t    hash_be[NRF_CRYPTO_HASH_SIZE_SHA256];
        size_t     hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
    
        nrf_crypto_hash_context_t hash_context = {0};
    
        crypto_init();
    
        if (little_endian)
        {
            // Convert to hash to big-endian format for use in nrf_crypto.
            nrf_crypto_internal_swap_endian(hash_be,
                                            p_hash,
                                            NRF_CRYPTO_HASH_SIZE_SHA256);
            p_hash = hash_be;
        }
    
        NRF_LOG_DEBUG("Hash verification. start address: 0x%x, size: 0x%x",
                      src_addr,
                      data_len);
    
        err_code = nrf_crypto_hash_calculate(&hash_context,
                                             &g_nrf_crypto_hash_sha256_info,
                                             (uint8_t*)src_addr,
                                             data_len,
                                             m_fw_hash,
                                             &hash_len);
    
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code);
            result = false;
        }
        else if (memcmp(m_fw_hash, p_hash, NRF_CRYPTO_HASH_SIZE_SHA256) != 0)
        {
            NRF_LOG_WARNING("Hash verification failed.");
            NRF_LOG_DEBUG("Expected FW hash:")
            NRF_LOG_HEXDUMP_DEBUG(p_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
            NRF_LOG_DEBUG("Actual FW hash:")
            NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
            NRF_LOG_FLUSH();
    
            result = false;
        }
    
        return result;
    }

    Have you initialized the crypto library correctly before calling the hash-function?

    Best regards.
    Jørgen

Related