lkml.org 
[lkml]   [2003]   [Jun]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
Subject[PATCH] Initial Vector Fix for loop.c.
From
Meta information: 

This mail proposes a fix for:
must-fix list item "drivers/block/loop.c" and
should-fix list item "drivers/block/cryptoloop"

Content:

loop.c is broken. It's broken since 2.4. In particular the initial vector
calculation which every cryptographic loop transformation uses is broken.

What's the problem you might ask.. It's that that the IV calculation is
based on the logical block sector of the block device. Just think of what
happends if you move your image to another device with a different block
size..

Correct! The IV metric changes and everyone who knows what's CBC
encryption will correctly conclude: you can't read your image.

That's bad. And that's the reason why every project which provides you with
encryption via loop.c will also provide you with a patch for this broken
loop.c behavior.

The fix is quite simple. Just switch to a fixed IV metric. Which is: the
smallest granulity -> fixed 512-byte and kerneli.org's cryptoloop as well as
Jari's loop-AES do exactly that.

These two packages are the only facilities I'm aware of that provides
harddisc encryption for the 2.4. kernel. However marcello refused to switch
the IV metric for 2.4. because it will - yes that's correct - break any
image which has been created with a IV-sensitiv loop transformation..

..BUT except for cryptoloop and loop-AES there are no such loop
transformation modules! And those two projects have already fixed this
issue. So we're providing backward compatiblity for nothing here. No user
base could ever benefit from this backward compatiblity, since the only
reason the initial vector calculation is done is for crypto and every crypto
project out there already uses the 512-byte IV-metric.

So go for it. Fix it before 2.6.x is out and we're stuck with this crap
again.

http://bugzilla.kernel.org/show_bug.cgi?id=192

Just apply the patch.

If this bug is fixed, we can go ahead and add cryptoloop which is ready and
tested.

Regards, Clemens
--- drivers/block/loop.c.orig Fri Jun 20 11:02:10 2003
+++ drivers/block/loop.c Fri Jun 20 11:02:49 2003
@@ -79,6 +79,8 @@

#include <asm/uaccess.h>

+#define LOOP_IV_SECTOR_BITS 9
+
static int max_loop = 8;
static struct loop_device *loop_dev;
static struct gendisk **disks;
@@ -196,7 +198,7 @@
data = kmap(bvec->bv_page) + bvec->bv_offset;
len = bvec->bv_len;
while (len > 0) {
- sector_t IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
+ sector_t IV = (index << (PAGE_CACHE_SHIFT - LOOP_IV_SECTOR_BITS)) + (offset >> LOOP_IV_SECTOR_BITS);
int transfer_result;

size = PAGE_CACHE_SIZE - offset;
@@ -279,7 +281,7 @@
unsigned long count = desc->count;
struct lo_read_data *p = (struct lo_read_data*)desc->buf;
struct loop_device *lo = p->lo;
- int IV = page->index * (PAGE_CACHE_SIZE/p->bsize) + offset/p->bsize;
+ int IV = (page->index << (PAGE_CACHE_SHIFT - LOOP_IV_SECTOR_BITS)) + (offset >> LOOP_IV_SECTOR_BITS);

if (size > count)
size = count;
@@ -484,7 +486,7 @@
bio_transfer(struct loop_device *lo, struct bio *to_bio,
struct bio *from_bio)
{
- unsigned long IV = loop_get_iv(lo, from_bio->bi_sector);
+ unsigned long IV = from_bio->bi_sector + (lo->lo_offset >> LOOP_IV_SECTOR_BITS);
struct bio_vec *from_bvec, *to_bvec;
char *vto, *vfrom;
int ret = 0, i;
@@ -545,7 +547,7 @@
* piggy old buffer on original, and submit for I/O
*/
new_bio = loop_get_buffer(lo, old_bio);
- IV = loop_get_iv(lo, old_bio->bi_sector);
+ IV = old_bio->bi_sector + (lo->lo_offset >> LOOP_IV_SECTOR_BITS);
if (rw == WRITE) {
if (bio_transfer(lo, new_bio, old_bio))
goto err;[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2005-03-22 13:36    [W:0.110 / U:0.060 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site