Why do some key derivation functions (like PBKDF2) use a salt? Let me start by explaining my understanding of the various concepts involved in this question:


Salt: Random bytes of data used as secondary input for a password hashing function, like so:

hashfunc(&lt;password&gt;, &lt;salt&gt;) -&gt; &lt;hash&gt;


And both the &lt;hash&gt; as well as the &lt;salt&gt; that was used are then stored (in a database, for example).

This prevents attacks using rainbow tables, making it more difficult for an attacker who has access to the output of the hash function (&lt;salt&gt; + &lt;hash&gt;) to deduce the original &lt;password&gt;.
Key derivation function: A function that takes a password &lt;password&gt; and an integer &lt;size&gt; as input, and generates arbitrary bytes of the desired &lt;size&gt; as output, like so:

kdf(&lt;password&gt;, &lt;size&gt;) -&gt; &lt;bytes of length &lt;size&gt;&gt;


This allows us to turn a plain-text password like "admin123" into a key of a certain size that can be used by other cryptographic functions (like AES encryption, which requires a key of size 32).


So if my understanding is correct, then key derivation functions have no use for a salt. After all, the derived key isn't intended to be stored - it'll be used as input for another cryptographic function, and then it'll simply be discarded. Unless someone steals the derived key from the computer's memory in this short time frame, there is no risk of a rainbow table attack.

And yet, according to wikipedia, the PBKDF2 key derivation function takes a salt as input:


  The PBKDF2 key derivation function has five input parameters:
  
  DK = PBKDF2(PRF, Password, Salt, c, dkLen)


What purpose does this salt serve? Did I misunderstand the purpose of key derivation functions?



Related questions:


PBKDF2 and salt does not answer my question because the answers seem to assume that the derived key will be stored, which, according to my understanding of key derivation functions, should never happen.
PBKDF2, like most password-based key derivation functions, has a salt input because that is often useful. Two examples:


When using PBKDF2 as a key derivation function, the salt allows to re-use the same master key for multiple derived keys, e.g. a confidentiality key and integrity keys, with a different salt per use. In the same vein, PBKDF2 could be used to generate per-site passwords from a master password and the site name as salt.
When using PBKDF2 for storage of access-control password tokens, salt will make brute-force attack impossible to carry before the salt is known, defeating rainbow tables. That's noted in the question.