prevent dfu 832 bootloader on 840 and vice versa
This commit is contained in:
		
							
								
								
									
										185
									
								
								src/dfu_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								src/dfu_init.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | ||||
| /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. | ||||
|  * | ||||
|  * The information contained herein is property of Nordic Semiconductor ASA. | ||||
|  * Terms and conditions of usage are described in detail in NORDIC | ||||
|  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. | ||||
|  * | ||||
|  * Licensees are granted free, non-transferable use of the information. NO | ||||
|  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from | ||||
|  * the file. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /**@file | ||||
|  * | ||||
|  * @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example. | ||||
|  * @{ | ||||
|  * | ||||
|  * @ingroup nrf_dfu | ||||
|  * | ||||
|  * @brief This file contains a template on how to implement DFU init packet handling. | ||||
|  * | ||||
|  * @details The template shows how device type and revision can be used for a safety check of the  | ||||
|  *          received image. It shows how validation can be performed in two stages: | ||||
|  *          - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches: | ||||
|  *                     - Device Type. | ||||
|  *                     - Device Revision. | ||||
|  *                     Installed SoftDevice. | ||||
|  *                     This template can be extended with additional checks according to needs. | ||||
|  *                     For example, such a check could be the origin of the image (trusted source)  | ||||
|  *                     based on a signature scheme. | ||||
|  *          - Stage 2: Post-check of the image after image transfer but before installing firmware. | ||||
|  *                     For example, such a check could be an integrity check in form of hashing or  | ||||
|  *                     verification of a signature. | ||||
|  *                     In this template, a simple CRC check is carried out. | ||||
|  *                     The CRC check can be replaced with other mechanisms, like signing. | ||||
|  * | ||||
|  * @note This module does not support security features such as image signing, but the  | ||||
|  *       implementation allows for such extension. | ||||
|  *       If the init packet is signed by a trusted source, it must be decrypted before it can be | ||||
|  *       processed. | ||||
|  */ | ||||
|  | ||||
| #include "dfu_init.h" | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <dfu_types.h> | ||||
| #include "nrf_error.h" | ||||
| #include "crc16.h" | ||||
|  | ||||
| /* ADAFRUIT | ||||
|  * - All firmware init data must has Device Type ADAFRUIT_DEVICE_TYPE (nrf52832 and nrf52840) | ||||
|  * - SD + Bootloader upgrade must have correct Device Revision to make sure bootloader is not flashed | ||||
|  * on the wrong device (e.g flah nRF52832's bootloader on nRF52840 board and vice versa) | ||||
|  *   - nrf52832 dev-rev is 0xADAF | ||||
|  *   - nrf52840 dev-rev is  52840 | ||||
|  */ | ||||
| #define ADAFRUIT_DEVICE_TYPE         0x0052 | ||||
|  | ||||
| #ifdef NRF52840_XXAA | ||||
|   #define ADAFRUIT_DEV_REV           52840 | ||||
| #elif defined NRF52832_XXAA | ||||
|   #define ADAFRUIT_DEV_REV           0xADAF | ||||
| #else | ||||
|   #error Unknown MCU | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #define DFU_INIT_PACKET_EXT_LENGTH_MIN      2                       //< Minimum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a minimum value of two in order to hold a CRC. */ | ||||
| #define DFU_INIT_PACKET_EXT_LENGTH_MAX      10                      //< Maximum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a maximum value of 10 in order to hold a CRC and any padded data on transport layer without overflow. */ | ||||
|  | ||||
| static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX];   //< Data array for storage of the extended data received. The extended data follows the normal init data of type \ref dfu_init_packet_t. Extended data can be used for a CRC, hash, signature, or other data. */ | ||||
| static uint8_t m_extended_packet_length;                            //< Length of the extended data received with init packet. */ | ||||
|  | ||||
|  | ||||
| uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len, uint8_t image_type) | ||||
| { | ||||
|     uint32_t i = 0; | ||||
|      | ||||
|     // In order to support signing or encryption then any init packet decryption function / library | ||||
|     // should be called from here or implemented at this location. | ||||
|  | ||||
|     // Length check to ensure valid data are parsed. | ||||
|     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. | ||||
| //    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 no Device revision is present in DFU_DEVICE_INFO then any image will be accepted. | ||||
|     // if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) && | ||||
|     //    (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev)) | ||||
|  | ||||
|     if ( p_init_packet->device_type != ADAFRUIT_DEVICE_TYPE ) | ||||
|     { | ||||
|         return NRF_ERROR_FORBIDDEN; | ||||
|     } | ||||
|  | ||||
|     // Adafruit unlock code must match to upgrade SoftDevice and/or Bootloader | ||||
|     if ( image_type & (DFU_UPDATE_SD | DFU_UPDATE_BL) ) | ||||
|     { | ||||
|       if (p_init_packet->device_rev != ADAFRUIT_DEV_REV) | ||||
|       { | ||||
|         return NRF_ERROR_FORBIDDEN; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // 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++] == SD_FWID_GET(MBR_SIZE)) | ||||
|         { | ||||
|             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; | ||||
|      | ||||
|     // In order to support hashing (and signing) then the (decrypted) hash should be fetched and | ||||
|     // the corresponding hash should be calculated over the image at this location. | ||||
|     // If hashing (or signing) is added to the system then the CRC validation should be removed. | ||||
|  | ||||
|     // 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; | ||||
| } | ||||
|  | ||||
| @@ -19,13 +19,13 @@ | ||||
|       arm_target_device_name="nRF52840_xxAA" | ||||
|       arm_target_interface_type="SWD" | ||||
|       c_preprocessor_definitions="NRF52840_XXAA;__nRF_FAMILY;ARM_MATH_CM4;FLASH_PLACEMENT=1;NO_VTOR_CONFIG;BOARD_PCA10056;MK_BOOTLOADER_VERSION=0x06000000;MK_DIS_FIRMWARE="s140 6.0.0 r0";S140;CONFIG_GPIO_AS_PINRESET;BLE_STACK_SUPPORT_REQD;SWI_DISABLE0;SOFTDEVICE_PRESENT;FLOAT_ABI_HARD" | ||||
|       c_user_include_directories="../;../usb;../cmsis/include;$(tusbDir);$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include;$(sdDir)/headers;$(sdDir)/headers/nrf52;$(sdk11Dir)/drivers_nrf/pstorage;$(sdk11Dir)/ble/common/;$(sdk11Dir)/ble/ble_services/ble_dfu;$(sdk11Dir)/ble/ble_services/ble_dis;$(sdk11Dir)/libraries/bootloader_dfu;$(sdk11Dir)/libraries/bootloader_dfu/hci_transport;$(sdk11Dir)/libraries/util;$(sdkDir)/toolchain/cmsis/include;$(sdkDir)/device;$(sdkDir)/toolchain;$(sdkDir)/drivers_nrf/hal;$(sdkDir)/drivers_nrf/systick;$(sdkDir)/drivers_nrf/uart;$(sdkDir)/drivers_nrf/usbd;$(sdkDir)/drivers_nrf/common;$(sdkDir)/drivers_nrf/delay;$(sdkDir)/drivers_nrf/power;$(sdkDir)/drivers_nrf/clock;$(sdkDir)/libraries/util;$(sdkDir)/libraries/timer;$(sdkDir)/libraries/scheduler;$(sdkDir)/libraries/crc16;$(sdkDir)/libraries/util;$(sdkDir)/libraries/hci/config;$(sdkDir)/libraries/uart;$(sdkDir)/libraries/hci;$(sdkDir)/external/fprintf;$(sdkDir)/libraries/strerror;$(sdkDir)/libraries/atomic;$(sdkDir)/libraries/balloc;$(sdkDir)/libraries/experimental_log/src;$(sdkDir)/libraries/experimental_log;$(sdkDir)/libraries/experimental_section_vars;$(sdkDir)/libraries/experimental_memobj" | ||||
|       c_user_include_directories="../;../usb;../cmsis/include;$(tusbDir);$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include;$(sdDir)/include;$(sdDir)/include/nrf52;$(sdk11Dir)/drivers_nrf/pstorage;$(sdk11Dir)/ble/common/;$(sdk11Dir)/ble/ble_services/ble_dfu;$(sdk11Dir)/ble/ble_services/ble_dis;$(sdk11Dir)/libraries/bootloader_dfu;$(sdk11Dir)/libraries/bootloader_dfu/hci_transport;$(sdk11Dir)/libraries/util;$(sdkDir)/toolchain/cmsis/include;$(sdkDir)/device;$(sdkDir)/toolchain;$(sdkDir)/drivers_nrf/hal;$(sdkDir)/drivers_nrf/systick;$(sdkDir)/drivers_nrf/uart;$(sdkDir)/drivers_nrf/usbd;$(sdkDir)/drivers_nrf/common;$(sdkDir)/drivers_nrf/delay;$(sdkDir)/drivers_nrf/power;$(sdkDir)/drivers_nrf/clock;$(sdkDir)/libraries/util;$(sdkDir)/libraries/timer;$(sdkDir)/libraries/scheduler;$(sdkDir)/libraries/crc16;$(sdkDir)/libraries/util;$(sdkDir)/libraries/hci/config;$(sdkDir)/libraries/uart;$(sdkDir)/libraries/hci;$(sdkDir)/external/fprintf;$(sdkDir)/libraries/strerror;$(sdkDir)/libraries/atomic;$(sdkDir)/libraries/balloc;$(sdkDir)/libraries/experimental_log/src;$(sdkDir)/libraries/experimental_log;$(sdkDir)/libraries/experimental_section_vars;$(sdkDir)/libraries/experimental_memobj" | ||||
|       debug_register_definition_file="$(ProjectDir)/nrf52840_Registers.xml" | ||||
|       debug_target_connection="J-Link" | ||||
|       gcc_entry_point="Reset_Handler" | ||||
|       linker_memory_map_file="$(ProjectDir)/nRF52840_xxAA_MemoryMap.xml" | ||||
|       linker_section_placement_file="$(ProjectDir)/flash_placement.xml" | ||||
|       macros="DeviceHeaderFile=$(PackagesDir)/nRF/CMSIS/Device/Include/nrf.h;DeviceLibraryIdentifier=M4lf;DeviceSystemFile=$(PackagesDir)/nRF/CMSIS/Device/Source/system_nrf52840.c;DeviceVectorsFile=$(PackagesDir)/nRF/Source/ses_nrf52840_Vectors.s;DeviceFamily=nRF;Target=nRF52840_xxAA;Placement=Flash;sdkDir=../../lib/sdk/components;sdk11Dir=../../lib/sdk11/components;sdDir=../../lib/softdevice/s140/6.0.0;tusbDir=../../lib/tinyusb/src;nrfxDir=../../lib/nrfx" | ||||
|       macros="DeviceHeaderFile=$(PackagesDir)/nRF/CMSIS/Device/Include/nrf.h;DeviceLibraryIdentifier=M4lf;DeviceSystemFile=$(PackagesDir)/nRF/CMSIS/Device/Source/system_nrf52840.c;DeviceVectorsFile=$(PackagesDir)/nRF/Source/ses_nrf52840_Vectors.s;DeviceFamily=nRF;Target=nRF52840_xxAA;Placement=Flash;sdkDir=../../lib/sdk/components;sdk11Dir=../../lib/sdk11/components;sdDir=../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API;tusbDir=../../lib/tinyusb/src;nrfxDir=../../lib/nrfx" | ||||
|       project_directory="" | ||||
|       project_type="Executable" | ||||
|       target_reset_script="Reset();" | ||||
| @@ -93,6 +93,7 @@ | ||||
|         <file file_name="../boards/feather52840.h" /> | ||||
|         <file file_name="../boards/pca10056.h" /> | ||||
|       </folder> | ||||
|       <file file_name="../dfu_init.c" /> | ||||
|     </folder> | ||||
|     <configuration Name="Debug Single" gcc_optimization_level="Debug" /> | ||||
|     <configuration | ||||
| @@ -142,7 +143,6 @@ | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_ble_svc.h" /> | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h" /> | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_init.h" /> | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_init_template.c" /> | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_transport.h" /> | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_ble.c" /> | ||||
|               <file file_name="../../lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_serial.c" /> | ||||
| @@ -228,29 +228,28 @@ | ||||
|         </folder> | ||||
|       </folder> | ||||
|       <folder Name="softdevice"> | ||||
|         <folder Name="6.0.0"> | ||||
|           <folder Name="s140"> | ||||
|             <folder Name="headers"> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_err.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_gap.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_gatt.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_gattc.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_gatts.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_hci.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_l2cap.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_ranges.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/ble_types.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_error.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_error_sdm.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_error_soc.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_nvic.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_sd_def.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_sdm.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_soc.h" /> | ||||
|               <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf_svc.h" /> | ||||
|         <folder Name="s140_nrf52_6.1.0"> | ||||
|           <folder Name="s140_nrf52_6.1.0_API"> | ||||
|             <folder Name="include"> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_err.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gap.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatt.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gattc.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatts.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_hci.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_ranges.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_types.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_sdm.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_soc.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_nvic.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_sdm.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_soc.h" /> | ||||
|               <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_svc.h" /> | ||||
|               <folder Name="nrf52"> | ||||
|                 <file file_name="../../lib/softdevice/6.0.0/s140/headers/nrf52/nrf_mbr.h" /> | ||||
|                 <file file_name="../../lib/softdevice/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf52/nrf_mbr.h" /> | ||||
|               </folder> | ||||
|             </folder> | ||||
|           </folder> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user