I am currently revising an AES data format. I would like to determine whether a provided password/key is incorrect. Previously this was done by validating the HMAC, but this makes it impossible to distinguish between data corruption and a bad password. It also requires reading the entire stream before validating the password, which is problematic.
My new design is as follows (the HMAC step is HKDF):
prk = PBKDF2(SHA512, password, salt, rounds, 512 bits)
(validator[16], iv[16]) = HMAC(SHA512, prk, "rncryptor.validator+iv" || 0x01, 256 bits)
The validator is 16 bytes that are written to the header. During decryption, I recompute the validator to check the password before proceeding.
I believe this scheme is secure. Common best-practice for password validation is a salted and stretched hash. I believe HKDF is providing the same. My one slight concern is NIST SP 800-56a, Section 5.8:
An Approved key derivation function (KDF) shall be used to derive secret keying material from a shared secret. The output from a KDF shall only be used for secret keying material, such as a symmetric key used for data encryption or message integrity, a secret initialization vector, or a master key that will be used to generate other keys (possibly using a different process). Non- secret keying material (such as a non-secret initialization vector) shall not be generated using the shared secret.
The validator is not "keying material" at all, so I don't believe this is relevant, but I don't understand the restriction even for "a non-secret initialization vector." Why would it be dangerous to use a proper, salted KDF to generate a non-secret IV? Does this impact my use as a key/password validator?