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);


  •  size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
    
            nrf_crypto_hash_context_t hash_context = {0};
    
           // uint32_t src_addr = CODE_START, data_len = CODE_SIZE;
    
            crypto_init();
            
            ret_code_t err_code;
            err_code = nrf_crypto_hash_calculate(&hash_context,
                             &g_nrf_crypto_hash_sha256_info,
                             (uint8_t*)challenge_no,
                             32,
                             temp1,
                             &hash_len);
           
            sha256_Raw(&challenge_no,32,temp2);
    

    I tried to check if nrf_crypto_hash work or not for that i passed random no to it and also to sha256_Raw .     After running both temp1 and temp2 value is equal , so don't think there's a issue in the initialization or working of it                                                                                          
                                                                                                                                                                    Thanks and Regard,
    Andhakanoon                                                                                                                                                                            

  • Are you checking all error return codes from the functions?

    andhakanoon said:
    but its going into SaSi_HalWaitInterrupt after nrf_crypto_hash_update and not coming back

    Does it enter SaSi_HalWaitInterrupt inside or after nrf_crypto_hash_update? This function is inside the CC310 library, so I'm not sure where that is called from. I cannot see any calls to it in our SDK (v17.0.2).

  • Does it enter SaSi_HalWaitInterrupt inside or after nrf_crypto_hash_update?

     its enters Sasi_HalWaitInterrupt insed nrf_crypto_hash_update , also nrf_crypto_hash_calculate works properly if data_len is less , but when i try to give large length it goes into Sasi_HalWaitInterrupt , Also i tried another hash_calculate function from another library and it is working , So is there anyway to crosscheck the hash generated .
    .

    thank you for helping and replying to my queries , very much appreciated                                                                                                                                                                           

  • Looks like the CC310 does not support hashing directly from Flash, so you need to copy pieces of the FW to RAM before hashing.

    I was able to correctly calculate the SHA256 Hash using the following code in the nrf_crypto_hash example:

    // Initialize the hash context
    err_code = nrf_crypto_hash_init(&hash_context, &g_nrf_crypto_hash_sha256_info);
    APP_ERROR_CHECK(err_code);
    
    // Run the update function (this can be run multiples of time if the data is accessible
    // in smaller chunks, e.g. when received on-air.
    uint32_t fw_start_addr = CODE_START;
    uint32_t fw_size = CODE_SIZE;
    uint32_t fw_piece_size = 0x1000;
    static uint8_t fw_piece[0x1000];
    NRF_LOG_INFO("FW Start address: %x", fw_start_addr);
    NRF_LOG_INFO("FW size: %x", fw_size);
    NRF_LOG_INFO("Hash piece size: %x", fw_piece_size);
    for(int fw_hash_start_addr = fw_start_addr; fw_hash_start_addr < (fw_start_addr + fw_size); fw_hash_start_addr+=fw_piece_size)
    {
        if((fw_hash_start_addr + fw_piece_size) > (fw_start_addr + fw_size))
        {
            fw_piece_size = fw_size - fw_hash_start_addr;
        }
        memcpy(fw_piece, (uint8_t *)(fw_start_addr+fw_hash_start_addr), fw_piece_size);
        err_code = nrf_crypto_hash_update(&hash_context, fw_piece, fw_piece_size);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("Current last hashed address: %x", fw_hash_start_addr + fw_piece_size);
    }
    // Run the finalize when all data has been fed to the update function.
    // this gives you the result
    err_code = nrf_crypto_hash_finalize(&hash_context, m_digest, &digest_len);
    APP_ERROR_CHECK(err_code);

    Note that I have not tested this with a lot of FW sizes or start addresses, so there may be some edge-cases that are not handled.

  • Thank you for your help and co-ordination and also sharing your code with few modification that worked for me.

    void fw_hash_calculate(uint8_t * m_digest){
    
        size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
                nrf_crypto_hash_context_t hash_context = {0};
        // Initialize the hash context
        ret_code_t err_code = nrf_crypto_hash_init(&hash_context, &g_nrf_crypto_hash_sha256_info);
        APP_ERROR_CHECK(err_code);
    
        // Run the update function (this can be run multiples of time if the data is accessible
        // in smaller chunks, e.g. when received on-air.
        uint32_t fw_start_addr = CODE_START;
        uint32_t fw_size = CODE_SIZE;
        uint32_t fw_piece_size = 32;
        uint32_t end = CODE_END;
        static uint8_t fw_piece[32];
        printf("FW Start address: %x\n", fw_start_addr);
        printf("FW size: %x\n", fw_size);
        printf("FW end: %x\n", end);
        printf("Hash piece size: %x\n", fw_piece_size);
        for(int fw_hash_start_addr = fw_start_addr; fw_hash_start_addr < (fw_start_addr + fw_size); fw_hash_start_addr+=fw_piece_size)
        {
            if((fw_hash_start_addr + fw_piece_size) > (fw_start_addr + fw_size))
            {
                fw_piece_size = fw_start_addr + fw_size - fw_hash_start_addr;
            }
            memcpy(fw_piece, (uint8_t *)(fw_hash_start_addr), fw_piece_size);
            err_code = nrf_crypto_hash_update(&hash_context, fw_piece, fw_piece_size);
            APP_ERROR_CHECK(err_code);
            printf("Current last hashed address: %x\n", fw_hash_start_addr + fw_piece_size);
        }
        // Run the finalize when all data has been fed to the update function.
        // this gives you the result
    
        err_code = nrf_crypto_hash_finalize(&hash_context, m_digest, &hash_len);
        APP_ERROR_CHECK(err_code);
    }

Related