On Sat, Jul 23, 2022 at 08:52:28PM -0400, Sweet Tea Dorminy wrote:
Certain filesystems may want to use IVs generated and stored outside of
fscrypt's inode-based IV generation policies. In particular, btrfs can
have multiple inodes referencing a single block of data, and moves
logical data blocks to different physical locations on disk; these two
features mean inode or physical-location-based IV generation policies
will not work for btrfs. For these or similar reasons, such filesystems
may want to implement their own IV generation and storage for data
blocks.
Plumbing each such filesystem's internals into fscrypt for IV generation
would be ungainly and fragile. Thus, this change adds a new policy,
IV_FROM_FS, and a new operation function pointer, get_fs_derived_iv. If
this policy is selected, the filesystem is required to provide the
function pointer, which populates the IV for a particular data block.
The IV buffer passed to get_fs_derived_iv() is pre-populated with the
inode contexts' nonce, in case the filesystem would like to use this
information; for btrfs, this is used for filename encryption. Any
filesystem using this policy is expected to appropriately generate and
store a persistent random IV for each block of data.
This is changed from the original proposal to store just a random "starting IV"
per extent, right?
Given that this new proposal uses per-block metadata, has
support for authenticated encryption been considered? Has space been reserved
in the per-block metadata for authentication tags so that authenticated
encryption support could be added later even if it's not in the initial version?
I think you're imagining an interface similar to get/set_context, where the first time a block is written the filesystem's set_IV method is called, and subsequent encryption/decryption calls get_IV, which is definitely elegant in its symmetry. But I'm not sure how to have a per-block set_IV and also only store an IV per extent, and it would be a significant cost to store an IV per block.
Also, could the new IV generation method just be defined as RANDOM_IV instead of
IV_FROM_FS? Why do individual filesystems have to generate the IVs? Shouldn't
IV generation happen in common code, with filesystems just storing and
retrieving the IVs?