Background: I'm putting together a personal project to store multiple short message protected by a master password. This is more to learn and demonstrate that I understand how to use some standard cryptographic primitives than for practical use.
I am using HMAC_SHA256 inside a standard pbkdf2 function (part of OpenSSL). I have ended up with a choice between two designs for data model when it comes to deriving an AES key from a master password:
Store a pbkdf2 salt for each message, and derive a different AES key for each one.
Store a single pbkdf2 salt for the whole database, and derive a single AES key used for all the messages.
I am using a cryptographic RNG for salts and for initial values in AES 256 CBC. I store the salts and ivs in the clear in the database, the threat model is attacker has copy of all encrypted text, salts and ivs, but not the master password. Attacker is not able to request encryption, but they may observe any existing encryptions and may correctly guess one or more plaintexts.
As far as I can tell, both schemes have the same level of secrecy for the data at rest. The use of random initial values and the short messages mean that there is no real need to have a different key per message. There is no known plaintext attack that could take advantage of the fact that the key is shared in scheme 2. Both schemes support re-keying without changing the password, although I don't think that is particularly useful.
I think scheme 2 offers some advantages in performance - the costly pbkdf2 is only used once for multiple messages. It doesn't make brute-forcing the password any easier. It does mean ignoring the password and brute-forcing the key is potentially more damaging, but I think that is entirely unrealistic for AES 256, and that the password is the most vulnerable to attack secret in my project.
Have I missed anything? Is there some additional reason why I would choose one approach over the other?