# PBKDF2 for key diversification

I am looking for a secure key diversification function to create individual AES keys for a local smart card deployment. The keys need to be derived from a secret master key and the smart card serial number. Key calculation can happen on the host system.

Is it secure and practical to use PBKDF2(password=master_key, salt=serial_number, rounds=1000, dkLen=16) to get individual keys, or would an easier scheme like AES(key=master_key, data=serial_number) suffice?

Edit: the master_key will be created only for this purpose, with at least 128 bits of random data from a proper RNG. An issue that I wondered about is: typically, the salt is also a high-entropy value. Will this scheme become vulnerable if the serial numbers are not high-entropy (but still unique)?

-
How much entropy does your master key have? Whether or not you need a PBKDF depends on that. – Thomas Feb 11 '13 at 18:26
If the master key has high entropy, I'd prefer HKDF over PBKDF2 – CodesInChaos Feb 11 '13 at 20:31
@CodesInChaos me too, but most of the time AES is in hardware and SHA isn't, so you might be better off using a MAC (or actually DAC) based algorithm for smart cards, also regarding DPA attacks as fgrieu pointed out. – Maarten Bodewes Feb 13 '13 at 0:23

If you want key diversification with a key as input, you are better off using a key based key derivation function (KBKDF) over a password based key derivation function (PBKDF). Difference is that KBKDF requires a key with high entropy. This also means that it does not require a salt nor an iteration count. It does however require context specific data for each derived key. In your case that would of course include an encoding of the serial number. It may also include some kind of ID or label for a specific key, for instance ASCII "ENC" for an encryption key and "MAC" for an authentication key.

If you are looking for a key derivation function you are best off using NIST SP 800-108 or HKDF. NIST SP 800-108 defines a whole range of KBKDF's. Unfortunately, it does not provide any kind of recommendation or default.

As indicated by fgrieu, countermeasures against side channel attacks may not be implemented for hash functions on a smart card. So it would probably be best to opt for the Counter mode KBKDF using AES in CMAC mode for the PRF. This is the first mode described in the SP800-108 document.

Both the KBKDF and CMAC are relatively easy to implement if you are used to twiddling with binary data. I've just implemented all KBKDF's in 800-108 and HKDF for the Bouncy Castle framework (Java), so they are all in there in case you need a reference implementation (tested against the official test vectors, of course).

-
Note: I edited in HKDF in case somebody does want to use a hash function instead of AES. – Maarten Bodewes Oct 14 at 20:57

For the purpose of key diversification (that is, assigning a unique key per device), a true master_key is customary; that is, one with plenty of entropy (like, 128 bits or more random bits). Edit: that's now stated in the question.

With that caveat, yes, PBKDF2(password=master_key, salt=serial_number, rounds=1000, dkLen=16)is appropriate to generate one 128-bit key; it's even overkill, especially as parameterized: rounds could be 1, since the only purpose of rounds is to stretch the password input, which is not needed if that input is a true key. Reducing rounds will speed up production, and use by a master server, with no cryptographic drawback.

And yes, AES(key=master_key, data=serial_number) is appropriate, and usual. As a benefit, that allows to just state: each card has a different key, something that has a (minuscule, and non-exploitable) chance not to hold with PBKDF2.

Edit: For the purpose of having strong diversified keys, the salt (typically, the serial number) needs not be high entropy. It is enough that it is different from one device to the other [one drawback occurs in case of temporary compromise of a resource capable of doing the diversification, without compromise of the list of salts/serial numbers of existing devices: it becomes possible to compute the diversified keys of all the devices if the serial numbers are sequential; PBKDF2 with rounds=1000, or whatever slow KDF, is not an adequate way to mitigate that risk; a delay is much better].

Also, ask yourself one question: is there potential for a side channel attack on the device(s) doing diversification? If yes, is PBKDF2, which is hash-based, really appropriate from that implementation standpoint? I have yet to see a hash implementation evaluated against DPA, contrary to AES implementations, where this risk of DPA attacks is at least assessed.

Side note: if key stretching was needed (it is not), rounds=1000 in PBKDF2 is clearly obsolete; that was a suggested minimum over 12 years ago, and IMHO was not enough even at that time. Moore's law and friends (in the form of the democratization of GPU and FPGA accelerators) have made it necessary to use at least rounds=100000 for equivalent security. Further, PBKDF2 is obsolete as a key stretcher, except perhaps if you have a hardware-accelerated hash and positively no memory; scrypt is the new state of the art.

-
thank you very much for the long and informative answer. I have chosen the other one because a KBKDF is a perfect match for my scenario, and using a PBKDF or some ad-hoc scheme seems less appropriate. – ge0rg Feb 14 '13 at 2:44
@geOrg: I also upvoted owlstead's answer! Still, the AES scheme is not ad-hoc; its security directly follows from that of AES; and it is widely used in the industry of Smart Cards, because of its ease of implementation (e.g. in a SAM), with a security against side-channel leakage reducible to an evaluated primitive. – fgrieu Feb 14 '13 at 7:39
what frightens me a little (and why I thought the simple AES scheme is ad-hoc) is that you need to do proper padding of the serial numbers. I've seen another variant using AES-CMAC, which also seems more reasonable to me. – ge0rg Feb 14 '13 at 17:47
@geOrg: Yes, in the AES(key=master_key, data=serial_number) you need to map serial_number to input of AES in a specified and reversible way, e.g. in order to avoid that card 12 and 1200 get the same keys. I have always seen this done by specifying some fixed width for the serial number. Nowadays that is commonly 7 bytes, often with either leading fixed byte, and zero-padding to the block size on some specified side. – fgrieu Feb 15 '13 at 8:20

Yes, this is secure.

Given your statement that the master_key is a cryptographic-quality 128-bit random value (not a passphrase), you do not need to use PBKDF2. You can use any key derivation function, and you can use any secure one. For instance, any any pseudorandom function (PRF) will be adequate, such as AES-CMAC. Also, HKDF would be fine, too.

Also look up the notion of "key separation". See, e.g., these answers on this site: