6

I want to derive a key a number of times for a deterministic scenario, where I can get n keys from a single one.

The logic looks something like this:

masterKey = random 128-bit
For i from 0 to n:
    let key[i] = CMAC(masterKey, i)

Is this a proper way to generate a number of keys or does this have a flaw?

shewa
  • 61
  • 2

2 Answers2

5

CMAC(masterKey, i) should generally suffice, yes. Note that you would need to specify an encoding for i (e.g. octet string consisting of the big endian encoding of i, left-padded with zero valued octets up to 4 octets).

It's probably better to implement one of the schemes defined in NIST SP 800-108: "Recommendation for Key Derivation Using Pseudorandom Functions" though. Note that CMAC is a Pseudorandom Function (PRF) and is mentioned explicitly in this standard.

I'd recommend the NIST SP 800-108 counter mode (section 5.1), which is relatively commonplace and easy to implement. Note that the counter i in the standard is different from your definition of i. The i in the standard is used to derive more keying material for a single key than can be generated by the PRF (i.e. more than 128 bits in the case of AES-CMAC). Your i should be encoded in the Context variable if you follow the standard to the letter.

Maarten Bodewes
  • 96,351
  • 14
  • 169
  • 323
5

Everything that Maarten has said is true; however I would emphasize one point that may not be obvious. I'm pretty sure you've doing things correctly; however it would be prudent to say it anyways.

CMAC is a good KDF is the key is unknown, and the message being MACed is known. It is not a good KDF if the key is known, and the message is unknown. That is, if we use the notation that the first parameter to the CMAC function is the key, then:

masterKey = random 128-bit
For i from 0 to n:
    let key[i] = CMAC(masterKey, i)

is safe; but the similar looking

masterKey = random 128-bit
For i from 0 to n:
    let key[i] = CMAC(i, masterKey)

is not. That's because, in the second case, someone who learns one of the key[i] values can find the 128-bit preimage to the CMAC (under the known key i), and thus rederive the masterKey (and from that, recover all the other keys).

This is because CMAC with a 128 bit plaintext $P$ is effectively $AES_k(P) \oplus c_k$ (for a $c_k$ constant that depends on $k$); if you know $k$, you can recover $P$. This is not a violation of CMAC's security properties as a secure MAC; those properties don't promise anything if the attacker knows the key.

poncho
  • 154,064
  • 12
  • 239
  • 382