[PATCH] cryptoloop: 2 fixes. resend

From: Fruhwirth Clemens
Date: Thu Aug 14 2003 - 07:31:43 EST


Hi!

Two fixes for cryptoloop:

Patch #1: Fixes ECB mode. cryptoloop won't oops anymore if ECB mode is
requested.

Patch #2: Fixes disk corruption under CBC mode caused by improper IV
calculation in loop.c. Tested:
http://marc.theaimsgroup.com/?t=106048335200003&r=1&w=2

Please apply.

Regards, Clemens
--- drivers/block/cryptoloop.c.orig Sun Jul 27 19:03:58 2003
+++ drivers/block/cryptoloop.c Sat Aug 9 13:51:03 2003
@@ -79,20 +79,70 @@
return err;
}

-typedef int (*encdec_t)(struct crypto_tfm *tfm,
+
+typedef int (*encdec_ecb_t)(struct crypto_tfm *tfm,
+ struct scatterlist *sg_out,
+ struct scatterlist *sg_in,
+ unsigned int nsg);
+
+
+static int
+cryptoloop_transfer_ecb(struct loop_device *lo, int cmd, char *raw_buf,
+ char *loop_buf, int size, sector_t IV)
+{
+ struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
+ struct scatterlist sg_out = { 0, };
+ struct scatterlist sg_in = { 0, };
+
+ encdec_ecb_t encdecfunc;
+ char const *in;
+ char *out;
+
+ if (cmd == READ) {
+ in = raw_buf;
+ out = loop_buf;
+ encdecfunc = tfm->crt_u.cipher.cit_decrypt;
+ } else {
+ in = loop_buf;
+ out = raw_buf;
+ encdecfunc = tfm->crt_u.cipher.cit_encrypt;
+ }
+
+ while (size > 0) {
+ const int sz = min(size, LOOP_IV_SECTOR_SIZE);
+
+ sg_in.page = virt_to_page(in);
+ sg_in.offset = (unsigned long)in & ~PAGE_MASK;
+ sg_in.length = sz;
+
+ sg_out.page = virt_to_page(out);
+ sg_out.offset = (unsigned long)out & ~PAGE_MASK;
+ sg_out.length = sz;
+
+ encdecfunc(tfm, &sg_out, &sg_in, sz);
+
+ size -= sz;
+ in += sz;
+ out += sz;
+ }
+
+ return 0;
+}
+
+typedef int (*encdec_cbc_t)(struct crypto_tfm *tfm,
struct scatterlist *sg_out,
struct scatterlist *sg_in,
unsigned int nsg, u8 *iv);

static int
-cryptoloop_transfer(struct loop_device *lo, int cmd, char *raw_buf,
+cryptoloop_transfer_cbc(struct loop_device *lo, int cmd, char *raw_buf,
char *loop_buf, int size, sector_t IV)
{
struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
struct scatterlist sg_out = { 0, };
struct scatterlist sg_in = { 0, };

- encdec_t encdecfunc;
+ encdec_cbc_t encdecfunc;
char const *in;
char *out;

@@ -130,6 +180,27 @@
return 0;
}

+static int
+cryptoloop_transfer(struct loop_device *lo, int cmd, char *raw_buf,
+ char *loop_buf, int size, sector_t IV)
+{
+ struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
+ if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB)
+ {
+ lo->transfer = cryptoloop_transfer_ecb;
+ return cryptoloop_transfer_ecb(lo, cmd, raw_buf, loop_buf, size, IV);
+ }
+ if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_CBC)
+ {
+ lo->transfer = cryptoloop_transfer_cbc;
+ return cryptoloop_transfer_cbc(lo, cmd, raw_buf, loop_buf, size, IV);
+ }
+
+ /* This is not supposed to happen */
+
+ printk( KERN_ERR "cryptoloop: unsupported cipher mode in cryptoloop_transfer!\n");
+ return -EINVAL;
+}

static int
cryptoloop_ioctl(struct loop_device *lo, int cmd, unsigned long arg)
--- drivers/block/loop.c~ Sun Jul 27 19:03:16 2003
+++ drivers/block/loop.c Sun Aug 10 04:22:44 2003
@@ -513,6 +513,7 @@
from_bvec->bv_len, IV);
kunmap(from_bvec->bv_page);
kunmap(to_bvec->bv_page);
+ IV += from_bvec->bv_len >> 9;
}

return ret;

Attachment: pgp00001.pgp
Description: PGP signature