[PATCH] cryptoloop: Fixing ECB Mode

From: Fruhwirth Clemens
Date: Sat Aug 09 2003 - 07:09:39 EST


Hi,

When cit_en/decrypt_iv has been introduced for cryptoapi,
cryptoloop_transfer has been changed unintentionally from a generic version
for ECB/CBC to CBC-specific code. This patch fixes this mistake.

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)

Attachment: pgp00003.pgp
Description: PGP signature