Problem verifying DFU init package signature in custom background DFU

Hi

I am currently developing a custom dfu in my app in background through LTE communication. I am working with nRF5 SDK 17.0.2, softdevice s132 7.2.0 and nRF52832.

I'm using nrfutil to generate dfu package .zip. The version of nrfutil I'm using seems to be v6 (from command "nrfutil list" because "nrfutil version" is unknown command")

So far I've used nrf_dfu_req_handler module to make dfu requests with the following sequence complying with DFU protocol : 

  • Call nrf_dfu_req_handler_init() to init module
  • MTU GET request
  • CREATE OBJECT request
  • WRITE command for Init Packet
  • Compare CRC and EXECUTE request

At this point the validation fails with error code 0x8542 (NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE). See the following logs : 

I have displayed the signature of the package .zip I generated with nrfutil by typing : 

and it corresponds to the signature in the logs but with first and last halves switched.

How do I solve this issue ?

Also in the logs above there is a line "nrf_dfu_validation: PB: Init packet data len: 65". However the init packet I write with WRITE request is 142 bytes long. The write request response confirms that size (=offset) of 142 bytes. I wonder if this has something to do with my issue above.

Parents
  • Hello,

    It appears that the init command gets received correctly. Maybe it is a problem with the endianness. Did you build your application with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 like in the bootloader project, or are you using the uECC library? 

    Best regards,

    Vidar

  • Hi,

    Yes I build with uECC_VLI_NATIVE_LITTLE_ENDIAN=1

    About uECC I have a warning when compiling : 

    Maybe this file is causing the issue ?

    Best regards

  • Hi,

    Thanks for confirming. It is good to know that the DFU package is valid at least. I assume you use the same public key and uECC in both app and bootloader. I am not able to spot anything obvious from your sdk_config.h settings. NRF_CRYPTO_ALLOCATOR == 0 should work as long as you don't get any build errors. 

    With regards to the init packet size, 65 bytes is the actual payload after the 144 byte packet is decoded. 

    In the application, can you try to place a breakpoint at the line below to confirm that the endianness is being swapped when the init command is validated?

  • I am not able to put a breakpoint  in this function because SES says "no code for breakpoint". I guess it is not used and not compiled.

    It looks like the function nrf_crypto_backend_micro_ecc_private_key_from_raw() on your screenshot is only called in function nrf_crypto_ecc_private_key_from_raw() in file nrf_crypto_ecc.c

    But in my case the error 0x8542 is returned by function nrf_crypto_ecdsa_verify() called in nrf_dfu_validation_signature_check() in file nrf_dfu_validation.c and it seems that the endianness is swapped right before calling this function : 

  • Sorry, nrf_crypto_ecdsa_verify() is calling nrf_crypto_backend_micro_ecc_verify() in micro_ecc_backend_ecdsa.c. The only thing I can think of to try now is that you compare the input parameters passed to uECC_verify() in micr_ecc_backend_ecdsa.c when you upload via the bootloader and when you do it via the application to see if there are any differences. 

    EDIT: Another option may be to try with the Oberon library instead like I did in the example here:  RE: Background DFU application source code  

  • How can I get the parameters passed to uECC_verify() in my bootloader's DFU ? Is there a way to debug the bootloader when both the bootloader and the app are programmed via nrfjprog ?

    Ok for Oberon I'm going to try this.

  • You can start a debug session with the bootloader project even if there is an application present and running. The breakpoint should be reached as soon as you initiate the DFU.

Reply
  • You can start a debug session with the bootloader project even if there is an application present and running. The breakpoint should be reached as soon as you initiate the DFU.

Children
  • Hi Vidar,

    Sorry for the delay of my response but I still struggle trying to debug the secure bootloader. As advised on a different devzone thread with similar issue, I've tried to lower the optimisation level and to reallocate memory section for the bigger bootloader generated. However I did not manage to get either debug or logs. Mayby I'll open a thread later on if I still need to debug the bootloader.

    Anyway I finally found the cause of my problem. The file dfu_public_key.c included in my app project was not the same as the dfu_public_key.c used by my bootloader which I also used to generate my zip packages. The intern I got the project from created its own public key trying to implement a custom dfu. Slight smile

    Thanks for helping me and for your responsiveness !

    BR

  • This is why debugging crypto services can be hard at times Slight smile Anyway I am glad to hear that it works now. Thank you for updating the ticket.

    Adding logging to the "release" bootloader can be a bit cumbersome as it does not include the logger dependencies by default. Nor does it have enough flash allocated to it. This is why I usually try to just debug the bootloader with optimizations enabled and without logging first. The screenshot I posted earlier that showed the paramaters passed to uECC verify was with optimizations enabled.