test
Fork of nrf51-sdk by
Embed:
(wiki syntax)
Show/hide line numbers
dfu_init_template.c
Go to the documentation of this file.
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 15:51:26 by 1.7.2