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 nrf51-sdk by
dfu_init_template.c
00001 /* 00002 * Copyright (c) Nordic Semiconductor ASA 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, this 00012 * list of conditions and the following disclaimer in the documentation and/or 00013 * other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 00016 * contributors to this software may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00024 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 /**@file 00034 * 00035 * @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example. 00036 * @{ 00037 * 00038 * @ingroup nrf_dfu 00039 * 00040 * @brief This file contains a template on how to implement DFU init packet handling. 00041 * 00042 * @details The template shows how device type and revision can be used for a safety check of the 00043 * received image. It shows how validation can be performed in two stages: 00044 * - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches: 00045 * - Device Type. 00046 * - Device Revision. 00047 * Installed SoftDevice. 00048 * This template can be extended with additional checks according to needs. 00049 * For example, such a check could be the origin of the image (trusted source) 00050 * based on a signature scheme. 00051 * - Stage 2: Post-check of the image after image transfer but before installing firmware. 00052 * For example, such a check could be an integrity check in form of hashing or 00053 * verification of a signature. 00054 * In this template, a simple CRC check is carried out. 00055 * The CRC check can be replaced with other mechanisms, like signing. 00056 * 00057 * @note This module does not support security features such as image signing, but the 00058 * implementation allows for such extension. 00059 * If the init packet is signed by a trusted source, it must be decrypted before it can be 00060 * processed. 00061 */ 00062 00063 #include "dfu_init.h " 00064 #include <stdint.h> 00065 #include <string.h> 00066 #include <dfu_types.h > 00067 #include "nrf_error.h" 00068 #include "crc16.h " 00069 00070 #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. */ 00071 #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. */ 00072 00073 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. */ 00074 static uint8_t m_extended_packet_length; //< Length of the extended data received with init packet. */ 00075 00076 00077 uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len) 00078 { 00079 uint32_t i = 0; 00080 00081 // In order to support signing or encryption then any init packet decryption function / library 00082 // should be called from here or implemented at this location. 00083 00084 // Length check to ensure valid data are parsed. 00085 if (init_data_len < sizeof(dfu_init_packet_t)) 00086 { 00087 return NRF_ERROR_INVALID_LENGTH; 00088 } 00089 00090 // Current template uses clear text data so they can be casted for pre-check. 00091 dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data; 00092 00093 m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) - 00094 (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]; 00095 if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN) 00096 { 00097 return NRF_ERROR_INVALID_LENGTH; 00098 } 00099 00100 if (((uint32_t)p_init_data + init_data_len) < 00101 (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]) 00102 { 00103 return NRF_ERROR_INVALID_LENGTH; 00104 } 00105 00106 memcpy(m_extended_packet, 00107 &p_init_packet->softdevice[p_init_packet->softdevice_len], 00108 m_extended_packet_length); 00109 00110 /** [DFU init application version] */ 00111 // To support application versioning, this check should be updated. 00112 // This template allows for any application to be installed. However, 00113 // customers can place a revision number at the bottom of the application 00114 // to be verified by the bootloader. This can be done at a location 00115 // relative to the application, for example the application start 00116 // address + 0x0100. 00117 /** [DFU init application version] */ 00118 00119 // First check to verify the image to be transfered matches the device type. 00120 // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted. 00121 if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) && 00122 (p_init_packet->device_type != DFU_DEVICE_INFO->device_type)) 00123 { 00124 return NRF_ERROR_INVALID_DATA; 00125 } 00126 00127 // Second check to verify the image to be transfered matches the device revision. 00128 // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted. 00129 if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) && 00130 (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev)) 00131 { 00132 return NRF_ERROR_INVALID_DATA; 00133 } 00134 00135 // Third check: Check the array of supported SoftDevices by this application. 00136 // If the installed SoftDevice does not match any SoftDevice in the list then an 00137 // error is returned. 00138 while (i < p_init_packet->softdevice_len) 00139 { 00140 if (p_init_packet->softdevice[i] == DFU_SOFTDEVICE_ANY || 00141 p_init_packet->softdevice[i++] == SD_FWID_GET(MBR_SIZE)) 00142 { 00143 return NRF_SUCCESS; 00144 } 00145 } 00146 00147 // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA. 00148 return NRF_ERROR_INVALID_DATA; 00149 } 00150 00151 00152 uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len) 00153 { 00154 #if NEED_CRC_CHECK /* disabled for now */ 00155 uint16_t image_crc; 00156 uint16_t received_crc; 00157 00158 // In order to support hashing (and signing) then the (decrypted) hash should be fetched and 00159 // the corresponding hash should be calculated over the image at this location. 00160 // If hashing (or signing) is added to the system then the CRC validation should be removed. 00161 00162 // calculate CRC from active block. 00163 image_crc = crc16_compute(p_image, image_len, NULL); 00164 00165 // Decode the received CRC from extended data. 00166 received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]); 00167 00168 // Compare the received and calculated CRC. 00169 if (image_crc != received_crc) 00170 { 00171 return NRF_ERROR_INVALID_DATA; 00172 } 00173 #endif /* NEED_CRC_CHECK */ 00174 00175 return NRF_SUCCESS; 00176 } 00177
Generated on Tue Jul 12 2022 14:11:19 by
