aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorRik Snel <rsnel@cube.dyndns.org>2006-09-02 18:56:39 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-06 21:38:47 -0500
commit48527fa7cf7fefb84e9fe03cddd08ddafc9f15f3 (patch)
tree38062656a96888f3f5dbbf2d74073a0159a39f69 /drivers/md
parent9fe757b0cfcee0724027a675c533077287a21b96 (diff)
[BLOCK] dm-crypt: benbi IV, big endian narrow block count for LRW-32-AES
LRW-32-AES needs a certain IV. This IV should be provided dm-crypt. The block cipher mode could, in principle generate the correct IV from the plain IV, but I think that it is cleaner to supply the right IV directly. The sector -> narrow block calculation uses a shift for performance reasons. This shift is computed in .ctr and stored in cc->iv_gen_private (as a void *). Signed-off-by: Rik Snel <rsnel@cube.dyndns.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index ed2d4ef27fd8..6dbaeee48ced 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -20,6 +20,7 @@
20#include <asm/atomic.h> 20#include <asm/atomic.h>
21#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
22#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/unaligned.h>
23 24
24#include "dm.h" 25#include "dm.h"
25 26
@@ -113,6 +114,9 @@ static kmem_cache_t *_crypt_io_pool;
113 * encrypted with the bulk cipher using a salt as key. The salt 114 * encrypted with the bulk cipher using a salt as key. The salt
114 * should be derived from the bulk cipher's key via hashing. 115 * should be derived from the bulk cipher's key via hashing.
115 * 116 *
117 * benbi: the 64-bit "big-endian 'narrow block'-count", starting at 1
118 * (needed for LRW-32-AES and possible other narrow block modes)
119 *
116 * plumb: unimplemented, see: 120 * plumb: unimplemented, see:
117 * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454 121 * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454
118 */ 122 */
@@ -209,6 +213,44 @@ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
209 return 0; 213 return 0;
210} 214}
211 215
216static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
217 const char *opts)
218{
219 unsigned int bs = crypto_blkcipher_blocksize(cc->tfm);
220 int log = long_log2(bs);
221
222 /* we need to calculate how far we must shift the sector count
223 * to get the cipher block count, we use this shift in _gen */
224
225 if (1 << log != bs) {
226 ti->error = "cypher blocksize is not a power of 2";
227 return -EINVAL;
228 }
229
230 if (log > 9) {
231 ti->error = "cypher blocksize is > 512";
232 return -EINVAL;
233 }
234
235 cc->iv_gen_private = (void *)(9 - log);
236
237 return 0;
238}
239
240static void crypt_iv_benbi_dtr(struct crypt_config *cc)
241{
242 cc->iv_gen_private = NULL;
243}
244
245static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
246{
247 memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */
248 put_unaligned(cpu_to_be64(((u64)sector << (u32)cc->iv_gen_private) + 1),
249 (__be64 *)(iv + cc->iv_size - sizeof(u64)));
250
251 return 0;
252}
253
212static struct crypt_iv_operations crypt_iv_plain_ops = { 254static struct crypt_iv_operations crypt_iv_plain_ops = {
213 .generator = crypt_iv_plain_gen 255 .generator = crypt_iv_plain_gen
214}; 256};
@@ -219,6 +261,11 @@ static struct crypt_iv_operations crypt_iv_essiv_ops = {
219 .generator = crypt_iv_essiv_gen 261 .generator = crypt_iv_essiv_gen
220}; 262};
221 263
264static struct crypt_iv_operations crypt_iv_benbi_ops = {
265 .ctr = crypt_iv_benbi_ctr,
266 .dtr = crypt_iv_benbi_dtr,
267 .generator = crypt_iv_benbi_gen
268};
222 269
223static int 270static int
224crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out, 271crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
@@ -768,7 +815,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
768 cc->tfm = tfm; 815 cc->tfm = tfm;
769 816
770 /* 817 /*
771 * Choose ivmode. Valid modes: "plain", "essiv:<esshash>". 818 * Choose ivmode. Valid modes: "plain", "essiv:<esshash>", "benbi".
772 * See comments at iv code 819 * See comments at iv code
773 */ 820 */
774 821
@@ -778,6 +825,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
778 cc->iv_gen_ops = &crypt_iv_plain_ops; 825 cc->iv_gen_ops = &crypt_iv_plain_ops;
779 else if (strcmp(ivmode, "essiv") == 0) 826 else if (strcmp(ivmode, "essiv") == 0)
780 cc->iv_gen_ops = &crypt_iv_essiv_ops; 827 cc->iv_gen_ops = &crypt_iv_essiv_ops;
828 else if (strcmp(ivmode, "benbi") == 0)
829 cc->iv_gen_ops = &crypt_iv_benbi_ops;
781 else { 830 else {
782 ti->error = "Invalid IV mode"; 831 ti->error = "Invalid IV mode";
783 goto bad2; 832 goto bad2;