I've gotten a couple of questions asking how our key derivation function works. The technique is very similar to that described in RFC 2898, also known as PKCS #5. There are two key derivation functions (KDF) documented in this RFC – PBKDF1 and PBKDF2. Our KDF implementation is very similar to PBKDF1 (section 5.1), with the following changes:

  1. 8 bytes of salt are recommended, we use 16 by default
  2. 1000 iterations are recommended, we use 50,000
  3. The function documented hashes the previous hash a number of times. We concatenate the counter with the previous hash, and hash that. This was done on the recommendation of Paul Leach, and makes the hash harder to optimize.
  4. We will allow more advanced hashing algorithms than SHA-1 in the Agile encryption.
  5. The final output is passed into CryptDeriveKey as documented in MS-OFFCRYPTO, agile encryption does something slightly different.

So we're not absolutely using a completely standard KDF, but it's close – and stronger than the standard.