RFC: block/loop.c & crypto
A message that is not in the archive (sent off-list or not yet received): [email protected]
...moving it back to the kernel list...
Quoted 5 lines · Andrea Arcangeli
You don't read 1k. You only read 512bytes and you encrypt them using the IV of such 512byte block.
Then the next 512byte block will use again the same IV again. What's the problem?
ok, so I didn't understand you well in the first place :-)
you actually want only to change the IV calculation to be based on a hardcoded 1024 IV-blocksize, but don't change anything else in the loop.c module, right? (if not, ignore the following text... :-)
if so, I really don't like it;
1.) I really don't like to encode 2 512-blocks with the same IV, (I actually thought I could just switch to 1024-blocks and thus have it sensible again, but since you only change the IV calculation without changing the data-transfer granularity it won't work)
2.) It will break filesystems using set_blocksize(lo_dev, 512)... why?
say, we had a transfer request from the buffer cache requesting starting at byte 0 (initial IV=0) of the block device for length of 2048 bytes, this would lead to
transfer_filter (buf, bufsize=2048, IV=0);
since the transfer_filter contains the logic to split the buffer into chunks with the blocksize (e.g. 512 byte blocks) required*) for encryption the loop may look like:
int IV2 = IV << 1;
while (bufsize > 0) {
encdecfunc (buf, 512, IV2 >> 1);
IV2++;
buf += 512;
}which leads to the following calls for the mentioned example:
encdecfunc (buf, 512, 0); encdecfunc (buf+512, 512, 0); encdecfunc (buf+1024, 512, 1); encdecfunc (buf+1536, 512, 1);
so far so good; but now imagine that the original request get's changed a bit, to start at offset 512 (initial IV still 0!!) instead of offset 0;
transfer_filter (buf, bufsize=2048, IV=0); // the same values are
// passed for bufsize and IV!
encdecfunc (buf, 512, IV=0); // OK encdecfunc (buf+512, 512, IV=0); // wrong, IV should be 1 encdecfunc (buf+1024, 512, IV=1); // OK encdecfunc (buf+1536, 512, IV=1); // wrong, IV should be 2
...so you see?
that's why it's better IMHO to stick to the same IV-granularity that is used for transfers, otherwise you'd have to lose performance by passing only single IV-blocksize length data-blocks to the filter functions which need to be aligned...
*) actually only filters making use of the IV parameter would need to
split it up, other function may process bigger blocks at once, and thus minimizing possible overhead...
Quoted 5 lines
Quoted 2 lines
and btw, at least one other popular crypto loop filter uses 512 byte based IVs, namely loop-AES...
I guess it emulates it internally, so it should keep working if we do the fixed 1k granularity for the IV (while it should break the on-disk format if we do the 512byte granularity).
no, you can't emulate it internally if the passed IV is calculated based on a bigger IV-blocksize than the needed one... that's the problem, and why it's IMHO better to calculate based on the smallest used IV-blocksize :-( (that way you can always convert it to a bigger IV-blocksize based one)
regards,
Signature · 3 lines
Herbert Valerio Riedel / Phone: (EUROPE) +43-1-58801-18840 Email: [email protected] / Finger [email protected] for GnuPG Public Key GnuPG Key Fingerprint: 7BB9 2D6C D485 CE64 4748 5F65 4981 E064 883F 4142
Quoted 7 lines · Herbert Valerio Riedel
...moving it back to the kernel list...
Quoted 3 lines · Andrea Arcangeli
You don't read 1k. You only read 512bytes and you encrypt them using the IV of such 512byte block.
Quoted 7 lines
Quoted 2 lines
Then the next 512byte block will use again the same IV again. What's the problem?
ok, so I didn't understand you well in the first place :-)
you actually want only to change the IV calculation to be based on a hardcoded 1024 IV-blocksize, but don't change anything else in the
loop.cmodule, right? (if not, ignore the following text... :-)
yes
Quoted 7 lines
if so, I really don't like it;
1.) I really don't like to encode 2 512-blocks with the same IV, (I actually thought I could just switch to 1024-blocks and thus have it sensible again, but since you only change the IV calculation without changing the data-transfer granularity it won't work)
the only data transfer that you can be using right now is the one with softblocksize 1k (or you would not been able to mount the fs), so I don't change the IV granularity for those in use cryptoloops and that's why 1k is automatically backwards compatible and it will(/should ;) work.
Quoted 1 line
2.) It will break filesystems using
set_blocksize(lo_dev, 512)... why?
If a filesystem uses set_blocksize(512) you couldn't create it, this is why I'm saying 1k softblocksize should take care of the existing cryptoloops.
Quoted 2 lines
say, we had a transfer request from the buffer cache requesting starting at byte 0 (initial IV=0) of the block device for length of 2048 bytes,
the length will always be 512bytes because you said the softblocksize is 512.
Quoted 3 lines
this would lead to
transfer_filter (buf, bufsize=2048, IV=0);
bufsize will be 512.
Quoted 3 lines
since the
transfer_filtercontains the logic to split the buffer into chunks with the blocksize (e.g. 512 byte blocks) required*) for
but anyways even if bufsize could be 2048 I think the logic for the IV progression should be in the highlevel if something, not in the low layer because:
Quoted 8 lines
encryption the loop may look like:
int IV2 = IV << 1;
while (bufsize > 0) {
encdecfunc (buf, 512, IV2 >> 1);
IV2++;
buf += 512;
}the real cost is encdecfunc not the while(bufsize >0) loop, so you can also take a cleaner transfer API and have the knowledge of the granularity of the IV only in one place without duplicating the knowledge and the code of the logic in all the crypto plugins.
Andrea