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.