Key management and derivation - Allow changing of the passphrase I'm working on a program, which allows encrypting files before storing it on a cloud service. Currently I'm trying to figure out how to derive and store the keys.

First, I wanted to use a simple passphrase from which the file encryption keys are derived using PBKDF2HMAC and a file specific random salt. This helps providing unique nonce/key pairs, which is required for GCM mode.

Now one additional feature would allow changing the passphrase without re-encrypting and re-uploading all files. The new key derivation would look like this: The passphrase is used to generate a decryption key, again using PBKDF2HMAC with salt. This key can be used to unwrap a master key file, which is encrypted and authenticated using AES-KW. This master key is randomly generated and matches the key size used for file encryption. To generate unique keys for every file the master key is then XORed with a file specific random salt, which acts as a one-time-pad. To change the passphrase one would unwrap the master key and wrap it again using a different passphrase. I know that this technique does not allow revoking passphrases. Any previously used passphrase and master key file can still be used to decrypt the data.

While I am quite sure, that this method is secure (given that all random generated keys and salts are truly random) it seems a bit complex. Is there a reason to avoid the obvious extension to the first method? That is: Changable passphrase decrypts random master passphrase (using GCM mode), which again decrypts the files.
If you want to allow sharing of files between users without sharing their master key and/or pass phrase, you need to allow for something like this extra layer of "indirection" complexity.

However, per-file keys must be crated from HKDF(master_key, file_nonce) or a similar one-way key derivation function. Using simple XOR in this case would expose the master key to anyone with whom a per-file key is shared.

A file share would be simply taking the per-file key and wrapping it using some key known to the "destination" user. The "owning" user doesn't need this information, as they can always re-derive the per-file key using their master key and the per-file nonce.

Note that you will want to use a string such as "per-file key derivation" as the info parameter to HKDF to provide "domain separation". That is, you are using the source key and a nonce as input, and then deriving a key for a specific purpose. You don't want to generate the exact same key and use it for a different purpose later on, you would use for example a different info parameter if you were going to generate something else from the same master_key and file_nonce.