nrf_dfu_validation.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. /**
  2. * Copyright (c) 2017 - 2020, 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. nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size)
  213. {
  214. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  215. if (size == 0)
  216. {
  217. ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
  218. }
  219. else if (size > INIT_COMMAND_MAX_SIZE)
  220. {
  221. ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
  222. }
  223. else
  224. {
  225. // Set DFU to uninitialized.
  226. m_valid_init_cmd_present = false;
  227. // Reset all progress.
  228. nrf_dfu_settings_progress_reset();
  229. // Set the init command size.
  230. s_dfu_settings.progress.command_size = size;
  231. }
  232. return ret_val;
  233. }
  234. nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length)
  235. {
  236. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  237. if ((length + s_dfu_settings.progress.command_offset) > s_dfu_settings.progress.command_size)
  238. {
  239. NRF_LOG_ERROR("Init command larger than expected.");
  240. ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
  241. }
  242. else
  243. {
  244. // Copy the received data to RAM, update offset and calculate CRC.
  245. memcpy(&s_dfu_settings.init_command[s_dfu_settings.progress.command_offset],
  246. p_data,
  247. length);
  248. s_dfu_settings.progress.command_offset += length;
  249. s_dfu_settings.progress.command_crc = crc32_compute(p_data,
  250. length,
  251. &s_dfu_settings.progress.command_crc);
  252. }
  253. return ret_val;
  254. }
  255. void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
  256. uint32_t * p_crc,
  257. uint32_t * p_max_size)
  258. {
  259. *p_offset = s_dfu_settings.progress.command_offset;
  260. *p_crc = s_dfu_settings.progress.command_crc;
  261. *p_max_size = INIT_COMMAND_MAX_SIZE;
  262. }
  263. bool nrf_dfu_validation_init_cmd_present(void)
  264. {
  265. return m_valid_init_cmd_present;
  266. }
  267. // Function determines if init command signature is obligatory.
  268. static bool signature_required(dfu_fw_type_t fw_type_to_be_updated)
  269. {
  270. bool result = true;
  271. // DFU_FW_TYPE_EXTERNAL_APPLICATION and bootloader updates always require
  272. // signature check
  273. if ((!DFU_REQUIRES_SOFTDEVICE && (fw_type_to_be_updated == DFU_FW_TYPE_SOFTDEVICE)) ||
  274. (fw_type_to_be_updated == DFU_FW_TYPE_APPLICATION))
  275. {
  276. result = NRF_DFU_REQUIRE_SIGNED_APP_UPDATE;
  277. }
  278. return result;
  279. }
  280. // Function to perform signature check if required.
  281. static nrf_dfu_result_t nrf_dfu_validation_signature_check(dfu_signature_type_t signature_type,
  282. uint8_t const * p_signature,
  283. uint32_t signature_len,
  284. uint8_t const * p_data,
  285. uint32_t data_len)
  286. {
  287. ret_code_t err_code;
  288. size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
  289. nrf_crypto_hash_context_t hash_context = {0};
  290. nrf_crypto_ecdsa_verify_context_t verify_context = {0};
  291. crypto_init();
  292. NRF_LOG_INFO("Signature required. Checking signature.")
  293. if (p_signature == NULL)
  294. {
  295. NRF_LOG_WARNING("No signature found.");
  296. return EXT_ERR(NRF_DFU_EXT_ERROR_SIGNATURE_MISSING);
  297. }
  298. if (signature_type != DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256)
  299. {
  300. NRF_LOG_INFO("Invalid signature type");
  301. return EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE);
  302. }
  303. NRF_LOG_INFO("Calculating hash (len: %d)", data_len);
  304. err_code = nrf_crypto_hash_calculate(&hash_context,
  305. &g_nrf_crypto_hash_sha256_info,
  306. p_data,
  307. data_len,
  308. m_sig_hash,
  309. &hash_len);
  310. if (err_code != NRF_SUCCESS)
  311. {
  312. return NRF_DFU_RES_CODE_OPERATION_FAILED;
  313. }
  314. if (sizeof(m_signature) != signature_len)
  315. {
  316. return NRF_DFU_RES_CODE_OPERATION_FAILED;
  317. }
  318. // Prepare the signature received over the air.
  319. memcpy(m_signature, p_signature, signature_len);
  320. // Calculate the signature.
  321. NRF_LOG_INFO("Verify signature");
  322. // The signature is in little-endian format. Change it to big-endian format for nrf_crypto use.
  323. nrf_crypto_internal_double_swap_endian_in_place(m_signature, sizeof(m_signature) / 2);
  324. err_code = nrf_crypto_ecdsa_verify(&verify_context,
  325. &m_public_key,
  326. m_sig_hash,
  327. hash_len,
  328. m_signature,
  329. sizeof(m_signature));
  330. if (err_code != NRF_SUCCESS)
  331. {
  332. NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code);
  333. NRF_LOG_DEBUG("Signature:");
  334. NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature));
  335. NRF_LOG_DEBUG("Hash:");
  336. NRF_LOG_HEXDUMP_DEBUG(m_sig_hash, hash_len);
  337. NRF_LOG_DEBUG("Public Key:");
  338. NRF_LOG_HEXDUMP_DEBUG(pk, sizeof(pk));
  339. NRF_LOG_FLUSH();
  340. return NRF_DFU_RES_CODE_INVALID_OBJECT;
  341. }
  342. NRF_LOG_INFO("Image verified");
  343. return NRF_DFU_RES_CODE_SUCCESS;
  344. }
  345. // Function to calculate the total size of the firmware(s) in the update.
  346. static nrf_dfu_result_t update_data_size_get(dfu_init_command_t const * p_init, uint32_t * p_size)
  347. {
  348. nrf_dfu_result_t ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
  349. uint32_t fw_sz = 0;
  350. if ((p_init->type == DFU_FW_TYPE_APPLICATION ||
  351. p_init->type == DFU_FW_TYPE_EXTERNAL_APPLICATION) &&
  352. (p_init->has_app_size == true))
  353. {
  354. fw_sz = p_init->app_size;
  355. }
  356. else
  357. {
  358. if ((p_init->type & DFU_FW_TYPE_SOFTDEVICE) && (p_init->has_sd_size == true))
  359. {
  360. fw_sz = p_init->sd_size;
  361. }
  362. if ((p_init->type & DFU_FW_TYPE_BOOTLOADER) && (p_init->has_bl_size == true))
  363. {
  364. if (p_init->bl_size <= BOOTLOADER_SIZE)
  365. {
  366. fw_sz += p_init->bl_size;
  367. }
  368. else
  369. {
  370. NRF_LOG_ERROR("BL size (%d) over limit (%d)", p_init->bl_size, BOOTLOADER_SIZE);
  371. fw_sz = 0;
  372. ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
  373. }
  374. }
  375. }
  376. if (fw_sz)
  377. {
  378. *p_size = fw_sz;
  379. ret_val = NRF_DFU_RES_CODE_SUCCESS;
  380. }
  381. else
  382. {
  383. NRF_LOG_ERROR("Init packet does not contain valid firmware size");
  384. }
  385. return ret_val;
  386. }
  387. /**
  388. * @brief Function to check if single bank update should be used.
  389. *
  390. * @param new_fw_type Firmware type.
  391. */
  392. static bool use_single_bank(dfu_fw_type_t new_fw_type)
  393. {
  394. bool result = false;
  395. // DFU_FW_TYPE_EXTERNAL_APPLICATION never uses single bank
  396. if (((new_fw_type == DFU_FW_TYPE_APPLICATION) ||
  397. (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)) &&
  398. NRF_DFU_SINGLE_BANK_APP_UPDATES)
  399. {
  400. result = true;
  401. }
  402. return result;
  403. }
  404. // Function to determine whether the new firmware needs a SoftDevice to be present.
  405. static bool update_requires_softdevice(dfu_init_command_t const * p_init)
  406. {
  407. return ((p_init->sd_req_count > 0) && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD));
  408. }
  409. // Function to determine whether the SoftDevice can be removed during the update or not.
  410. static bool keep_softdevice(dfu_init_command_t const * p_init)
  411. {
  412. UNUSED_PARAMETER(p_init); // It's unused when DFU_REQUIRES_SOFTDEVICE is true.
  413. return DFU_REQUIRES_SOFTDEVICE || update_requires_softdevice(p_init);
  414. }
  415. /**@brief Function to determine where to temporarily store the incoming firmware.
  416. * This also checks whether the update will fit, and deletes existing
  417. * firmware to make room for the new firmware.
  418. *
  419. * @param[in] p_init Init command.
  420. * @param[in] fw_size The size of the incoming firmware.
  421. * @param[out] p_addr The address at which to initially store the firmware.
  422. *
  423. * @retval NRF_DFU_RES_CODE_SUCCESS If the size check passed and
  424. * an address was found.
  425. * @retval NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES If the size check failed.
  426. */
  427. static nrf_dfu_result_t update_data_addr_get(dfu_init_command_t const * p_init,
  428. uint32_t fw_size,
  429. uint32_t * p_addr)
  430. {
  431. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  432. ret_code_t err_code = nrf_dfu_cache_prepare(fw_size,
  433. use_single_bank(p_init->type),
  434. NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES,
  435. keep_softdevice(p_init));
  436. if (err_code != NRF_SUCCESS)
  437. {
  438. NRF_LOG_ERROR("Can't find room for update");
  439. ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
  440. }
  441. else
  442. {
  443. *p_addr = nrf_dfu_bank1_start_addr();
  444. NRF_LOG_DEBUG("Write address set to 0x%08x", *p_addr);
  445. }
  446. return ret_val;
  447. }
  448. nrf_dfu_result_t nrf_dfu_validation_prevalidate(void)
  449. {
  450. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  451. dfu_command_t const * p_command = &m_packet.command;
  452. dfu_signature_type_t signature_type = DFU_SIGNATURE_TYPE_MIN;
  453. uint8_t const * p_signature = NULL;
  454. uint32_t signature_len = 0;
  455. if (m_packet.has_signed_command)
  456. {
  457. p_command = &m_packet.signed_command.command;
  458. signature_type = m_packet.signed_command.signature_type;
  459. p_signature = m_packet.signed_command.signature.bytes;
  460. signature_len = m_packet.signed_command.signature.size;
  461. }
  462. // Validate signature.
  463. if (signature_required(p_command->init.type))
  464. {
  465. ret_val = nrf_dfu_validation_signature_check(signature_type,
  466. p_signature,
  467. signature_len,
  468. m_init_packet_data_ptr,
  469. m_init_packet_data_len);
  470. }
  471. // Validate versions.
  472. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  473. {
  474. ret_val = nrf_dfu_ver_validation_check(&p_command->init);
  475. }
  476. if (ret_val != NRF_DFU_RES_CODE_SUCCESS)
  477. {
  478. NRF_LOG_WARNING("Prevalidation failed.");
  479. NRF_LOG_DEBUG("Init command:");
  480. NRF_LOG_HEXDUMP_DEBUG(m_init_packet_data_ptr, m_init_packet_data_len);
  481. }
  482. return ret_val;
  483. }
  484. nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
  485. uint32_t * p_data_len)
  486. {
  487. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  488. if (s_dfu_settings.progress.command_offset != s_dfu_settings.progress.command_size)
  489. {
  490. // The object wasn't the right (requested) size.
  491. NRF_LOG_ERROR("Execute with faulty offset");
  492. ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
  493. }
  494. else if (m_valid_init_cmd_present)
  495. {
  496. *p_dst_data_addr = nrf_dfu_bank1_start_addr();
  497. ret_val = update_data_size_get(mp_init, p_data_len);
  498. }
  499. else if (stored_init_cmd_decode())
  500. {
  501. // Will only get here if init command was received since last reset.
  502. // An init command should not be written to flash until after it's been checked here.
  503. ret_val = nrf_dfu_validation_prevalidate();
  504. *p_dst_data_addr = 0;
  505. *p_data_len = 0;
  506. // Get size of binary.
  507. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  508. {
  509. ret_val = update_data_size_get(mp_init, p_data_len);
  510. }
  511. // Get address where to flash the binary.
  512. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  513. {
  514. ret_val = update_data_addr_get(mp_init, *p_data_len, p_dst_data_addr);
  515. }
  516. // Set flag validating the init command.
  517. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  518. {
  519. m_valid_init_cmd_present = true;
  520. }
  521. else
  522. {
  523. nrf_dfu_settings_progress_reset();
  524. }
  525. }
  526. else
  527. {
  528. NRF_LOG_ERROR("Failed to decode init packet");
  529. ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
  530. }
  531. return ret_val;
  532. }
  533. // Function to check the hash received in the init command against the received firmware.
  534. // little_endian specifies the endianness of @p p_hash.
  535. static bool nrf_dfu_validation_hash_ok(uint8_t const * p_hash, uint32_t src_addr, uint32_t data_len, bool little_endian)
  536. {
  537. ret_code_t err_code;
  538. bool result = true;
  539. uint8_t hash_be[NRF_CRYPTO_HASH_SIZE_SHA256];
  540. size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
  541. nrf_crypto_hash_context_t hash_context = {0};
  542. crypto_init();
  543. if (little_endian)
  544. {
  545. // Convert to hash to big-endian format for use in nrf_crypto.
  546. nrf_crypto_internal_swap_endian(hash_be,
  547. p_hash,
  548. NRF_CRYPTO_HASH_SIZE_SHA256);
  549. p_hash = hash_be;
  550. }
  551. NRF_LOG_DEBUG("Hash verification. start address: 0x%x, size: 0x%x",
  552. src_addr,
  553. data_len);
  554. err_code = nrf_crypto_hash_calculate(&hash_context,
  555. &g_nrf_crypto_hash_sha256_info,
  556. (uint8_t*)src_addr,
  557. data_len,
  558. m_fw_hash,
  559. &hash_len);
  560. if (err_code != NRF_SUCCESS)
  561. {
  562. NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code);
  563. result = false;
  564. }
  565. else if (memcmp(m_fw_hash, p_hash, NRF_CRYPTO_HASH_SIZE_SHA256) != 0)
  566. {
  567. NRF_LOG_WARNING("Hash verification failed.");
  568. NRF_LOG_DEBUG("Expected FW hash:")
  569. NRF_LOG_HEXDUMP_DEBUG(p_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
  570. NRF_LOG_DEBUG("Actual FW hash:")
  571. NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
  572. NRF_LOG_FLUSH();
  573. result = false;
  574. }
  575. return result;
  576. }
  577. // Function to check the hash received in the init command against the received firmware.
  578. bool fw_hash_ok(dfu_init_command_t const * p_init, uint32_t fw_start_addr, uint32_t fw_size)
  579. {
  580. ASSERT(p_init != NULL);
  581. return nrf_dfu_validation_hash_ok((uint8_t *)p_init->hash.hash.bytes, fw_start_addr, fw_size, true);
  582. }
  583. // Function to check whether the update contains a SoftDevice and, if so, if it is of a different
  584. // major version than the existing SoftDevice.
  585. static bool is_major_softdevice_update(uint32_t new_sd_addr)
  586. {
  587. // True if there is no SD right now, but there is a new one coming. This counts as a major update.
  588. bool result = !SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER);
  589. if (SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER))
  590. {
  591. // Both SoftDevices are present.
  592. uint32_t current_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(MBR_SIZE));
  593. uint32_t new_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(new_sd_addr));
  594. result = (current_SD_major != new_SD_major);
  595. NRF_LOG_INFO("SoftDevice update is a %s version update. Current: %d. New: %d.",
  596. result ? "major" : "minor",
  597. current_SD_major,
  598. new_SD_major);
  599. }
  600. return result;
  601. }
  602. /**@brief Validate the SoftDevice size and magic number in structure found at 0x2000 in received SoftDevice.
  603. *
  604. * @param[in] sd_start_addr Start address of received SoftDevice.
  605. * @param[in] sd_size Size of received SoftDevice in bytes.
  606. */
  607. static bool softdevice_info_ok(uint32_t sd_start_addr, uint32_t sd_size)
  608. {
  609. bool result = true;
  610. if (SD_MAGIC_NUMBER_GET(sd_start_addr) != SD_MAGIC_NUMBER)
  611. {
  612. NRF_LOG_ERROR("The SoftDevice does not contain the magic number identifying it as a SoftDevice.");
  613. result = false;
  614. }
  615. else if (SD_SIZE_GET(sd_start_addr) < ALIGN_TO_PAGE(sd_size + MBR_SIZE))
  616. {
  617. // The size in the info struct should be rounded up to a page boundary
  618. // and be larger than the actual size + the size of the MBR.
  619. NRF_LOG_ERROR("The SoftDevice size in the info struct is too small compared with the size reported in the init command.");
  620. result = false;
  621. }
  622. else if (SD_PRESENT && (SD_ID_GET(MBR_SIZE) != SD_ID_GET(sd_start_addr)))
  623. {
  624. NRF_LOG_ERROR("The new SoftDevice is of a different family than the present SoftDevice. Compatibility cannot be guaranteed.");
  625. result = false;
  626. }
  627. return result;
  628. }
  629. static bool boot_validation_extract(boot_validation_t * p_boot_validation,
  630. dfu_init_command_t const * p_init,
  631. uint32_t index,
  632. uint32_t start_addr,
  633. uint32_t data_len,
  634. boot_validation_type_t default_type)
  635. {
  636. ret_code_t err_code;
  637. size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
  638. nrf_crypto_hash_context_t hash_context = {0};
  639. memset(p_boot_validation, 0, sizeof(boot_validation_t));
  640. p_boot_validation->type = (p_init->boot_validation_count > index)
  641. ? (boot_validation_type_t)p_init->boot_validation[index].type
  642. : default_type; // default
  643. switch(p_boot_validation->type)
  644. {
  645. case NO_VALIDATION:
  646. break;
  647. case VALIDATE_CRC:
  648. *(uint32_t *)&p_boot_validation->bytes[0] = crc32_compute((uint8_t *)start_addr, data_len, NULL);
  649. break;
  650. case VALIDATE_SHA256:
  651. err_code = nrf_crypto_hash_calculate(&hash_context,
  652. &g_nrf_crypto_hash_sha256_info,
  653. (uint8_t*)start_addr,
  654. data_len,
  655. p_boot_validation->bytes,
  656. &hash_len);
  657. if (err_code != NRF_SUCCESS)
  658. {
  659. NRF_LOG_ERROR("nrf_crypto_hash_calculate() failed with error %s", nrf_strerror_get(err_code));
  660. return false;
  661. }
  662. break;
  663. case VALIDATE_ECDSA_P256_SHA256:
  664. memcpy(p_boot_validation->bytes, p_init->boot_validation[index].bytes.bytes, p_init->boot_validation[index].bytes.size);
  665. break;
  666. default:
  667. NRF_LOG_ERROR("Invalid boot validation type: %d", p_boot_validation->type);
  668. return false;
  669. }
  670. return nrf_dfu_validation_boot_validate(p_boot_validation, start_addr, data_len);
  671. }
  672. // The is_trusted argument specifies whether the function should have side effects.
  673. static bool postvalidate_app(dfu_init_command_t const * p_init, uint32_t src_addr, uint32_t data_len, bool is_trusted)
  674. {
  675. boot_validation_t boot_validation;
  676. ASSERT(p_init->type == DFU_FW_TYPE_APPLICATION);
  677. if (!boot_validation_extract(&boot_validation, p_init, 0, src_addr, data_len, VALIDATE_CRC))
  678. {
  679. return false;
  680. }
  681. #if !NRF_DFU_IN_APP
  682. else if (NRF_BL_APP_SIGNATURE_CHECK_REQUIRED &&
  683. (boot_validation.type != VALIDATE_ECDSA_P256_SHA256))
  684. {
  685. NRF_LOG_WARNING("The boot validation of the app must be a signature check.");
  686. return false;
  687. }
  688. #endif
  689. if (!is_trusted)
  690. {
  691. return true;
  692. }
  693. memcpy(&s_dfu_settings.boot_validation_app, &boot_validation, sizeof(boot_validation));
  694. s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
  695. NRF_LOG_DEBUG("Invalidating old application in bank 0.");
  696. s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
  697. if (!DFU_REQUIRES_SOFTDEVICE && !update_requires_softdevice(p_init))
  698. {
  699. // App does not need SD, so it should be placed where SD is.
  700. nrf_dfu_softdevice_invalidate();
  701. }
  702. if (!NRF_DFU_DEBUG ||
  703. (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
  704. {
  705. s_dfu_settings.app_version = p_init->fw_version;
  706. }
  707. return true;
  708. }
  709. // Function to check a received SoftDevice or Bootloader firmware, or both,
  710. // before it is copied into place.
  711. // The is_trusted argument specifies whether the function should have side effects.
  712. static bool postvalidate_sd_bl(dfu_init_command_t const * p_init,
  713. bool with_sd,
  714. bool with_bl,
  715. uint32_t start_addr,
  716. uint32_t data_len,
  717. bool is_trusted)
  718. {
  719. boot_validation_t boot_validation_sd = {NO_VALIDATION};
  720. boot_validation_t boot_validation_bl = {NO_VALIDATION};
  721. uint32_t bl_start = start_addr;
  722. uint32_t bl_size = data_len;
  723. ASSERT(with_sd || with_bl);
  724. if (with_sd)
  725. {
  726. if (!softdevice_info_ok(start_addr, p_init->sd_size))
  727. {
  728. return false;
  729. }
  730. if (is_major_softdevice_update(start_addr))
  731. {
  732. NRF_LOG_WARNING("Invalidating app because it is incompatible with the SoftDevice.");
  733. if (DFU_REQUIRES_SOFTDEVICE && !with_bl)
  734. {
  735. NRF_LOG_ERROR("Major SD update but no BL. Abort to avoid incapacitating the BL.");
  736. return false;
  737. }
  738. }
  739. if (!boot_validation_extract(&boot_validation_sd, p_init, 0, start_addr, p_init->sd_size, VALIDATE_CRC))
  740. {
  741. return false;
  742. }
  743. bl_start += p_init->sd_size;
  744. bl_size -= p_init->sd_size;
  745. }
  746. if (with_bl)
  747. {
  748. if (!boot_validation_extract(&boot_validation_bl, p_init, with_sd ? 1 : 0, bl_start, bl_size, NO_VALIDATION))
  749. {
  750. return false;
  751. }
  752. else if (boot_validation_bl.type != NO_VALIDATION)
  753. {
  754. NRF_LOG_WARNING("Boot validation of bootloader is not supported and will be ignored.");
  755. }
  756. }
  757. if (!is_trusted)
  758. {
  759. return true;
  760. }
  761. if (with_sd)
  762. {
  763. if (is_major_softdevice_update(start_addr))
  764. {
  765. // Invalidate app since it may not be compatible with new SD.
  766. nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
  767. }
  768. memcpy(&s_dfu_settings.boot_validation_softdevice, &boot_validation_sd, sizeof(boot_validation_sd));
  769. // Mark the update as valid.
  770. s_dfu_settings.bank_1.bank_code = with_bl ? NRF_DFU_BANK_VALID_SD_BL
  771. : NRF_DFU_BANK_VALID_SD;
  772. s_dfu_settings.sd_size = p_init->sd_size;
  773. }
  774. else
  775. {
  776. s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_BL;
  777. }
  778. if (with_bl)
  779. {
  780. memcpy(&s_dfu_settings.boot_validation_bootloader, &boot_validation_bl, sizeof(boot_validation_bl));
  781. if (!NRF_DFU_DEBUG ||
  782. (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
  783. {
  784. // If the update contains a bootloader, update the version.
  785. // Unless the update is a debug packet.
  786. s_dfu_settings.bootloader_version = p_init->fw_version;
  787. }
  788. }
  789. return true;
  790. }
  791. bool nrf_dfu_validation_boot_validate(boot_validation_t const * p_validation, uint32_t data_addr, uint32_t data_len)
  792. {
  793. uint8_t const * p_data = (uint8_t*) data_addr;
  794. switch(p_validation->type)
  795. {
  796. case NO_VALIDATION:
  797. return true;
  798. case VALIDATE_CRC:
  799. {
  800. uint32_t current_crc = *(uint32_t *)p_validation->bytes;
  801. uint32_t crc = crc32_compute(p_data, data_len, NULL);
  802. if (crc != current_crc)
  803. {
  804. // CRC does not match with what is stored.
  805. NRF_LOG_DEBUG("CRC check of app failed. Return %d", NRF_DFU_DEBUG);
  806. return NRF_DFU_DEBUG;
  807. }
  808. return true;
  809. }
  810. case VALIDATE_SHA256:
  811. return nrf_dfu_validation_hash_ok(p_validation->bytes, data_addr, data_len, false);
  812. case VALIDATE_ECDSA_P256_SHA256:
  813. {
  814. nrf_dfu_result_t res_code = nrf_dfu_validation_signature_check(
  815. DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256,
  816. p_validation->bytes,
  817. NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE,
  818. p_data,
  819. data_len);
  820. return (res_code == NRF_DFU_RES_CODE_SUCCESS);
  821. }
  822. default:
  823. ASSERT(false);
  824. return false;
  825. }
  826. }
  827. nrf_dfu_result_t postvalidate(uint32_t data_addr, uint32_t data_len, bool is_trusted)
  828. {
  829. nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
  830. dfu_init_command_t const * p_init = mp_init;
  831. if (!fw_hash_ok(p_init, data_addr, data_len))
  832. {
  833. ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_VERIFICATION_FAILED);
  834. }
  835. else
  836. {
  837. if (p_init->type == DFU_FW_TYPE_APPLICATION)
  838. {
  839. if (!postvalidate_app(p_init, data_addr, data_len, is_trusted))
  840. {
  841. ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
  842. }
  843. }
  844. #if NRF_DFU_SUPPORTS_EXTERNAL_APP
  845. else if (p_init->type == DFU_FW_TYPE_EXTERNAL_APPLICATION)
  846. {
  847. if (!is_trusted)
  848. {
  849. // This function must be implemented externally
  850. ret_val = nrf_dfu_validation_post_external_app_execute(p_init, is_trusted);
  851. }
  852. else
  853. {
  854. s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_EXT_APP;
  855. }
  856. }
  857. #endif // NRF_DFU_SUPPORTS_EXTERNAL_APP
  858. else
  859. {
  860. bool with_sd = p_init->type & DFU_FW_TYPE_SOFTDEVICE;
  861. bool with_bl = p_init->type & DFU_FW_TYPE_BOOTLOADER;
  862. if (!postvalidate_sd_bl(p_init, with_sd, with_bl, data_addr, data_len, is_trusted))
  863. {
  864. ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
  865. if (is_trusted && with_sd && !DFU_REQUIRES_SOFTDEVICE &&
  866. (data_addr == nrf_dfu_softdevice_start_address()))
  867. {
  868. nrf_dfu_softdevice_invalidate();
  869. }
  870. }
  871. }
  872. }
  873. if (!is_trusted)
  874. {
  875. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  876. {
  877. s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
  878. }
  879. else
  880. {
  881. nrf_dfu_settings_progress_reset();
  882. }
  883. }
  884. else
  885. {
  886. if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
  887. {
  888. // Mark the update as complete and valid.
  889. s_dfu_settings.bank_1.image_crc = crc32_compute((uint8_t *)data_addr, data_len, NULL);
  890. s_dfu_settings.bank_1.image_size = data_len;
  891. }
  892. else
  893. {
  894. nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
  895. }
  896. nrf_dfu_settings_progress_reset();
  897. s_dfu_settings.progress.update_start_address = data_addr;
  898. }
  899. return ret_val;
  900. }
  901. nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t data_addr, uint32_t data_len)
  902. {
  903. return postvalidate(data_addr, data_len, false);
  904. }
  905. nrf_dfu_result_t nrf_dfu_validation_activation_prepare(uint32_t data_addr, uint32_t data_len)
  906. {
  907. return postvalidate(data_addr, data_len, true);
  908. }
  909. bool nrf_dfu_validation_valid_external_app(void)
  910. {
  911. return s_dfu_settings.bank_1.bank_code == NRF_DFU_BANK_VALID_EXT_APP;
  912. }