Messages in this thread Patch in this message | | | Date | Sat, 9 Aug 2003 14:05:28 +0200 | Subject | [PATCH] cryptoloop: Fixing ECB Mode | From | Fruhwirth Clemens <> |
| |
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)[unhandled content-type:application/pgp-signature] | |