We will be using following commands to encrypt to firmware file at server and that will be decrypted on the embedded board using decryption command mentioned below,

Following command will be used to generate symmetric key of 128 bit length

openssl rand 16 > ./symmetric.key

we will use following commands to create private and public keys in PKCS#8 format

openssl genrsa 4096 | openssl pkcs8 -inform PEM -topk8 -v2 aes-128-cbc -nocrypt -out keyfile.pem
openssl pkey -inform PEM -in keyfile.pem -pubout -out keyfile_pkcs.pub

For encrypting firmware we will use following command

openssl enc  -in firmware.tar -aes-128-cbc -salt -out firmware.enc -pass file:./symmetric.key

We have two choices to encrypt/decrypt symmetric key at board side,

Option 1. Encrypt symmetric key using public key at server and decrypt it using private key at board.

We thought of using following command sets,

openssl pkeyutl -encrypt -pubin -inkey keyfile_pkcs.pub -in symmetric.key -out symmetric.key.enc
openssl pkeyutl -decrypt -inkey keyfile.pem -in symmetric.key.enc -out decrypted_symmetric.key

Option 2. Encrypt(sign) it using private key at server and decrypt(verifyrecover) it using public key at board. We thought of using following command sets,

openssl pkeyutl -sign -inkey keyfile.pem -in symmetric.key -out symmetric.key.enc
openssl pkeyutl -verifyrecover -pubin -inkey keyfile_pkcs.pub -in symmetric.key.enc -out decrypted_symmetric.key

EDIT Just for completeness putting command to decrypt firmware file using symmetric key.

openssl enc -d -aes-128-cbc -in firmware.enc -pass file:./decrypted_symmetric.key -out firmware.tar

Now being new to this cryptography and OpenSSL we have following doubts,

Doubt 1: Which option to choose for encrypting symmetric key? (option 1 or option 2)

Doubt 2: Do you suggest any improvements in above commands? Do you see any problem in this method ?

Any other suggestion/correction/pointers ?

  • 1
    I noticed that, in Option 2, Encrypt and sign are treated as if they are somewhat similar concepts. Encrypt and Sign are very different processes: one of them keeps the data private(cannot be known to anyone without the key) but the other only ensures integrity by providing a signature with the original message unecrypted. So signing a private key only ensures that the private key does not changed, and everyone can also see the private key openly which is not a good idea. – Makif Jun 20 '16 at 12:17
  • @Makif Thank you for attention. I get same opinion from everyone regarding signing. However I tend to think its possible to encrypt using private key(signing) (Like for broadcast message) and -verifyrecover is decrypting such broadcast message using public key, isn't it ? In our case public key is not really public its stored on the embedded board, So either ways it should be same isn't it ? Though not conceptually. – AnkurTank Jun 20 '16 at 12:43
  • 1
    I would suggest using gpg for this task instead of openssl. By default, when encrypting, gpg generates a random symmetric key and encrypt the symmetric key with asymmetric encryption. Using gpg is much simpler than doing these fiddly steps yourself as you can sign and encrypt in a single command: gpg2 --recipient KEYID --encrypt --sign file.tar – Lie Ryan Jun 21 '16 at 15:21
  • @LieRyan Thank you for comment. I get same suggestion on every other website/post. But there are couple of problems. We don't have gpg on board and when I try to cross compile it I see many dependencies. However we have OpenSSL available on our board(AM335x based). And we were planning to use crypto hardware accelerator available on SOC. So far we see that TI used it with OpenSSL, So we are inclined to use the same. – AnkurTank Jun 21 '16 at 16:26

Not an answer but you asked for suggestions and this would be a lot for (SX) comments.

(0) openssl pkcs8 -topk8 ... -v2 aes-128-cbc -nocrypt is misleading at best if not wrong. If the output file is not encrypted, it doesn't matter what algorithm is not used to encrypt it.

(1) openssl enc -pass file: (or -kfile) reads the first line of the file as a string, and uses it as password (not key) with a weak PBKDF. You have random bytes for 'password' so the weak PBKDF is only silly not broken, but there's a 12% chance one of the random bytes will be NL or null and cause the key to have reduced entropy and about a 6% chance it will have low enough entropy to be broken. Either use rand -hex value as key with -K uppercase; or use rand -hex or convert to base64 (either of which gives all-alphanumeric) and let the PBKDF (trivially) distill it.

(2) CBC is unauthenticated and somewhat malleable (though not as bad as the stream modes) and you don't add authenticatation. If an attacker wants your device to accept an altered file, they probably can after a fair amount of work, although the details depend on your file(s) and your device(s).

(3) CBC requires padding and openssl enc uses PKCS#5, and you don't authenticate; if your device is observable, this probably gives a padding oracle. If an attacker can provide crafted files and detect whether your device successfully decrypts or not, they can quickly break your encryption.

(4) But why are you encrypting anyway? Is this firmware secret? Most firmware isn't, and in most applications where firmware is downloaded the important thing is integrity and authenticity, that is, loading only authorized firmware while rejecting tampered or forged firmware. Encryption in general is not designed to do that, and this encryption in particular does not do that. If what you want is integrity and authenticity, use signature not encryption, as @P4cK3tHuNt3R pointed to.

EDIT: specifically for authentication you can use digital signature

openssl dgst -$hash -sign privatekeyfile >sigfile 
# combine the pieces for transmission then separate and 
openssl dgst -$hash -verify publickeyfile -signature sigfile

or use CMS format which combines and separates the data for you

openssl cms -sign -signer certfile [-inkey keyfile_if_not_in_certfile] -outform der
openssl cms -verify -inform der [-CAfile/CApath unless your root or selfsigned is in default truststore]
# assumes the transfer process handles binary, as most do nowadays;
# if not use -outform and -inform PEM, or default SMIME with -text 
# to add/strip dummy headers presuming your data isn't proper MIME

or several possible MACs, but from commandline HMAC is easiest

openssl dgst -$hash -hmac keystring 
# at each and and compare
# note you can't easily use an arbitrary (binary) key here
# but HMAC construction inherently distills up to one hash input block
# worth of key so just use about 128 bits of entropy in hex or base64

openssl supports a variety of hashes, but unless you need to consider other factors I would use sha256 or sha512, the latter especially on 64bit machines. Hashes now officially broken or endangered for general signature (MD5, SHA1) would actually be safe in your application, but that can be complicated and timeconsuming to justify to people, so just avoid the problem.

If you really want encryption and authentication, although as above I don't think you need it, authenticed encryption modes GCM and CCM (which do both at once) are available in openssl library but not (currently?) in commandline, so easiest is to just encrypt and then authenticate with either/any of the above. The key (as it were) is encrypt then authenticate, and conversely verify then decrypt; this blocks the malleability and oracle that apply to unprotected CBC (and most other) encryption.

  • Thank you for suggestions. (0) I will change openssl genrsa 4096 | openssl pkcs8 -inform PEM -topk8 -nocrypt -out keyfile.pem. (1) Will use openssl rand -hex 16 > ./symmetric.key (2) Do you suggest any other algorithm apart from CBC ? (3) Unless attacker has access to device GUI he won't be able to find out if decryption is successful or not (4) Firmware is not secret but It will be available on the public server and we don't want unauthorized attacker to inspect firmware files and modify it. – AnkurTank Jun 19 '16 at 8:08
  • 1
    @AnkurTank: expanded answer; see if that helps – dave_thompson_085 Jun 21 '16 at 9:44
  • Thank you Dave, Your previous answer was also of big help. EDIT will definitely help. I will try to understand your EDIT and might ask further question. :) Hope you don't mind. – AnkurTank Jun 21 '16 at 10:05
  • We would like to do encrypting and authentication. I didnt get your suggestion. So are you suggesting to use the keys which I have generated in my original post and then encrypt firmware using symmetric key and sign symmetric key(from either of the methods you suggested above) and verify it in the embedded board? – AnkurTank Jun 24 '16 at 15:08
  • I could sign symmetric key using openssl using command you suggested openssl dgst -sha256 -sign privatekeyfile -out symmetrickey.enc symmetrickey. – AnkurTank Jun 24 '16 at 16:31

As I understood the problem you are trying to protect the firmware file over web when board needs to be updated(Firmware Update), correct me if I'm wrong. Why you are mixing symmetric and asymmetric cryptography altogether, even you can achieve your goal by only using asymmetric cryptography. As you mentioned you are generating the public and private key pairs, so use your public key to encrypt the file then decrypt it on board using private key. It will reduce the computation time as well. The main problem will be how are you going to store the private key on board. Here you need to come up with different approach, so that no one get to know the private key after doing reversing etc of your hardware.

So choose your option 1 but without symmetric key for encryption and decryption of firmware. The firmware signing signing which you have mentioned in the option 2nd is wrong. Please follow this link to get to know the process of signing Digital Signature

  • 1
    Thank you for reply, You are right about firmware file and firmware update. whatever I read on internet suggests that asymmetric encryption is slower so its best to encrypt big file using symmetric key and encrypt symmetric key using asymmetric key. So We went ahead with that approach. – AnkurTank Jun 17 '16 at 16:10
  • 1
    I'm not sure that using asymmetric encryption for bulk data is really appropriate. – Neil Smithline Jun 17 '16 at 16:13
  • If the file is big then you can go with your first option, but you need to make sure that no one could get to know your private key. – P4cK3tHuNt3R Jun 17 '16 at 16:21
  • @P4cK3tHuNt3R: I agree with you. We have to keep private key secure. Thank you. – AnkurTank Jun 17 '16 at 16:25
  • @P4cK3tHuNt3R Just to clarify, in option2, I am using private key to sign the symmetric key, I don't understand what is wrong with that. It should still be okay, isn't it ? Symmetric key encryption of firmware has nothing to do with digital signing right ? – AnkurTank Jun 20 '16 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.