This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DFU firmware encryption

Hi,

I would like to implement DFU with firmware encryption. I'm aware this isn't present in SDK 12 and would like to modify the secured bootloader to implement it.

As far as I understand, a DFU package is a zip file containing a manifest, and sets of 2 files, a .dat and a .bin . Is it right that the .bin is pure image, and .dat is the header/init packet?

My plan was to encrypt the .bin file, then, in the DFU bootloader, decrypt just before writing to flash. Does this sound like a good approach?

Thanks for your help!

Parents Reply Children
  • Thanks for the confirmation, I've figured I had to change the CRC computation, so far I've failed, but I'll keep trying! (If I got it right, CRC is computed on the flight as data is received, I've tried to change to "compute CRC on decrypted data", but getting glitches)

  • CRC is calculated and checked after each object is received. Have a look here. You can consider to check CRC for the encrypted packet instead of decrypted packet. This is to ensure the object is received properly over the air. Also, doing this you don't have to modify the bootloader on that part.

    You can use the hash of the decrypted image to do the final validation of the image integrity.

  • Thank you very much for the suggestion! I'm now looking at changing the CRC in my update package, but something puzzles me... I can't find the CRC inside the DAT file. I was under the impression it would follow struct dfu_init_command_t (or dfu-cc.proto). The first 16 bytes are 12 84 01 0A 3E 08 01 12 3A 08 01 10 33 1A 02 87, 87 could match with SD requirement, but 12 (first one) certainly doesn't look like a boolean!

  • The bootloader uses the hash from the init packet to verify the authenticity and integrity of the FW image in the post validation step, while the checksum values (sent upon request) are only used by the dfu controller to verify that the data is received correctly during the transfer. For instance, to verify that a data object is valid before issuing the EXECUTE command. In other words, the bootloader must compute the CRC on encrypted data.

  • Response was too long for one comment:

    Something to be aware of, the bootloader stores DFU progress in bootloader settings to allow DFU to continue in case of power loss, which will need to be modified if you are using a stream cipher for decryption (i.e., include decryption state in progress data). This feature can be disabled by making the following change in dfu_req_handling:

    case NRF_DFU_OBJECT_OP_SELECT:
                NRF_LOG_INFO("Valid Command: NRF_DFU_OBJECT_OP_SELECT\r\n");
                p_res->crc = 0; //s_dfu_settings.progress.command_crc;
                p_res->offset = 0;  //s_dfu_settings.progress.command_offset;
                p_res->max_size = INIT_COMMAND_MAX_SIZE;
                break;
    

    Also, in case you are not aware of it, nrfutil has an option for viewing init packets in a more readable format:

    nrfutil pkg display app_dfu_package.zip
    
Related