I want to implement AES-128 in my IoT network which consists of a Master device which runs Linux on it and slave devices which are 8-bit micro-controllers that periodically transmit data packets to the master.

I read about the AES/Rijndael algorithm and liked it.

The only questions I have are:-

  1. What should I set my IV to be ?

  2. What should be the key value?

Can the key value be a random value chosen by me or it has to come from a specific source?

  • 1
    $\begingroup$ The key should ideally be truely random, the IV depends on the mode of operation. However, you are hopefully aware that implementing AES (or any crypto really) yourself is generally not recommended? $\endgroup$
    – Guut Boy
    Aug 16 '18 at 11:01
  • 4
    $\begingroup$ There's no IV in AES. There are in some of its modes of operation. The requirements on IV somewhat depend on the mode. Likely you want a mode with authenticated encryption. $\endgroup$
    – fgrieu
    Aug 16 '18 at 11:51
  • 2
    $\begingroup$ You're focusing on the technicalities surrounding AES. You're however doing this too early if you don't know where the key must come from. First think of your use model, then the threats, then the protocol, the algorithms (primitives) to use and finally the parameters of the algorithms. $\endgroup$
    – Maarten Bodewes
    Aug 16 '18 at 12:41

What should I set my IV to be ?

For any decent mode of operation, like AES-EAX or AES-CCM you want to not re-use a key-IV pair. That is different keys with the same IV is fine as is the same key with different IVs and different keys with different IVs. Beyond that if you can enforce the above restriction with a counter (or domain-separated counters, e.g. $2^{32}$ unique prefixes for the devices which independently count from $0$ up with their prefix) that is fine, if you can't then you probably want to just generate the IVs at random if possible.

You may want to note that CBC is not a decent mode of operation, forcing you to use unpredictable IVs.

What should be the key value ?

Keys should ideally be generated such that they are indistinguishable from random strings of the same length. This may involve a key-exchange (using symmetric or asymmetric cryptography) or other methods of key-derivation (e.g. using a password or key-based key deriviation function like Argon2 or HKDF).

In your specific scenario one idea would be let the master have a secret key $K$ and each device having a unique serial number. Then on deployment you use HKDF to derive two keys for each device using its serial number and the data flow direction and store the keys on the device. Then when you get a packet, you can simply re-derive and / or cache the specific keys on your master device.

One final warning: You really don't want to implement AES (or maybe even the mode) yourself because that's quite hard to do securely and with good performance. You really want to use a library for that instead, e.g. BearSSL or mbedTLS.

Oh and if you are doing transport encryption you probably want to consider using TLS (for TCP-like transport guarantees) or DTLS (for UDP-like transport guarantees) with pre-shared keys which handles all the encryption and authentication and IV management for you if you just supply it the shared key (only one this time, it will derive its own for each traffic direction).

  • $\begingroup$ "In your specific scenario one idea would be let the master have a secret key K and each device having a unique serial number. Then on ..... master device." As I understand, if the master is M and there are 2 slaves S1 and S2, I can use some string like "SERIAL_11111_FROM" and "SERIAL_11111_TO" generate two keys for slave 1 and "SERIAL_22222__FROM" and "SERIAL_22222_TO" generate two keys for slave 2. Also, I need to generate a key for master say "SERIAL_00000" for master. All of them using HKDF. Then apply aes.do_aes_encrypt and aes.do_aes_decrypt (from AES.h) for messaging. $\endgroup$
    – hitx11
    Aug 16 '18 at 12:35
  • $\begingroup$ @Hitesh yes, you can use these strings along with a master key to derive the separate keys. Note though that the aes.do_aes_encryption() function uses CBC which has a) unpredictable IVs as a requirement and b) offers no guarantee whatsoever of the delivered ciphertext being untampered in malicious ways. If possible you really want to use EAX, CCM or GCM. $\endgroup$
    – SEJPM
    Aug 16 '18 at 12:44
  • $\begingroup$ No. You should not use aes directly to do anything. Modes of operation matter. Also, key management is a bug deal, and you must not use input for a kdf which is easy to guess. Also, words as input need a kdf suitable for passwords, not a general one. $\endgroup$
    – tylo
    Aug 16 '18 at 12:44
  • 1
    $\begingroup$ @tylo the mentioned encryption function performs CBC encryption / decryption. Also using strings as for the label input of HKDF is ok as long as a proper high-entropy key is still supplied. $\endgroup$
    – SEJPM
    Aug 16 '18 at 12:47
  • $\begingroup$ @SEJPM and @tylo thanks for explaining. Can you suggest a weblink where this process is available in code form. I don't need to copy, but just check the implementations? $\endgroup$
    – hitx11
    Aug 16 '18 at 12:56

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.