According to the documentation, the scrypt hash function works like so:
The hash function does the following:
- Adds random salt.
- Creates a HMAC to protect against active attack.
- Uses the scrypt key derivation function to derive a hash for a key.
All hashes start with the word "scrypt". Next comes the scrypt parameters used in the key derivation function, followed by random salt. Finally, a 256 bit HMAC of previous content is appended, with the key for the HMAC being produced by the scrypt key derivation function. The result is a 768 bit (96 byte) output:
- bytes 0-5: The word "scrypt"
- bytes 6-15: Scrypt parameters N, r, and p
- bytes 16-47: 32 bits of random salt
- bytes 48-63: A 16 bit checksum
- bytes 64-95: A 32 bit HMAC of bytes 0 to 63 using a key produced by the scrypt key derivation function.
Bytes 0 to 63 are left in plaintext. This is necessary as these bytes contain metadata needed for verifying the hash. This information not being encrypted does not mean that security is weakened. What is essential in terms of security is hash integrity (meaning that no part of the hashed output can be changed) and that the original password cannot be determined from the hashed output (this is why you are using scrypt - because it does this in a good way). Bytes 64 to 95 is where all this happens.
My question is why does it use the scrypt hash as a key for the HMAC algorithm rather than just returning the scrypt hash directly? What extra protection does this give? It mentions "active attacks" but doesn't give details.