Fixing the cryptoloop driver
[Posted June 24, 2003 by corbet]
The Linux loop driver is a virtual disk driver which loops block I/O
requests back to a file or partition on a local drive. It has a number of
uses, such as mounting ISO images contained within a file on another
filesystem. The loop driver is also well positioned to apply
transformations to block data as it passes through, however. It is thus
a logical place for the implementation of encrypted filesystems.
By adding a cryptographic
transformation to the loop driver, encryption can be added to any standard
Linux filesystem without having to worry about the filesystem code itself.
An actual encrypted loop driver has never been packaged with the Linux kernel,
but implementation have long been available through sites like
kerneli.org.
In 2.5 the mainline kernel was opened up to cryptographic code. Numerous
ciphers and other algorithms have been added as part of the new crypto API,
but, so far, encryption has not been hooked into the loop driver.
Connecting up the components is not that hard at this point, but there is
one slightly thorny issue which still needs to be resolved.
Many ciphers can take an "initial vector" argument, along with the
encryption key and the data to encrypt (or decrypt). The initial vector
influences the encryption of the data;
the same initial vector must be supplied when that data is decrypted. For
filesystems, the initial vector is often derived from the position of
the data block within the filesystem, with the result that how data is
encrypted depends on its position on the (virtual) disk.
The Linux loop driver, while not performing encryption itself, has long had
a number of hooks to make it easier for others to plug in encryption
algorithms. One of the things the loop driver does is calculate and
provide an initial vector value for data transformations. This seems like
a useful service for the loop driver to provide, except that
nobody likes how that initial vector is calculated.
The problem is that the initial vector is derived from the logical
block number of the data in the filesystem holding the loopback image.
This method works until the block size of that filesystem changes; at that
point the initial vectors change and the filesystem becomes unreadable.
The loopback driver does, by behaving this way, achieve the objective of
protecting the data from prying eyes. But users can be hard to satisfy,
and they complain anyway.
The fix, as posted by Fruhwirth Clemens (or,
as part of a bigger loop patch by Andries Brouwer), is
simple. Rather than using block numbers to generate the initial vector,
the loop driver should simply use 512-byte sector offsets. With that
change, initial vectors are independent of the blocksize of the underlying
filesystem and all is well.
Except, of course, for those users who created filesystems using the
older initial vector calculation. A change in the initial vector will lock
all of those users out of their data, an act which is seen as being in poor
taste. As a result, some developers have argued that this change cannot be merged as it
is.
The real question, however, is whether anybody actually has filesystems
encrypted with block-based initial vectors. The kernel itself has not ever had
support for a cryptographic loop driver, so there is no compatibility with
older mainline kernels to break. The external projects which have provided
this support - loop-AES and kerneli - also noticed the initial vector
problem a long time ago and fixed it in their code. So it would seem
that, in fact, there are no users dependent on the older algorithm. In
that case, it makes a great deal of sense to fix it now, before somebody
does start using it in 2.6. If, on the other hand, somebody, somewhere
really has used the old initial vector calculation to encrypt data, they
may want to speak up fairly soon.
(
Log in to post comments)