tech-crypto archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Re: [patch] cgd



On Thu, Dec 02, 2010 at 05:21:30AM +0000, Roland C. Dowdeswell wrote:
> >                                       The best that you could do is
> >    force the attacker to have to rewind the entire disk to a previous
> >    state rather than simply rewinding sectors at a time or ciphertext
> >    blocks at a time given the constraints of the problem.  Using an
> >    HMAC can't completely solve this problem.
> > 
> > If you can force the attacker to rewind the entire disk, perhaps a
> > timestamp and on the disk could do the trick, if the user can remember
> > the last time he wrote to the disk.  However, I don't know how to
> > force the attacker to rewind the entire disk, at the disk layer.
> > (With cryptographic integrity checks in the file system, perhaps --
> > how's ZFS on NetBSD coming?)
> 
> I'm of the opinion that integrity checking best belongs in the file
> system layer because it necessarily involves increasing the size
> of the data which for a pseudo-disk is very expensive indeed.  If
> you decide to break a single disk write into multiple writes then
> you must also necessarily maintain state on the disk of what you
> are doing in case you crash in the midst of a write.  This would
> involve turning each single sector write into at least three separate
> writes.  At the file system layer, you have no such problem and
> can preserve performance while also ensuring integrity.  (Unless
> you can present 500 byte sectors to the rest of the kernel.)

GELI in FreeBSD does support integrity verification and you don't need
three writes. This best works when you increase sector size of the
decrypted disk-like device to eg. 4kB - this way you don't waste too
much space.

Let me paste comment of how it works from g_eli_integrity.c:

One of the most important assumption here is that authenticated data and its
HMAC has to be stored in the same place (namely in the same sector) to make it
work reliable.
The problem is that file systems work only with sectors that are multiple of
512 bytes and a power of two number.
My idea to implement it is as follows.
Let's store HMAC in sector. This is a must. This leaves us 480 bytes for
data. We can't use that directly (ie. we can't create provider with 480 bytes
sector size). We need another sector from where we take only 32 bytes of data
and we store HMAC of this data as well. This takes two sectors from the
original provider at the input and leaves us one sector of authenticated data
at the output. Not very efficient, but you got the idea.
Now, let's assume, we want to create provider with 4096 bytes sector.
To output 4096 bytes of authenticated data we need 8x480 plus 1x256, so we
need nine 512-bytes sectors at the input to get one 4096-bytes sector at the
output. That's better. With 4096 bytes sector we can use 89% of size of the
original provider. I find it as an acceptable cost.
The reliability comes from the fact, that every HMAC stored inside the sector
is calculated only for the data in the same sector, so its impossible to
write new data and leave old HMAC or vice versa.

And here is the picture:

da0: +----+----+ +----+----+ +----+----+ +----+----+ +----+----+ +----+----+ 
+----+----+ +----+----+ +----+-----+
     |32b |480b| |32b |480b| |32b |480b| |32b |480b| |32b |480b| |32b |480b| 
|32b |480b| |32b |480b| |32b |256b |
     |HMAC|Data| |HMAC|Data| |HMAC|Data| |HMAC|Data| |HMAC|Data| |HMAC|Data| 
|HMAC|Data| |HMAC|Data| |HMAC|Data |
     +----+----+ +----+----+ +----+----+ +----+----+ +----+----+ +----+----+ 
+----+----+ +----+----+ +----+-----+
     |512 bytes| |512 bytes| |512 bytes| |512 bytes| |512 bytes| |512 bytes| 
|512 bytes| |512 bytes| |288 bytes |
     +---------+ +---------+ +---------+ +---------+ +---------+ +---------+ 
+---------+ +---------+ |224 unused|
                                                                                
                     +----------+
da0.eli: +----+----+----+----+----+----+----+----+----+
         |480b|480b|480b|480b|480b|480b|480b|480b|256b|
         +----+----+----+----+----+----+----+----+----+
         |                 4096 bytes                 |
         +--------------------------------------------+

PS. You can use any sector size with geli(8). My example is using 4kB,
    because it's most efficient. For 8kB sectors you need 2 extra sectors,
    so the cost is the same as for 4kB sectors.

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
pjd%FreeBSD.org@localhost                           http://www.FreeBSD.org
FreeBSD committer                         Am I Evil? Yes, I Am!

Attachment: pgpuP_fhF19av.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index