2016-01-29 02:17 AM
I've implemented DFU-OTA over GSM network with Fail-back feature (reverting back to older firmware if the upgrade failed, sudden shutdown during the upgrade and in the event of network error) and so far it seem to work fine (Probably I need to test more), However, I would now like to add security features in the upgrade process. I've heard that there could be man in the middle attack, execution of malicious code by reverse engineering the firmware etc. This topic is very new to me, hence I'm looking for guidelines on what and how I should implement secured f/w upgrade.
My firmware binary (My application firmware that will be flashed on the internal main flash memory of STM32F072) will reside on a HTTPS server and I download this binary over GSM network by issuing AT+ command (STM32 MCU is connected to SIM800H GSM module over UART on the custom board). Some of the first few questions that I've in mind are:1: Is it possible to sniff the GSM communication that my board is making, then probably doing a Man in the middle attack won't be very difficult. How to subvert such attempts ?2: Assuming that the HTTPS server where I keep my firmware binary is very robust against attacks (the firmware binary will be uploaded on the server, only after successful authentication), what else can go wrong ?3: Any other guidelines would be also very helpful.Thanks, #iap #stm32f0 #fota2016-01-29 03:16 AM
You should encrypt your firmware so that even if somebody sniffs the communication and extracts the firmware they can't read it.
Cryptography is hard, and if you don't have any experience you will make mistakes that can be exploited by experienced professionals (side-channel attacks, timing attacks, bad implementation, etc.). You can do using both symmetric or asymmetric (public key) encryptions, or a combination of them. You definitely need authentication. If you want a short guideline, here is one using symmetric encryption: You need both . For this you will need a symmetric stream cipher like ChaCha20 (you can use a block cipher too) and message authentication code (MAC) like Poly1305. Both are supported by x-cube-cryptolib which even has combined version (CHACHA20-POLY1305) of those algorithms so that you don't have to do the MAC and encrypt/decrypt steps manually (in which case you should always do encrypt-then-MAC). 1. The key must be stored in the firmware and protected from the read-out. 2. The firmware reads the new version of the encrypted firmware and the used Nonce, checks the authenticity of the firmware, if it's authentic it decrypts the firmware and updates itself, the new firmware might contain a different key for the next version than the previous one for additional security, but in this case (if you want to use different keys for each version) one can not update i.e. from v1.1 to v1.4, and must go through all the versions in between. P.S. I hope you will open source your work when it's ready.2016-01-29 04:30 AM
Thanks a ton.
At the moment, it looks like, I'm going to bite off more than can chew, however it does sound very interesting and probably my supervisor (I'm doing this IAP exercise as part of my Masters Thesis and a small startup where I work as well has been interested to implement this on their product if everything goes well. Fingers crossed), would be excited as well. I'd love to open source it (provided, it's robust and clean), but _probably* that needs to be discussed with my manager at my work place.Thanks once again!!!2016-01-29 06:21 AM
.. can be exploited by experienced professionals ..
Or just sharp witted amateurs.Even if the pipe is supposedly secure, you really need end-to-end encryption, as none of the infrastructure is free of intrusion.2016-01-31 06:27 PM
I started looking for existing solutions, which I could apply (I've a long way to go before I understand what I'm doing) in my application and so far, I've found,
and . A quick look in the wolfSSL suggests that it requires pthread support, which I do not have in my application (I do not have any RTOS, It's a bare metal code with ST's library) and mbedTLS also seem to be quite huge (I've currently STM32F072C8 MCU which has a total of 64 kB main flash memory. I'm planning to move to STM32F072R8 (128 kB flash memory version). I then plan to divide the main flash memory of 128 kB into three regions; Bootloader (say 24 kB) and 52 kB each for two application firmware. So at this moment my question is, what SOC should I pick (Considering the fact that STM32F0 has been enough for my needs so far). Thank you for your help.2016-02-01 01:13 AM
I think you don't absolutely need wolfSSL or mbedTLS. They can be used for trivial encryption but they are mainly designed to be used as TLS library, i.e. if you need HTTPS or you want to design your firmware update protocol using HTTPS/TLS (with both client-side and server-side certificates, which is not a bad idea at all).
Otherwise, the crypto library by ST is sufficient and it supports all the STM32 families with software or hardware accelerated (when available) encryption. Cryptography library for STM32Cube -http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1920/PF262570
Cryptography library for StdPeriph -2016-02-03 02:28 AM
Excellent!
So there are multiple aspects of secure firmware upgrade; Authentication, Encryption and securing Key by READ Protection. For the time being, I've a query on encrypting the application F/W(Forget about the overall security for a moment). My application F/W is currently being stored on a HTTP server (In future, I'd like to move to HTTPS instead). This F/W is downloaded over GSM network by the bootloader and since this application F/W is quite big, I download it in chunks and flash it in memory one after another until entire F/W is downloaded and programmed. Currently, the application F/W which is kept on the HTTP server for download is un-encrypted and is in binary format. I'd like to put an encrypted version of this F/W instead on the HTTP server, download the encrypted version, use the key stored in the bootloader to decrypt each chunk and program it. To encrypt the application F/W with the same key, It seems that I need to write a separate program on my PC that uses the same STM32-cryptography library package and encrypt the F/W binary. Is this understanding correct ? Better alternative to achieve the same result ? In other words, how to encrypt the entire application firmware ? Thanks.2016-02-03 04:16 AM
Dear All,
Thanks for explaining this topic in such a nice way. Yes of course ST Cryptography Library is a good choice. I am also trying to use it but it takes too much space. Because it is precompiled library. So is there a way to use any selected module(like AES or RSA) while commenting others.2016-02-04 12:45 AM
> Thanks for explaining this topic in such a nice way. Yes of course ST Cryptography Library
> is a good choice. I am also trying to use it but it takes too much space. Because it
> is precompiled library. So is there a way to use any selected module(like AES or
> RSA) while commenting others. Your linker should do that automatically, i.e. include in the final binary blob only the objects (functions/variables/etc.) which were used by your code. See the generated MAP file to check it.
2016-02-04 01:22 AM
@sidekick
Yes, your understanding of the scheme is correct. To encrypt the firmware you must write a PC software which does it using the same or a compatible cryptography library as the one in the firmware. I think this option is preferable. In case if it is problematic you can use a microcontroller as a cryptography black-box and write a PC software which reads the firmware, passes it to the microcontroller by chunks, and reads encrypted chunks back using some kind of simple protocol, something like this: completely not-tested out-of-head PSEUDO-CODE:#define PLAINTEXT_MAX_CHUNK_SIZE (64)
#define ENCRYPTED_MAX_CHUNK_SIZE (2 * PLAINTEXT_MAX_CHUNK_SIZE)
static
int
err = 0;
static
unsigned
char
buffer_plaintext[PLAINTEXT_MAX_CHUNK_SIZE];
static
unsigned
char
buffer_encrypted[ENCRYPTED_MAX_CHUNK_SIZE];
com_write_string(
''FIRMWARE_START
''
);
for
(;;) {
int
n;
uint16_t checksum;
n = read_file(file_plaintext, buffer_plaintext, PLAINTEXT_MAX_CHUNK_SIZE);
if
(n < 1 || n > PLAINTEXT_MAX_CHUNK_SIZE) {
break
;
}
checksum = crc16(buffer_plaintext, n);
// sending the chunk of size n + crc
com_write_string(
''CHUNK_START
''
);
com_write_buf(&n,
sizeof
n);
com_write_buf(buffer_plaintext, n);
com_write_buf(&checksum,
sizeof
checksum);
// reading the encrypted chunk
com_read_buf(&n,
sizeof
n);
if
(n < 1 || n > ENCRYPTED_MAX_CHUNK_SIZE) {
err = 1;
break
;
}
com_read_buf(buffer_encrypted, n);
com_read_buf(&checksum,
sizeof
checksum);
if
(checksum != crc16(buffer_encrypted, n)) {
err = 3;
break
;
}
write_file(file_encrypted, buffer_encrypted, n);
}
com_write_string(
''FIRMWARE_END
''
);
And the firmware encrypts the chunks using the ChaCha20Poly1305_Encrypt_Append function.