nrf_dfu_validation.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. /**
  2. * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include <stdbool.h>
  41. #include "nrf_dfu_types.h"
  42. #include "nrf_dfu_settings.h"
  43. #include "nrf_dfu_utils.h"
  44. #include "nrf_dfu_flash.h"
  45. #include "nrf_bootloader_info.h"
  46. #include "pb.h"
  47. #include "pb_common.h"
  48. #include "pb_decode.h"
  49. #include "dfu-cc.pb.h"
  50. #include "crc32.h"
  51. #include "nrf_crypto.h"
  52. #include "nrf_crypto_shared.h"
  53. #include "nrf_assert.h"
  54. #include "nrf_dfu_validation.h"
  55. #include "nrf_dfu_ver_validation.h"
  56. #include "nrf_strerror.h"
  57. #define NRF_LOG_MODULE_NAME nrf_dfu_validation
  58. #include "nrf_log.h"
  59. #include "nrf_log_ctrl.h"
  60. NRF_LOG_MODULE_REGISTER();
  61. #ifndef DFU_REQUIRES_SOFTDEVICE
  62. #if !defined(BLE_STACK_SUPPORT_REQD) && !defined(ANT_STACK_SUPPORT_REQD)
  63. #define DFU_REQUIRES_SOFTDEVICE 0
  64. #else
  65. #define DFU_REQUIRES_SOFTDEVICE 1
  66. #endif
  67. #endif
  68. #define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
  69. /* Whether a complete init command has been received and prevalidated, but the firmware
  70. * is not yet fully transferred. This value will also be correct after reset.
  71. */
  72. static bool m_valid_init_cmd_present = false;
  73. static dfu_packet_t m_packet = DFU_PACKET_INIT_DEFAULT;
  74. static uint8_t* m_init_packet_data_ptr = 0;
  75. static uint32_t m_init_packet_data_len = 0;
  76. static pb_istream_t m_pb_stream;
  77. static dfu_init_command_t const * mp_init = NULL;
  78. __ALIGN(4) extern const uint8_t pk[64];
  79. /** @brief Value length structure holding the public key.
  80. *
  81. * @details The pk value pointed to is the public key present in dfu_public_key.c
  82. */
  83. static nrf_crypto_ecc_public_key_t m_public_key;
  84. /** @brief Structure to hold a signature
  85. */
  86. static nrf_crypto_ecdsa_secp256r1_signature_t m_signature;
  87. /** @brief Structure to hold the hash for signature verification
  88. */
  89. static nrf_crypto_hash_sha256_digest_t m_sig_hash;
  90. /** @brief Structure to hold the hash for the firmware image
  91. */
  92. static nrf_crypto_hash_sha256_digest_t m_fw_hash;
  93. /** @brief Whether nrf_crypto and local keys have been initialized.
  94. */
  95. static bool m_crypto_initialized = false;
  96. /** @brief Flag used by parser code to indicate that the init command has been found to be invalid.
  97. */
  98. static bool m_init_packet_valid = false;
  99. static void pb_decoding_callback(pb_istream_t *str,
  100. uint32_t tag,
  101. pb_wire_type_t wire_type,
  102. void *iter)
  103. {
  104. pb_field_iter_t* p_iter = (pb_field_iter_t *) iter;
  105. // Match the beginning of the init command.
  106. if (p_iter->pos->ptr == &dfu_init_command_fields[0])
  107. {
  108. uint8_t * ptr = (uint8_t *)str->state;
  109. uint32_t size = str->bytes_left;
  110. if (m_init_packet_data_ptr != NULL || m_init_packet_data_len != 0)
  111. {
  112. m_init_packet_valid = false;
  113. return;
  114. }
  115. // Remove tag.
  116. while (*ptr & 0x80)
  117. {
  118. ptr++;
  119. size--;
  120. }
  121. ptr++;
  122. size--;
  123. // Store the info in init_packet_data.
  124. m_init_packet_data_ptr = ptr;
  125. m_init_packet_data_len = size;
  126. m_init_packet_valid = true;
  127. NRF_LOG_DEBUG("PB: Init packet data len: %d", size);
  128. }
  129. }
  130. /** @brief Function for decoding byte stream into variable.
  131. *
  132. * @retval true If the stored init command was successfully decoded.
  133. * @retval false If there was no stored init command, or the decoding failed.
  134. */
  135. static bool stored_init_cmd_decode(void)
  136. {
  137. m_pb_stream = pb_istream_from_buffer(s_dfu_settings.init_command,
  138. s_dfu_settings.progress.command_size);
  139. dfu_init_command_t * p_init;
  140. // Attach our callback to follow the field decoding.
  141. m_pb_stream.decoding_callback = pb_decoding_callback;
  142. m_init_packet_valid = false;
  143. m_init_packet_data_ptr = NULL;
  144. m_init_packet_data_len = 0;
  145. memset(&m_packet, 0, sizeof(m_packet));
  146. if (!pb_decode(&m_pb_stream, dfu_packet_fields, &m_packet))
  147. {
  148. NRF_LOG_ERROR("Handler: Invalid protocol buffer m_pb_stream");
  149. return false;
  150. }
  151. if (!m_init_packet_valid || (m_packet.has_signed_command && m_packet.has_command))
  152. {
  153. NRF_LOG_ERROR("Handler: Invalid init command.");
  154. return false;
  155. }
  156. else if (m_packet.has_signed_command && m_packet.signed_command.command.has_init)
  157. {
  158. p_init = &m_packet.signed_command.command.init;
  159. m_pb_stream = pb_istream_from_buffer(m_init_packet_data_ptr, m_init_packet_data_len);
  160. memset(p_init, 0, sizeof(dfu_init_command_t));
  161. if (!pb_decode(&m_pb_stream, dfu_init_command_fields, p_init))
  162. {
  163. NRF_LOG_ERROR("Handler: Invalid protocol buffer m_pb_stream (init command)");
  164. return false;
  165. }
  166. }
  167. else if (m_packet.has_command && m_packet.command.has_init)
  168. {
  169. p_init = &m_packet.command.init;
  170. }
  171. else
  172. {
  173. return false;
  174. }
  175. mp_init = p_init;
  176. return true;
  177. }
  178. static void crypto_init(void)
  179. {
  180. ret_code_t err_code;
  181. uint8_t pk_copy[sizeof(pk)];
  182. if (m_crypto_initialized)
  183. {
  184. return;
  185. }
  186. err_code = nrf_crypto_init();
  187. ASSERT(err_code == NRF_SUCCESS);
  188. UNUSED_PARAMETER(err_code);
  189. // Convert public key to big-endian format for use in nrf_crypto.
  190. nrf_crypto_internal_double_swap_endian(pk_copy, pk, sizeof(pk) / 2);
  191. err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
  192. &m_public_key,
  193. pk_copy,
  194. sizeof(pk));
  195. ASSERT(err_code == NRF_SUCCESS);
  196. UNUSED_PARAMETER(err_code);
  197. m_crypto_initialized = true;
  198. }
  199. void nrf_dfu_validation_init(void)
  200. {
  201. // If the command is stored to flash, init command was valid.
  202. if ((s_dfu_settings.progress.command_size != 0) &&
  203. stored_init_cmd_decode())
  204. {
  205. m_valid_init_cmd_present = true;
  206. }
  207. else
  208. {
  209. m_valid_init_cmd_present = false;
  210. }
  211. }
  212. static void dfu_progress_reset(void)
  213. {
  214. memset(s_dfu_settings.init_command, 0xFF, INIT_COMMAND_MAX_SIZE); // Remove the last init command
  215. memset(&s_dfu_settings.progress, 0, sizeof(dfu_progress_t));
  216. s_dfu_settings.write_offset = 0;
  217. }
  218. nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size)
  219. {
  220. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  221. if (size == 0)
  222. {
  223. ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
  224. }
  225. else if (size > INIT_COMMAND_MAX_SIZE)
  226. {
  227. ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
  228. }
  229. else
  230. {
  231. // Set DFU to uninitialized.
  232. m_valid_init_cmd_present = false;
  233. // Reset all progress.
  234. dfu_progress_reset();
  235. // Set the init command size.
  236. s_dfu_settings.progress.command_size = size;
  237. }
  238. return ret_val;
  239. }
  240. nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length)
  241. {
  242. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  243. if ((length + s_dfu_settings.progress.command_offset) > s_dfu_settings.progress.command_size)
  244. {
  245. NRF_LOG_ERROR("Init command larger than expected.");
  246. ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
  247. }
  248. else
  249. {
  250. // Copy the received data to RAM, update offset and calculate CRC.
  251. memcpy(&s_dfu_settings.init_command[s_dfu_settings.progress.command_offset],
  252. p_data,
  253. length);
  254. s_dfu_settings.progress.command_offset += length;
  255. s_dfu_settings.progress.command_crc = crc32_compute(p_data,
  256. length,
  257. &s_dfu_settings.progress.command_crc);
  258. }
  259. return ret_val;
  260. }
  261. void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
  262. uint32_t * p_crc,
  263. uint32_t * p_max_size)
  264. {
  265. *p_offset = s_dfu_settings.progress.command_offset;
  266. *p_crc = s_dfu_settings.progress.command_crc;
  267. *p_max_size = INIT_COMMAND_MAX_SIZE;
  268. }
  269. bool nrf_dfu_validation_init_cmd_present(void)
  270. {
  271. return m_valid_init_cmd_present;
  272. }
  273. // Function determines if init command signature is obligatory.
  274. static bool signature_required(dfu_fw_type_t fw_type_to_be_updated)
  275. {
  276. bool result = true;
  277. // DFU_FW_TYPE_EXTERNAL_APPLICATION and bootloader updates always require
  278. // signature check
  279. if ((!DFU_REQUIRES_SOFTDEVICE && (fw_type_to_be_updated == DFU_FW_TYPE_SOFTDEVICE)) ||
  280. (fw_type_to_be_updated == DFU_FW_TYPE_APPLICATION))
  281. {
  282. result = NRF_DFU_REQUIRE_SIGNED_APP_UPDATE;
  283. }
  284. return result;
  285. }
  286. // Function to perform signature check if required.
  287. static nrf_dfu_result_t nrf_dfu_validation_signature_check(dfu_signature_type_t signature_type,
  288. uint8_t const * p_signature,
  289. uint32_t signature_len,
  290. uint8_t const * p_data,
  291. uint32_t data_len)
  292. {
  293. ret_code_t err_code;
  294. size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
  295. nrf_crypto_hash_context_t hash_context = {0};
  296. nrf_crypto_ecdsa_verify_context_t verify_context = {0};
  297. crypto_init();
  298. NRF_LOG_INFO("Signature required. Checking signature.")
  299. if (p_signature == NULL)
  300. {
  301. NRF_LOG_WARNING("No signature found.");
  302. return EXT_ERR(NRF_DFU_EXT_ERROR_SIGNATURE_MISSING);
  303. }
  304. if (signature_type != DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256)
  305. {
  306. NRF_LOG_INFO("Invalid signature type");
  307. return EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE);
  308. }
  309. NRF_LOG_INFO("Calculating hash (len: %d)", data_len);
  310. err_code = nrf_crypto_hash_calculate(&hash_context,
  311. &g_nrf_crypto_hash_sha256_info,
  312. p_data,
  313. data_len,
  314. m_sig_hash,
  315. &hash_len);
  316. if (err_code != NRF_SUCCESS)
  317. {
  318. return NRF_DFU_RES_CODE_OPERATION_FAILED;
  319. }
  320. if (sizeof(m_signature) != signature_len)
  321. {
  322. return NRF_DFU_RES_CODE_OPERATION_FAILED;
  323. }
  324. // Prepare the signature received over the air.
  325. memcpy(m_signature, p_signature, signature_len);
  326. // Calculate the signature.
  327. NRF_LOG_INFO("Verify signature");
  328. // The signature is in little-endian format. Change it to big-endian format for nrf_crypto use.
  329. nrf_crypto_internal_double_swap_endian_in_place(m_signature, sizeof(m_signature) / 2);
  330. err_code = nrf_crypto_ecdsa_verify(&verify_context,
  331. &m_public_key,
  332. m_sig_hash,
  333. hash_len,
  334. m_signature,
  335. sizeof(m_signature));
  336. if (err_code != NRF_SUCCESS)
  337. {
  338. NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code);
  339. NRF_LOG_DEBUG("Signature:");
  340. NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature));
  341. NRF_LOG_DEBUG("Hash:");
  342. NRF_LOG_HEXDUMP_DEBUG(m_sig_hash, hash_len);
  343. NRF_LOG_DEBUG("Public Key:");
  344. NRF_LOG_HEXDUMP_DEBUG(pk, sizeof(pk));
  345. NRF_LOG_FLUSH();
  346. return NRF_DFU_RES_CODE_INVALID_OBJECT;
  347. }
  348. NRF_LOG_INFO("Image verified");
  349. return NRF_DFU_RES_CODE_SUCCESS;
  350. }
  351. // Function to calculate the total size of the firmware(s) in the update.
  352. static nrf_dfu_result_t update_data_size_get(dfu_init_command_t const * p_init, uint32_t * p_size)
  353. {
  354. nrf_dfu_result_t ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
  355. uint32_t fw_sz = 0;
  356. if ((p_init->type == DFU_FW_TYPE_APPLICATION ||
  357. p_init->type == DFU_FW_TYPE_EXTERNAL_APPLICATION) &&
  358. (p_init->has_app_size == true))
  359. {
  360. fw_sz = p_init->app_size;
  361. }
  362. else
  363. {
  364. if ((p_init->type & DFU_FW_TYPE_SOFTDEVICE) && (p_init->has_sd_size == true))
  365. {
  366. fw_sz = p_init->sd_size;
  367. }
  368. if ((p_init->type & DFU_FW_TYPE_BOOTLOADER) && (p_init->has_bl_size == true))
  369. {
  370. if (p_init->bl_size <= BOOTLOADER_SIZE)
  371. {
  372. fw_sz += p_init->bl_size;
  373. }
  374. else
  375. {
  376. NRF_LOG_ERROR("BL size (%d) over limit (%d)", p_init->bl_size, BOOTLOADER_SIZE);
  377. fw_sz = 0;
  378. ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
  379. }
  380. }
  381. }
  382. if (fw_sz)
  383. {
  384. *p_size = fw_sz;
  385. ret_val = NRF_DFU_RES_CODE_SUCCESS;
  386. }
  387. else
  388. {
  389. NRF_LOG_ERROR("Init packet does not contain valid firmware size");
  390. }
  391. return ret_val;
  392. }
  393. /**
  394. * @brief Function to check if single bank update should be used.
  395. *
  396. * @param new_fw_type Firmware type.
  397. */
  398. static bool use_single_bank(dfu_fw_type_t new_fw_type)
  399. {
  400. bool result = false;
  401. // DFU_FW_TYPE_EXTERNAL_APPLICATION never uses single bank
  402. if (((new_fw_type == DFU_FW_TYPE_APPLICATION) ||
  403. (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)) &&
  404. NRF_DFU_SINGLE_BANK_APP_UPDATES)
  405. {
  406. result = true;
  407. }
  408. return result;
  409. }
  410. // Function to determine whether the new firmware needs a SoftDevice to be present.
  411. static bool update_requires_softdevice(dfu_init_command_t const * p_init)
  412. {
  413. return ((p_init->sd_req_count > 0) && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD));
  414. }
  415. // Function to determine whether the SoftDevice can be removed during the update or not.
  416. static bool keep_softdevice(dfu_init_command_t const * p_init)
  417. {
  418. UNUSED_PARAMETER(p_init); // It's unused when DFU_REQUIRES_SOFTDEVICE is true.
  419. return DFU_REQUIRES_SOFTDEVICE || update_requires_softdevice(p_init);
  420. }
  421. /**@brief Function to determine where to temporarily store the incoming firmware.
  422. * This also checks whether the update will fit, and deletes existing
  423. * firmware to make room for the new firmware.
  424. *
  425. * @param[in] p_init Init command.
  426. * @param[in] fw_size The size of the incoming firmware.
  427. * @param[out] p_addr The address at which to initially store the firmware.
  428. *
  429. * @retval NRF_DFU_RES_CODE_SUCCESS If the size check passed and
  430. * an address was found.
  431. * @retval NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES If the size check failed.
  432. */
  433. static nrf_dfu_result_t update_data_addr_get(dfu_init_command_t const * p_init,
  434. uint32_t fw_size,
  435. uint32_t * p_addr)
  436. {
  437. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  438. ret_code_t err_code = nrf_dfu_cache_prepare(fw_size,
  439. use_single_bank(p_init->type),
  440. NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES,
  441. keep_softdevice(p_init));
  442. if (err_code != NRF_SUCCESS)
  443. {
  444. NRF_LOG_ERROR("Can't find room for update");
  445. ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
  446. }
  447. else
  448. {
  449. *p_addr = nrf_dfu_bank1_start_addr();
  450. NRF_LOG_DEBUG("Write address set to 0x%08x", *p_addr);
  451. }
  452. return ret_val;
  453. }
  454. nrf_dfu_result_t nrf_dfu_validation_prevalidate(void)
  455. {
  456. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  457. dfu_command_t const * p_command = &m_packet.command;
  458. dfu_signature_type_t signature_type = DFU_SIGNATURE_TYPE_MIN;
  459. uint8_t const * p_signature = NULL;
  460. uint32_t signature_len = 0;
  461. if (m_packet.has_signed_command)
  462. {
  463. p_command = &m_packet.signed_command.command;
  464. signature_type = m_packet.signed_command.signature_type;
  465. p_signature = m_packet.signed_command.signature.bytes;
  466. signature_len = m_packet.signed_command.signature.size;
  467. }
  468. // Validate signature.
  469. if (signature_required(p_command->init.type))
  470. {
  471. ret_val = nrf_dfu_validation_signature_check(signature_type,
  472. p_signature,
  473. signature_len,
  474. m_init_packet_data_ptr,
  475. m_init_packet_data_len);
  476. }
  477. // Validate versions.
  478. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  479. {
  480. ret_val = nrf_dfu_ver_validation_check(&p_command->init);
  481. }
  482. if (ret_val != NRF_DFU_RES_CODE_SUCCESS)
  483. {
  484. NRF_LOG_WARNING("Prevalidation failed.");
  485. NRF_LOG_DEBUG("Init command:");
  486. NRF_LOG_HEXDUMP_DEBUG(m_init_packet_data_ptr, m_init_packet_data_len);
  487. }
  488. return ret_val;
  489. }
  490. nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
  491. uint32_t * p_data_len)
  492. {
  493. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  494. if (s_dfu_settings.progress.command_offset != s_dfu_settings.progress.command_size)
  495. {
  496. // The object wasn't the right (requested) size.
  497. NRF_LOG_ERROR("Execute with faulty offset");
  498. ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
  499. }
  500. else if (m_valid_init_cmd_present)
  501. {
  502. *p_dst_data_addr = nrf_dfu_bank1_start_addr();
  503. ret_val = update_data_size_get(mp_init, p_data_len);
  504. }
  505. else if (stored_init_cmd_decode())
  506. {
  507. // Will only get here if init command was received since last reset.
  508. // An init command should not be written to flash until after it's been checked here.
  509. ret_val = nrf_dfu_validation_prevalidate();
  510. *p_dst_data_addr = 0;
  511. *p_data_len = 0;
  512. // Get size of binary.
  513. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  514. {
  515. ret_val = update_data_size_get(mp_init, p_data_len);
  516. }
  517. // Get address where to flash the binary.
  518. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  519. {
  520. ret_val = update_data_addr_get(mp_init, *p_data_len, p_dst_data_addr);
  521. }
  522. // Set flag validating the init command.
  523. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  524. {
  525. m_valid_init_cmd_present = true;
  526. }
  527. else
  528. {
  529. dfu_progress_reset();
  530. }
  531. }
  532. else
  533. {
  534. NRF_LOG_ERROR("Failed to decode init packet");
  535. ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
  536. }
  537. return ret_val;
  538. }
  539. // Function to check the hash received in the init command against the received firmware.
  540. // little_endian specifies the endianness of @p p_hash.
  541. static bool nrf_dfu_validation_hash_ok(uint8_t const * p_hash, uint32_t src_addr, uint32_t data_len, bool little_endian)
  542. {
  543. ret_code_t err_code;
  544. bool result = true;
  545. uint8_t hash_be[NRF_CRYPTO_HASH_SIZE_SHA256];
  546. size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
  547. nrf_crypto_hash_context_t hash_context = {0};
  548. crypto_init();
  549. if (little_endian)
  550. {
  551. // Convert to hash to big-endian format for use in nrf_crypto.
  552. nrf_crypto_internal_swap_endian(hash_be,
  553. p_hash,
  554. NRF_CRYPTO_HASH_SIZE_SHA256);
  555. p_hash = hash_be;
  556. }
  557. NRF_LOG_DEBUG("Hash verification. start address: 0x%x, size: 0x%x",
  558. src_addr,
  559. data_len);
  560. err_code = nrf_crypto_hash_calculate(&hash_context,
  561. &g_nrf_crypto_hash_sha256_info,
  562. (uint8_t*)src_addr,
  563. data_len,
  564. m_fw_hash,
  565. &hash_len);
  566. if (err_code != NRF_SUCCESS)
  567. {
  568. NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code);
  569. result = false;
  570. }
  571. else if (memcmp(m_fw_hash, p_hash, NRF_CRYPTO_HASH_SIZE_SHA256) != 0)
  572. {
  573. NRF_LOG_WARNING("Hash verification failed.");
  574. NRF_LOG_DEBUG("Expected FW hash:")
  575. NRF_LOG_HEXDUMP_DEBUG(p_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
  576. NRF_LOG_DEBUG("Actual FW hash:")
  577. NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
  578. NRF_LOG_FLUSH();
  579. result = false;
  580. }
  581. return result;
  582. }
  583. // Function to check the hash received in the init command against the received firmware.
  584. bool fw_hash_ok(dfu_init_command_t const * p_init, uint32_t fw_start_addr, uint32_t fw_size)
  585. {
  586. ASSERT(p_init != NULL);
  587. return nrf_dfu_validation_hash_ok((uint8_t *)p_init->hash.hash.bytes, fw_start_addr, fw_size, true);
  588. }
  589. // Function to check whether the update contains a SoftDevice and, if so, if it is of a different
  590. // major version than the existing SoftDevice.
  591. static bool is_major_softdevice_update(uint32_t new_sd_addr)
  592. {
  593. // True if there is no SD right now, but there is a new one coming. This counts as a major update.
  594. bool result = !SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER);
  595. if (SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER))
  596. {
  597. // Both SoftDevices are present.
  598. uint32_t current_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(MBR_SIZE));
  599. uint32_t new_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(new_sd_addr));
  600. result = (current_SD_major != new_SD_major);
  601. NRF_LOG_INFO("SoftDevice update is a %s version update. Current: %d. New: %d.",
  602. result ? "major" : "minor",
  603. current_SD_major,
  604. new_SD_major);
  605. }
  606. return result;
  607. }
  608. /**@brief Validate the SoftDevice size and magic number in structure found at 0x2000 in received SoftDevice.
  609. *
  610. * @param[in] sd_start_addr Start address of received SoftDevice.
  611. * @param[in] sd_size Size of received SoftDevice in bytes.
  612. */
  613. static bool softdevice_info_ok(uint32_t sd_start_addr, uint32_t sd_size)
  614. {
  615. bool result = true;
  616. if (SD_MAGIC_NUMBER_GET(sd_start_addr) != SD_MAGIC_NUMBER)
  617. {
  618. NRF_LOG_ERROR("The SoftDevice does not contain the magic number identifying it as a SoftDevice.");
  619. result = false;
  620. }
  621. else if (SD_SIZE_GET(sd_start_addr) < ALIGN_TO_PAGE(sd_size + MBR_SIZE))
  622. {
  623. // The size in the info struct should be rounded up to a page boundary
  624. // and be larger than the actual size + the size of the MBR.
  625. NRF_LOG_ERROR("The SoftDevice size in the info struct is too small compared with the size reported in the init command.");
  626. result = false;
  627. }
  628. return result;
  629. }
  630. static bool boot_validation_extract(boot_validation_t * p_boot_validation,
  631. dfu_init_command_t const * p_init,
  632. uint32_t index,
  633. uint32_t start_addr,
  634. uint32_t data_len,
  635. boot_validation_type_t default_type)
  636. {
  637. ret_code_t err_code;
  638. size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
  639. nrf_crypto_hash_context_t hash_context = {0};
  640. memset(p_boot_validation, 0, sizeof(boot_validation_t));
  641. p_boot_validation->type = (p_init->boot_validation_count > index)
  642. ? (boot_validation_type_t)p_init->boot_validation[index].type
  643. : default_type; // default
  644. switch(p_boot_validation->type)
  645. {
  646. case NO_VALIDATION:
  647. break;
  648. case VALIDATE_CRC:
  649. *(uint32_t *)&p_boot_validation->bytes[0] = crc32_compute((uint8_t *)start_addr, data_len, NULL);
  650. break;
  651. case VALIDATE_SHA256:
  652. err_code = nrf_crypto_hash_calculate(&hash_context,
  653. &g_nrf_crypto_hash_sha256_info,
  654. (uint8_t*)start_addr,
  655. data_len,
  656. p_boot_validation->bytes,
  657. &hash_len);
  658. if (err_code != NRF_SUCCESS)
  659. {
  660. NRF_LOG_ERROR("nrf_crypto_hash_calculate() failed with error %s", nrf_strerror_get(err_code));
  661. return false;
  662. }
  663. break;
  664. case VALIDATE_ECDSA_P256_SHA256:
  665. memcpy(p_boot_validation->bytes, p_init->boot_validation[index].bytes.bytes, p_init->boot_validation[index].bytes.size);
  666. break;
  667. default:
  668. NRF_LOG_ERROR("Invalid boot validation type: %d", p_boot_validation->type);
  669. return false;
  670. }
  671. return nrf_dfu_validation_boot_validate(p_boot_validation, start_addr, data_len);
  672. }
  673. // The is_trusted argument specifies whether the function should have side effects.
  674. static bool postvalidate_app(dfu_init_command_t const * p_init, uint32_t src_addr, uint32_t data_len, bool is_trusted)
  675. {
  676. boot_validation_t boot_validation;
  677. ASSERT(p_init->type == DFU_FW_TYPE_APPLICATION);
  678. if (!boot_validation_extract(&boot_validation, p_init, 0, src_addr, data_len, VALIDATE_CRC))
  679. {
  680. return false;
  681. }
  682. #if !NRF_DFU_IN_APP
  683. else if (NRF_BL_APP_SIGNATURE_CHECK_REQUIRED &&
  684. (boot_validation.type != VALIDATE_ECDSA_P256_SHA256))
  685. {
  686. NRF_LOG_WARNING("The boot validation of the app must be a signature check.");
  687. return false;
  688. }
  689. #endif
  690. if (!is_trusted)
  691. {
  692. return true;
  693. }
  694. memcpy(&s_dfu_settings.boot_validation_app, &boot_validation, sizeof(boot_validation));
  695. s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
  696. NRF_LOG_DEBUG("Invalidating old application in bank 0.");
  697. s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
  698. if (!DFU_REQUIRES_SOFTDEVICE && !update_requires_softdevice(p_init))
  699. {
  700. // App does not need SD, so it should be placed where SD is.
  701. nrf_dfu_softdevice_invalidate();
  702. }
  703. if (!NRF_DFU_DEBUG ||
  704. (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
  705. {
  706. s_dfu_settings.app_version = p_init->fw_version;
  707. }
  708. return true;
  709. }
  710. // Function to check a received SoftDevice or Bootloader firmware, or both,
  711. // before it is copied into place.
  712. // The is_trusted argument specifies whether the function should have side effects.
  713. static bool postvalidate_sd_bl(dfu_init_command_t const * p_init,
  714. bool with_sd,
  715. bool with_bl,
  716. uint32_t start_addr,
  717. uint32_t data_len,
  718. bool is_trusted)
  719. {
  720. boot_validation_t boot_validation_sd = {NO_VALIDATION};
  721. boot_validation_t boot_validation_bl = {NO_VALIDATION};
  722. uint32_t bl_start = start_addr;
  723. uint32_t bl_size = data_len;
  724. ASSERT(with_sd || with_bl);
  725. if (with_sd)
  726. {
  727. if (!softdevice_info_ok(start_addr, p_init->sd_size))
  728. {
  729. return false;
  730. }
  731. if (is_major_softdevice_update(start_addr))
  732. {
  733. NRF_LOG_WARNING("Invalidating app because it is incompatible with the SoftDevice.");
  734. if (DFU_REQUIRES_SOFTDEVICE && !with_bl)
  735. {
  736. NRF_LOG_ERROR("Major SD update but no BL. Abort to avoid incapacitating the BL.");
  737. return false;
  738. }
  739. }
  740. if (!boot_validation_extract(&boot_validation_sd, p_init, 0, start_addr, p_init->sd_size, VALIDATE_CRC))
  741. {
  742. return false;
  743. }
  744. bl_start += p_init->sd_size;
  745. bl_size -= p_init->sd_size;
  746. }
  747. if (with_bl)
  748. {
  749. if (!boot_validation_extract(&boot_validation_bl, p_init, 0, bl_start, bl_size, NO_VALIDATION))
  750. {
  751. return false;
  752. }
  753. else if (boot_validation_bl.type != NO_VALIDATION)
  754. {
  755. NRF_LOG_WARNING("Boot validation of bootloader is not supported and will be ignored.");
  756. }
  757. }
  758. if (!is_trusted)
  759. {
  760. return true;
  761. }
  762. if (with_sd)
  763. {
  764. if (is_major_softdevice_update(start_addr))
  765. {
  766. // Invalidate app since it may not be compatible with new SD.
  767. nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
  768. }
  769. memcpy(&s_dfu_settings.boot_validation_softdevice, &boot_validation_sd, sizeof(boot_validation_sd));
  770. // Mark the update as valid.
  771. s_dfu_settings.bank_1.bank_code = with_bl ? NRF_DFU_BANK_VALID_SD_BL
  772. : NRF_DFU_BANK_VALID_SD;
  773. s_dfu_settings.sd_size = p_init->sd_size;
  774. }
  775. else
  776. {
  777. s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_BL;
  778. }
  779. if (with_bl)
  780. {
  781. memcpy(&s_dfu_settings.boot_validation_bootloader, &boot_validation_bl, sizeof(boot_validation_bl));
  782. if (!NRF_DFU_DEBUG ||
  783. (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
  784. {
  785. // If the update contains a bootloader, update the version.
  786. // Unless the update is a debug packet.
  787. s_dfu_settings.bootloader_version = p_init->fw_version;
  788. }
  789. }
  790. return true;
  791. }
  792. bool nrf_dfu_validation_boot_validate(boot_validation_t const * p_validation, uint32_t data_addr, uint32_t data_len)
  793. {
  794. uint8_t const * p_data = (uint8_t*) data_addr;
  795. switch(p_validation->type)
  796. {
  797. case NO_VALIDATION:
  798. return true;
  799. case VALIDATE_CRC:
  800. {
  801. uint32_t current_crc = *(uint32_t *)p_validation->bytes;
  802. uint32_t crc = crc32_compute(p_data, data_len, NULL);
  803. if (crc != current_crc)
  804. {
  805. // CRC does not match with what is stored.
  806. NRF_LOG_DEBUG("CRC check of app failed. Return %d", NRF_DFU_DEBUG);
  807. return NRF_DFU_DEBUG;
  808. }
  809. return true;
  810. }
  811. case VALIDATE_SHA256:
  812. return nrf_dfu_validation_hash_ok(p_validation->bytes, data_addr, data_len, false);
  813. case VALIDATE_ECDSA_P256_SHA256:
  814. {
  815. nrf_dfu_result_t res_code = nrf_dfu_validation_signature_check(
  816. DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256,
  817. p_validation->bytes,
  818. NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE,
  819. p_data,
  820. data_len);
  821. return (res_code == NRF_DFU_RES_CODE_SUCCESS);
  822. }
  823. default:
  824. ASSERT(false);
  825. return false;
  826. }
  827. }
  828. nrf_dfu_result_t postvalidate(uint32_t data_addr, uint32_t data_len, bool is_trusted)
  829. {
  830. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  831. dfu_init_command_t const * p_init = mp_init;
  832. if (!fw_hash_ok(p_init, data_addr, data_len))
  833. {
  834. ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_VERIFICATION_FAILED);
  835. }
  836. else
  837. {
  838. if (p_init->type == DFU_FW_TYPE_APPLICATION)
  839. {
  840. if (!postvalidate_app(p_init, data_addr, data_len, is_trusted))
  841. {
  842. ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
  843. }
  844. }
  845. #if NRF_DFU_SUPPORTS_EXTERNAL_APP
  846. else if (p_init->type == DFU_FW_TYPE_EXTERNAL_APPLICATION)
  847. {
  848. if (!is_trusted)
  849. {
  850. // This function must be implemented externally
  851. ret_val = nrf_dfu_validation_post_external_app_execute(p_init, is_trusted);
  852. }
  853. else
  854. {
  855. s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_EXT_APP;
  856. }
  857. }
  858. #endif // NRF_DFU_SUPPORTS_EXTERNAL_APP
  859. else
  860. {
  861. bool with_sd = p_init->type & DFU_FW_TYPE_SOFTDEVICE;
  862. bool with_bl = p_init->type & DFU_FW_TYPE_BOOTLOADER;
  863. if (!postvalidate_sd_bl(p_init, with_sd, with_bl, data_addr, data_len, is_trusted))
  864. {
  865. ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
  866. if (is_trusted && with_sd && !DFU_REQUIRES_SOFTDEVICE &&
  867. (data_addr == nrf_dfu_softdevice_start_address()))
  868. {
  869. nrf_dfu_softdevice_invalidate();
  870. }
  871. }
  872. }
  873. }
  874. if (!is_trusted)
  875. {
  876. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  877. {
  878. s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
  879. }
  880. else
  881. {
  882. dfu_progress_reset();
  883. }
  884. }
  885. else
  886. {
  887. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  888. {
  889. // Mark the update as complete and valid.
  890. s_dfu_settings.bank_1.image_crc = crc32_compute((uint8_t *)data_addr, data_len, NULL);
  891. s_dfu_settings.bank_1.image_size = data_len;
  892. }
  893. else
  894. {
  895. nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
  896. }
  897. dfu_progress_reset();
  898. s_dfu_settings.progress.update_start_address = data_addr;
  899. }
  900. return ret_val;
  901. }
  902. nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t data_addr, uint32_t data_len)
  903. {
  904. return postvalidate(data_addr, data_len, false);
  905. }
  906. nrf_dfu_result_t nrf_dfu_validation_activation_prepare(uint32_t data_addr, uint32_t data_len)
  907. {
  908. return postvalidate(data_addr, data_len, true);
  909. }
  910. bool nrf_dfu_validation_valid_external_app(void)
  911. {
  912. return s_dfu_settings.bank_1.bank_code == NRF_DFU_BANK_VALID_EXT_APP;
  913. }