<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DFU firmware encryption</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/22375/dfu-firmware-encryption</link><description>Hi, 
 I would like to implement DFU with firmware encryption. I&amp;#39;m aware this isn&amp;#39;t present in SDK 12 and would like to modify the secured bootloader to implement it. 
 As far as I understand, a DFU package is a zip file containing a manifest, and sets</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 16 Jun 2017 04:47:36 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/22375/dfu-firmware-encryption" /><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87966?ContentTypeID=1</link><pubDate>Fri, 16 Jun 2017 04:47:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e167d394-1314-466c-8edf-095e19975889</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;I didn&amp;#39;t do anything that would affect the bin file size. You can try but you may need to apply more changes for it to work [unsure]. One thing to keep in mind also is the transfer can be resumed, so unless you want to kill that feature, you&amp;#39;ll need an encryption that makes this possible [my XOR one does, but it's not a proper encryption].
I did keep the private key signature, having it means during transfer I don&amp;#39;t have to worry about malleability of the chosen encryption algorithm as any tampering will be detected at signature checking.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87965?ContentTypeID=1</link><pubDate>Thu, 15 Jun 2017 19:36:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:069604e7-a770-437f-9e98-8c7d6daa0250</guid><dc:creator>SRA</dc:creator><description>&lt;p&gt;When you say keep the same size, did you pad your bins or while decrypting did you pad or did it just work out where that wasn&amp;#39;t needed?&lt;/p&gt;
&lt;p&gt;And just checking but did you keep the private key signature in the SecureDFU?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87977?ContentTypeID=1</link><pubDate>Thu, 15 Jun 2017 16:17:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:87517039-e046-46ad-9f2f-628904917d69</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;For encryption of firmware image only:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a static  boolean m_image_encryption&lt;/li&gt;
&lt;li&gt;In dfu_handle_prevalidate(...), set this boolean to false, and in the swtich(p_init-&amp;gt;type), in branch &amp;quot;DFU_FW_TYPE_APPLICATION&amp;quot;, set it to true.&lt;/li&gt;
&lt;li&gt;In your decryption code, decrypt only if this boolean is set.
(Note I haven&amp;#39;t tried encrypting anything else than firmware, encrypting bootloader might be of interest, and I would not encrypt the SD, obviously)&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87982?ContentTypeID=1</link><pubDate>Thu, 15 Jun 2017 16:13:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d64bf8a4-be6f-48b7-b4e3-d0d1d543ff8d</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;@SRA, I can&amp;#39;t post the code due to NDA, but if you take my last 2 posts, you have everything!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encrypt your .bin file (keeping it to the same size, changing it would have side effects I&amp;#39;m sure, requiring more changes)&lt;/li&gt;
&lt;li&gt;Decrypt received buffers in dfu_req_handling.c, in nrf_dfu_data_req(...), before the calls to nrf_dfu_flash_store(...) (2 calls). See my if above.&lt;/li&gt;
&lt;li&gt;In nrf_dfu_postvalidate(...), re-compute the CRC in &amp;quot;if (res_code == NRF_DFU_RES_CODE_SUCCESS)&amp;quot;, in the DFU_FW_TYPE_APPLICATION branch of the switch. This is because so far, the CRC was computed on encrypted data transfered, and on next startup the CRC will be compared with CRC of the code actually written in flash, so we need CRC of the decrypted version. This could also be computed while receiving the code, after decrypting it, on the fly, but I&amp;#39;m not sure there&amp;#39;s an advantage to do so.&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87964?ContentTypeID=1</link><pubDate>Thu, 15 Jun 2017 15:53:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:edcba5a4-c309-40bc-9c32-9425a7d0655f</guid><dc:creator>SRA</dc:creator><description>&lt;p&gt;Jonathan, would you consider posting your code/changes for the community?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87974?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 13:15:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:133dcc07-a7c1-4e34-bf21-007a2e6b8fd4</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;So this is it, thank you so much guys!&lt;/p&gt;
&lt;p&gt;One more thin I did (and you&amp;#39;re welcome to tell me there&amp;#39;s a better way): in prevalidate, I set a global variable m_image_encryption depending on the type of image.&lt;/p&gt;
&lt;p&gt;And for reference here&amp;#39;s my great encryption/decryption code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        if (m_image_encryption)
        {
            for (int i = 0; i &amp;lt; m_data_buf_pos; i++)
            {
                m_data_buf[m_current_data_buffer][i] ^= 0x5A;
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is to be inserted in nrf_dfu_data_req() before each of the 2 calls to nrf_dfu_flash_store().
(And no, don&amp;#39;t consider xoring with any key safe)&lt;/p&gt;
&lt;p&gt;Additional tips to whoever would like to do something similar: when using nRF Connect on Android, if something seems to not work, kill the app and restart it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87975?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 12:41:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c22b957c-50cf-4b43-8b57-53d4ffd017d9</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;I added:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;s_dfu_settings.progress.firmware_image_crc = crc32_compute((uint8_t*)m_firmware_start_addr, m_firmware_size_req, NULL);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in the switch that sets NRF_DFU_VALID_APP&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87973?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 12:07:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8bd3af37-15e8-4279-81ad-63c39e9eec41</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;You&amp;#39;re right, forgot that CRC was checked on startup. Suggest to compute the CRC in the post-validate step  instead (image is already validated by the hash).&lt;/p&gt;
&lt;p&gt;In post validate:&lt;/p&gt;
&lt;p&gt;Replace:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    p_bank-&amp;gt;image_crc = s_dfu_settings.progress.firmware_image_crc;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;switch (p_init-&amp;gt;type)
{
    case DFU_FW_TYPE_APPLICATION:
        // s_dfu_settings.progress.firmware_image_crc 
        p_bank-&amp;gt;image_crc = crc32_compute((uint8_t *)MAIN_APPLICATION_START_ADDR, m_firmware_size_req, NULL);
        break;
    ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87972?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 11:54:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8fde464a-f708-4d1e-a2d9-bab5d87437e5</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;I&amp;#39;m almost there. nrf_dfu_app_is_valid() fails, the CRC stored in s_dfu_settings.bank_0.image_crc is the CRC of the encrypted image (ie the one computed on the fly during image transfer).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87971?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 09:33:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8711aefc-d674-457e-bb8a-d6fb8a7c8c74</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Note that you can extend the init packet to include IV/nounce if needed (to avoid reuse). More about that here: &lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.tools/dita/tools/nrfutil/nrfutil_customizing.html?cp=5_5_8"&gt;infocenter.nordicsemi.com/.../nrfutil_customizing.html&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87970?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 09:24:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:98041ac2-4848-498c-81fc-45ee9530bdc3</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Forgot to point out that you need to generate the init packet first, as you said. This should work.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87969?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 09:22:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c6cd6cf7-2868-44f8-98eb-fc5449879bdf</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;Ok there&amp;#39;s just one thing I think I need to clear... When checking the image hash, what does the bootloader use? Does it compute new firmware hash by reading it from the flash? That&amp;#39;s how I understand it.
And then it seems to me I could leave .dat file intact, encrypt .bin after generating .dat, and decrypt data just before writing to the flash memory. CRC is always computed on encrypted data, SHA2 is always computed on the decrypted data. Am I wrong?
I&amp;#39;m gonna flash again my firmware and put a breakpoint in nrf_dfu_postvalidate.
Thank you guys!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87968?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 09:18:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a9371968-3e29-4bf3-9880-f8a1f609aec4</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;So far, I&amp;#39;ve done the following: encrypt .bin file, leave .dat file untouched. When transferring, I leave everything as is, however, just before write to flash (the 2 calls to nrf_dfu_flash_store()) I decrypt the data into a new buffer, and instead of writing what is in m_data_buf, I change the call to write the decrypted content from the buffer.
This way, the CRC works fine (as you outlined, it&amp;#39;s computed on the transfered data), so I can transfer 100% of the object. However, once transfer is finished, it doesn&amp;#39;t start the firmware (I don&amp;#39;t know the exact reason why yet).
Regarding the transfer resume, I&amp;#39;m going to use AES CTR (so far I&amp;#39;m using a dumb XOR only), and it might be slightly annoying to program, but the idea is to determine the offset, compute the AES CTR blocks for the bytes to be written to flash, XOR my decryption buffer and I&amp;#39;m done.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87967?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 09:15:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ab82f109-26a7-4fca-b87c-cc3e432189d0</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;I agree with Vidar. You can encrypt the .bin file and then generate init packet base on the encrypted binary. Then you don&amp;#39;t need to modify the .dat file.
If you stil want to read/modify the .dat file manually you can have a look &lt;a href="https://developers.google.com/protocol-buffers/docs/encoding"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87981?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 07:23:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:558a5fde-52c8-4d70-8cd2-c872fa8eba60</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Response was too long for one comment:&lt;/p&gt;
&lt;p&gt;Something to be aware of, the bootloader stores DFU progress in bootloader settings to allow DFU to continue in case of power loss, which will need to be modified if you are using a stream cipher for decryption (i.e., include decryption state in progress data). This feature can be disabled by making the following change in dfu_req_handling:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;case NRF_DFU_OBJECT_OP_SELECT:
            NRF_LOG_INFO(&amp;quot;Valid Command: NRF_DFU_OBJECT_OP_SELECT\r\n&amp;quot;);
            p_res-&amp;gt;crc = 0; //s_dfu_settings.progress.command_crc;
            p_res-&amp;gt;offset = 0;  //s_dfu_settings.progress.command_offset;
            p_res-&amp;gt;max_size = INIT_COMMAND_MAX_SIZE;
            break;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, in case you are not aware of it, nrfutil has an option for viewing init packets in a more readable format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nrfutil pkg display app_dfu_package.zip
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87980?ContentTypeID=1</link><pubDate>Wed, 31 May 2017 07:22:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1f755ef9-3b8a-4b1a-b735-c45cfb7ff701</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;The bootloader uses the hash from the init packet  to verify the authenticity and integrity of the FW image in the post validation step, while the checksum values (sent upon request) are only used by the dfu controller to verify that the data is received correctly during the transfer. For instance, to verify that a data object is valid before issuing the EXECUTE command. In other words, the bootloader must compute the CRC on encrypted data.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87978?ContentTypeID=1</link><pubDate>Tue, 30 May 2017 18:06:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b7a0096c-0940-4fda-ad30-9eae4bd85815</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;Thank you very much for the suggestion! I&amp;#39;m now looking at changing the CRC in my update package, but something puzzles me... I can&amp;#39;t find the CRC inside the DAT file. I was under the impression it would follow struct dfu_init_command_t (or dfu-cc.proto). The first 16 bytes are 12 84 01 0A 3E 08 01 12 3A 08 01 10 33 1A 02 87, 87 could match with SD requirement, but 12 (first one) certainly doesn&amp;#39;t look like a boolean!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87976?ContentTypeID=1</link><pubDate>Tue, 30 May 2017 14:44:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2b7ec7df-7de6-4fb4-b5e0-b1f14db283a2</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;CRC is calculated and checked after each object is received. Have a look &lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v13.0.0/lib_dfu_transport_ble.html?cp=4_0_0_3_4_2_2_3#lib_dfu_transport_msc"&gt;here&lt;/a&gt;. You can consider to check CRC for the encrypted packet instead of decrypted packet. This is to ensure the object is received properly over the air. Also, doing this you don&amp;#39;t have to modify the bootloader on that part.&lt;/p&gt;
&lt;p&gt;You can use the hash of the decrypted image to do the final validation of the image integrity.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87979?ContentTypeID=1</link><pubDate>Tue, 30 May 2017 12:22:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eb31cbbd-509c-431f-affa-19c8d6fb2fe8</guid><dc:creator>Jonathan</dc:creator><description>&lt;p&gt;Thanks for the confirmation, I&amp;#39;ve figured I had to change the CRC computation, so far I&amp;#39;ve failed, but I&amp;#39;ll keep trying! (If I got it right, CRC is computed on the flight as data is received, I&amp;#39;ve tried to change to &amp;quot;compute CRC on decrypted data&amp;quot;, but getting glitches)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: DFU firmware encryption</title><link>https://devzone.nordicsemi.com/thread/87963?ContentTypeID=1</link><pubDate>Tue, 30 May 2017 10:20:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ebce1a74-a4b3-4f6b-ad95-c4a94c338f4a</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;I don&amp;#39;t see any problem with this.&lt;/p&gt;
&lt;p&gt;And you are correct, .bin file is the pure image, and .data is the init packet.&lt;/p&gt;
&lt;p&gt;If you going to encrypt the .bin file and decrypt it after you receive it on the bootloader, you need to modify the bootloader so that hash and signature is only validated after the image is decrypted.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>