# Key derivation for AES-GCM using HKDF?

I have a system comprising N >1000 nodes. At each node I would like to use HKDF to derive a unique 256-bit key, Kn (for the nth node), from a pre-shared master key, K0, and a locally-generated random bit string, Rn.

Kn would then be used to apply AES-GCM to UDP packets that the nth node sends to other nodes and the receiving nodes would independently derive the necessary Kn using K0 and Rn, which would be included in the packet header and protected as “additional data” by the AES-GCM MAC.

The HKDF implementation takes the following parameters…

• Hash type: SHA256, SHA384, SHA512, BLAKE2B
• Input key of arbitrary length (presumably K0)
• “Additional Info” of arbitrary length (optional, but presumably Rn)
• Salt of arbitrary length (optional)

My questions are:

• What would be a good choice for the hash type?
• What is a sufficient length for K0?
• What is a sufficient length for Rn?
• What is the purpose / benefit / need of the optional Salt? Is it okay to omit assuming it can't be sent in the clear or pre-shared?
• Any other general flaws / issues / recommendations w.r.t. this approach?

Thanks.

What would be a good choice for the hash type?

Whatever works best for you. As long as the hash is considered secure, the difference comes down to performance. SHA-256 and SHA-512 are both traditional and safe choices recommended e.g. by NIST. You can't really go wrong with either of those. Which one is faster depends on your hardware. (SHA-384 is basically just tweaked and truncated SHA-512; there's little point in using it unless you're implementing some standard that requires it.)

What is a sufficient length for K0?

The master key needs to be long enough to resist brute force guessing attacks. 128 bits is probably enough; 256 bits certainly is.

What is a sufficient length for Rn?

You should use Rn as the salt in HKDF-Extract, to detive a distinct PRK for each node. For that purpose it just needs to be (almost certainly) unique for each node.

If you can assign the values deterministically, even 10 bits would be just enough for 1000 nodes.l, and 16 bits wouldbe plenty. If every node chooses a random ID, you'll want something like 2×16 + 32 = 64 bits to guarantee a $$< 2^{-33}$$ (i.e. less than one in eight billion) chance of a collision for up to $$2^{16}$$ nodes. (But be careful to seed your RNGs well!)

Also, if your nodes already have some unique ID each, you can just use those, however long they might be.

What is the purpose / benefit / need of the optional Salt? Is it okay to omit assuming it can't be sent in the clear or pre-shared?

The purpose of the salt is key diversification. In your case, as noted above, you should use Rn as the salt to ensure that each node gets its own PRK.

The purpose of the info parameter to HKDF-Extract is to let you derive multiple (pseudo-)independent keys from the same PRK. If you only need one key per node, you may omit it.

• Thanks for the very detailed and helpful guidance. W.r.t the length of Rn I will probably use 96 bits since the extra four octets are cheap and even a single node will need to re-derive a new key at restart and at least every 2^32 packets per NIST 800-38D due to use of random IVs for the AES-GCM (which is simpler and safer than preserving a monotonic counter across restarts / crashes / re-flashing etc.). – NJS Sep 21 '19 at 20:21
• W.r.t Salt vs. Info I guess I’m still a bit confused about the distinction between extracting “a distinct PRK” key using a random salt and (expanding?) multiple pseudo-independent keys from the same PRK using the Info parameter… I know that Info is often not very random or independent (e.g. file names) but if Info was provided by a secure PRNG without any salt would that not also produce distinct keys as independent / secure as produced by extracting keys with random salts? – NJS Sep 21 '19 at 20:38
• RFC 5869 states: [T]he goal of the "extract" stage is to "concentrate" the possibly dispersed entropy of the input keying material into a short, but cryptographically strong, pseudorandom key. In some applications, the input may already be a good pseudorandom key; in these cases, the "extract" stage is not necessary, and the "expand" part can be used alone. Indeed, using expand only was suggested in similar discussion here: crypto.stackexchange.com/questions/64150/… – NJS Sep 21 '19 at 20:38