Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
dfu_init_template.c
00001 /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 /**@file 00014 * 00015 * @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example. 00016 * @{ 00017 * 00018 * @ingroup nrf_dfu 00019 * 00020 * @brief This file contains a template on how to implement DFU init packet handling. 00021 * 00022 * @details The template shows how device type and revision can be used for a safety check of the 00023 * received image. It shows how validation can be performed in two stages: 00024 * - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches: 00025 * - Device Type. 00026 * - Device Revision. 00027 * Installed SoftDevice. 00028 * This template can be extended with additional checks according to needs. 00029 * For example, such a check could be the origin of the image (trusted source) 00030 * based on a signature scheme. 00031 * - Stage 2: Post-check of the image after image transfer but before installing firmware. 00032 * For example, such a check could be an integrity check in form of hashing or 00033 * verification of a signature. 00034 * In this template, a simple CRC check is carried out. 00035 * The CRC check can be replaced with other mechanisms, like signing. 00036 * 00037 * @note This module does not support security features such as image signing, but the 00038 * implementation allows for such extension. 00039 * If the init packet is signed by a trusted source, it must be decrypted before it can be 00040 * processed. 00041 */ 00042 00043 #include "dfu_init.h " 00044 #include <stdint.h> 00045 #include <string.h> 00046 #include "dfu_types.h " 00047 #include "nrf_error.h" 00048 #include "crc16.h " 00049 00050 #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. */ 00051 #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. */ 00052 00053 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. */ 00054 static uint8_t m_extended_packet_length; //< Length of the extended data received with init packet. */ 00055 00056 00057 uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len) 00058 { 00059 uint32_t i = 0; 00060 00061 // In order to support signing or encryption then any init packet decryption function / library 00062 // should be called from here or implemented at this location. 00063 00064 // Length check to ensure valid data are parsed. 00065 if (init_data_len < sizeof(dfu_init_packet_t)) 00066 { 00067 return NRF_ERROR_INVALID_LENGTH; 00068 } 00069 00070 // Current template uses clear text data so they can be casted for pre-check. 00071 dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data; 00072 00073 m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) - 00074 (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]; 00075 if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN) 00076 { 00077 return NRF_ERROR_INVALID_LENGTH; 00078 } 00079 00080 if (((uint32_t)p_init_data + init_data_len) < 00081 (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]) 00082 { 00083 return NRF_ERROR_INVALID_LENGTH; 00084 } 00085 00086 memcpy(m_extended_packet, 00087 &p_init_packet->softdevice[p_init_packet->softdevice_len], 00088 m_extended_packet_length); 00089 00090 /** [DFU init application version] */ 00091 // In order to support application versioning this check should be updated. 00092 // This template allows for any application to be installed however customer could place a 00093 // revision number at bottom of application to be verified by bootloader. This could be done at 00094 // a relative location to this papplication for example Application start address + 0x0100. 00095 /** [DFU init application version] */ 00096 00097 // First check to verify the image to be transfered matches the device type. 00098 // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted. 00099 if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) && 00100 (p_init_packet->device_type != DFU_DEVICE_INFO->device_type)) 00101 { 00102 return NRF_ERROR_INVALID_DATA; 00103 } 00104 00105 // Second check to verify the image to be transfered matches the device revision. 00106 // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted. 00107 if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) && 00108 (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev)) 00109 { 00110 return NRF_ERROR_INVALID_DATA; 00111 } 00112 00113 // Third check: Check the array of supported SoftDevices by this application. 00114 // If the installed SoftDevice does not match any SoftDevice in the list then an 00115 // error is returned. 00116 while (i < p_init_packet->softdevice_len) 00117 { 00118 if (p_init_packet->softdevice[i] == DFU_SOFTDEVICE_ANY || 00119 p_init_packet->softdevice[i++] == SOFTDEVICE_INFORMATION->firmware_id) 00120 { 00121 return NRF_SUCCESS; 00122 } 00123 } 00124 00125 // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA. 00126 return NRF_ERROR_INVALID_DATA; 00127 } 00128 00129 00130 uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len) 00131 { 00132 uint16_t image_crc; 00133 uint16_t received_crc; 00134 00135 // In order to support hashing (and signing) then the (decrypted) hash should be fetched and 00136 // the corresponding hash should be calculated over the image at this location. 00137 // If hashing (or signing) is added to the system then the CRC validation should be removed. 00138 00139 // calculate CRC from active block. 00140 image_crc = crc16_compute(p_image, image_len, NULL); 00141 00142 // Decode the received CRC from extended data. 00143 received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]); 00144 00145 // Compare the received and calculated CRC. 00146 if (image_crc != received_crc) 00147 { 00148 return NRF_ERROR_INVALID_DATA; 00149 } 00150 00151 return NRF_SUCCESS; 00152 } 00153
Generated on Tue Jul 12 2022 16:21:03 by
