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!

  • 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
    
  • I agree with Vidar. You can encrypt the .bin file and then generate init packet base on the encrypted binary. Then you don't need to modify the .dat file. If you stil want to read/modify the .dat file manually you can have a look here.

  • So far, I've done the following: encrypt .bin file, leave .dat file untouched. When transferring, I leave everything as is, however, just before write to flash (the 2 calls to nrf_dfu_flash_store()) I decrypt the data into a new buffer, and instead of writing what is in m_data_buf, I change the call to write the decrypted content from the buffer. This way, the CRC works fine (as you outlined, it's computed on the transfered data), so I can transfer 100% of the object. However, once transfer is finished, it doesn't start the firmware (I don't know the exact reason why yet). Regarding the transfer resume, I'm going to use AES CTR (so far I'm using a dumb XOR only), and it might be slightly annoying to program, but the idea is to determine the offset, compute the AES CTR blocks for the bytes to be written to flash, XOR my decryption buffer and I'm done.

  • Ok there's just one thing I think I need to clear... When checking the image hash, what does the bootloader use? Does it compute new firmware hash by reading it from the flash? That's how I understand it. And then it seems to me I could leave .dat file intact, encrypt .bin after generating .dat, and decrypt data just before writing to the flash memory. CRC is always computed on encrypted data, SHA2 is always computed on the decrypted data. Am I wrong? I'm gonna flash again my firmware and put a breakpoint in nrf_dfu_postvalidate. Thank you guys!

  • Forgot to point out that you need to generate the init packet first, as you said. This should work.

Related