nrf51822 secure DFU by OTA: How to Set Password in the DFU zip File

This article is to provide a security solution for DFU.

My application is based on Heart rate Service 
(  s110  with dfu in Nordic SDK)

C:\..\..\..\nRF51_SDK_10.0.0\nRF51_SDK_10.0.0_dc26b5e\examples\ble_peripheral\ble_app_hrs

the firmware can check if the DFU .zip file is authorized by manifest.json 
(in.zip ,usually called INIT file in Nordic Website).

The PASSWORD could be set in the zip file parameters while packed, and you should modify the bootloader code, to consist with the parameters. 



step 0.my environment:

  • nRF51822DK xxac
  • softdevice s110 8.0.0
  • Keil_v5 
  • nrf SDK 10.0.0
  • bootloader_s110      <--will be changed by me in step 2
  • master control panel 3.10.0.8

  • Android 6.0.1
  • windows 7
  • nrf Connect (for android) <--download the latest version
  • Samsung J7 prime

step 1.set password in .zip file

There are 3 options to place my password: device version, device type and application version.



To simply my example, , I adopt the "application version" as my password column at first .

(About how to adopt device revision or device type ,see Note.3)


password :0x03734301

cd C:\Program Files (x86)\Nordic Semiconductor\Master Control Panel\3.10.0.14\nrf\
nrfutil.exe dfu genpkg --nRF51422_xxac_s110.bin --application-version 0x03734301 --dev-revision 0xFFFF --dev-type 0xFFFF --sd-req 0x4f,0x5a,0x64 app_version_password.zip


add the .zip file to smartphone

step 2.customized your bootloader

copy bootloader folder  from:
C:\\nRF51_SDK_10.0.0\nRF51_SDK_10.0.0_dc26b5e\examples\dfu\bootloader

rename it as  bootloader_with_password

copy dfu_init_template.c from  nRF51_SDK_10.0.0_dc26b5e\components\libraries\bootloader_dfu 

modift the project setting to  depend on the dfu_init_template.c  
which be inside folder bootloader_with_password, instead of the one in components\libraries\bootloader_dfu .

In  dfu_init_template.c

#include "dfu_init.h"
#include <stdint.h>
#include <string.h>
#include "dfu_types.h"
#include "nrf_error.h"
#include "crc16.h"

#define DFU_INIT_PACKET_EXT_LENGTH_MIN      2                       
#define DFU_INIT_PACKET_EXT_LENGTH_MAX      10                      

static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX];   
static uint8_t m_extended_packet_length;                            

#define APP_VERSION_PASSWORD                  ((uint32_t)0x03734301)

uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len)
{
    uint32_t i = 0;
    
    
    if (init_data_len < sizeof(dfu_init_packet_t))
    {
        return NRF_ERROR_INVALID_LENGTH;
    }

    // Current template uses clear text data so they can be casted for pre-check.
    dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data;

    m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) -
                   (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len];
    
    if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN)
    {
        return NRF_ERROR_INVALID_LENGTH;
    }

    if (((uint32_t)p_init_data + init_data_len) < 
        (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len])
    {
        return NRF_ERROR_INVALID_LENGTH;
    }

    memcpy(m_extended_packet,
           &p_init_packet->softdevice[p_init_packet->softdevice_len],
           m_extended_packet_length);

/** [DFU init application version] */
    // To support application versioning, this check should be updated.
    // This template allows for any application to be installed. However, 
    // customers can place a revision number at the bottom of the application 
    // to be verified by the bootloader. This can be done at a location 
    // relative to the application, for example the application start 
    // address + 0x0100.
/** [DFU init application version] */
    
    // First check to verify the image to be transfered matches the device type.
    // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted.
  

    /*agatha: set application version check*/  if ((p_init_packet->app_version!= APP_VERSION_PASSWORD)) { return NRF_ERROR_INVALID_DATA; }/*app_version check*/ 
    
    //First check 
    if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) &&
   (p_init_packet->device_type != DFU_DEVICE_INFO->device_type))
    {
        return NRF_ERROR_INVALID_DATA;
    }
   
    // Second check to verify the image to be transfered matches the device revision.
    
    if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) &&
        (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev))
    {
        return NRF_ERROR_INVALID_DATA;
    }

    // Third check: Check the array of supported SoftDevices by this application.
    // If the installed SoftDevice does not match any SoftDevice in the list then an
    // error is returned.
    while (i < p_init_packet->softdevice_len)
    {
        if (p_init_packet->softdevice[i] == DFU_SOFTDEVICE_ANY ||
            p_init_packet->softdevice[i++] == SOFTDEVICE_INFORMATION->firmware_id)
        {
            return NRF_SUCCESS;
        }
    }
    
    // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA.
    return NRF_ERROR_INVALID_DATA;
}


uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len)
{
    uint16_t image_crc;
    uint16_t received_crc;
    
    
    // calculate CRC from active block.
    image_crc = crc16_compute(p_image, image_len, NULL);

    // Decode the received CRC from extended data.    
    received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]);

    // Compare the received and calculated CRC.
    if (image_crc != received_crc)
    {
        return NRF_ERROR_INVALID_DATA;
    }

    return NRF_SUCCESS;
}

The structure   p_init_packet  would pass the password from INIT file, in here, modify the code to check its value consisted with true password .

Rebuild bootloader.hex and application. Then use nRFgo Studio to program:
  • softdevice
  • application
  • bootloader (be changed by you)




step 3.test 

open Nordic nRF connecter app

connect your board

press the DFU button above

press "Distribution packet" and select the .zip file we made in STEP 1
start DFU
After DFU , reset the board

if you add the zip file that the parameter  --application-version is incorrect, your smartphone will soon disconnect to device .


Additional notes:


0. This implement check the number of application version to achieve "set a password to avoid unknown .zip file ".


1. In my experience,Samsung smartphone has a higher probability to DFU failed.

(whether using which smartphone app)

2. nRF connect ,the app I used , has some problem in DFU mode and connect the device after DFU. 


3. I suggest not to check dev_type and dev_rev,but use application version ,because application version isn't used in normal bootloader.


However, if you want to check device type, that is feasible :


add in bootloader
/*agatha: how to check  device type*/
#define DEV_TYPE_PASSWORD  0x1618  
  
   if ((p_init_packet->device_type != DEV_TYPE_PASSWORD))
    {
        return NRF_ERROR_INVALID_DATA;
    }
  
#if (0)
   
    if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) &&
   (p_init_packet->device_type != DFU_DEVICE_INFO->device_type))
    {
        return NRF_ERROR_INVALID_DATA;
    }
#endif   
and make the .zip file


cd C:\Program Files (x86)\Nordic Semiconductor\Master Control Panel\3.10.0.14\nrf\
nrfutil.exe dfu genpkg --nRF51422_xxac_s110.bin --application-version 0x03734301 --dev-revision 0xFFFF --dev-type 0x1618 --sd-req 0x4f,0x5a,0x64 app_version_password.zip

you could adopt device_type and/or device_revision as further checking.


3. This method above can work in SDK11 , when the chip is nRF52 with softdevice s132.
But that can not be adopted to SDK12  and s232, s332. 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值