Actually, I changed my mind. Age uses the file key for at least three things:
1. HKDF with a random 128-bit nonce to derive the actual payload key.
2. HKDF with no nonce to derive the HMAC key for header authentication.
3. As input to every “recipient”.
I’m willing to believe that #1 is not subject to a multi-target attack and that this might even be provable.
I’m less willing to believe, without evidence, that #2 is safe. There isn’t an obvious (to me, on brief consideration) to, for example, tell whether two age files have the same HKDF output for the header key, but that’s only because the headers themselves are likely to differ for age files because the recipient stanzas are (presumably!) unlikely-to-collide functions of the file key.
I don’t like #3 at all. One could easily break multi-target security by having a DH recipient type that is just the identity to the power of file key. And I bet one could design a recipient type that looks reasonable on its own (and even has a security proof!) but breaks the system completely if two instances of the same recipient type are used in the same file.
If I were designing a v2, I would make two changes:
a) Either the file key is never used without a random nonce or the file key is >=256 bits, or both.
b) The recipient stanzas are not functions of the file key. Instead there is a per-stanza wrapping key that wraps the file key separately for each recipient.
The goal would be to enable a security proof that only needs to assume that each recipient stanza is independently secure.