aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2008-02-07 21:11:14 -0500
committerAlasdair G Kergon <agk@redhat.com>2008-02-07 21:11:14 -0500
commit3a7f6c990ad04e6f576a159876c602d14d6f7fef (patch)
treedc120485f8801050fa640f22c1bdeae1429728e0
parent95497a960015c89c7c585d5fb953bc2816dba1e5 (diff)
dm crypt: use async crypto
dm-crypt: Use crypto ablkcipher interface Move encrypt/decrypt core to async crypto call. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r--drivers/md/dm-crypt.c131
1 files changed, 72 insertions, 59 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index c45bd0e59dcc..b04f98df94ea 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -123,7 +123,7 @@ struct crypt_config {
123 123
124 char cipher[CRYPTO_MAX_ALG_NAME]; 124 char cipher[CRYPTO_MAX_ALG_NAME];
125 char chainmode[CRYPTO_MAX_ALG_NAME]; 125 char chainmode[CRYPTO_MAX_ALG_NAME];
126 struct crypto_blkcipher *tfm; 126 struct crypto_ablkcipher *tfm;
127 unsigned long flags; 127 unsigned long flags;
128 unsigned int key_size; 128 unsigned int key_size;
129 u8 key[0]; 129 u8 key[0];
@@ -217,7 +217,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
217 return PTR_ERR(essiv_tfm); 217 return PTR_ERR(essiv_tfm);
218 } 218 }
219 if (crypto_cipher_blocksize(essiv_tfm) != 219 if (crypto_cipher_blocksize(essiv_tfm) !=
220 crypto_blkcipher_ivsize(cc->tfm)) { 220 crypto_ablkcipher_ivsize(cc->tfm)) {
221 ti->error = "Block size of ESSIV cipher does " 221 ti->error = "Block size of ESSIV cipher does "
222 "not match IV size of block cipher"; 222 "not match IV size of block cipher";
223 crypto_free_cipher(essiv_tfm); 223 crypto_free_cipher(essiv_tfm);
@@ -254,7 +254,7 @@ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
254static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, 254static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
255 const char *opts) 255 const char *opts)
256{ 256{
257 unsigned int bs = crypto_blkcipher_blocksize(cc->tfm); 257 unsigned bs = crypto_ablkcipher_blocksize(cc->tfm);
258 int log = ilog2(bs); 258 int log = ilog2(bs);
259 259
260 /* we need to calculate how far we must shift the sector count 260 /* we need to calculate how far we must shift the sector count
@@ -318,38 +318,6 @@ static struct crypt_iv_operations crypt_iv_null_ops = {
318 .generator = crypt_iv_null_gen 318 .generator = crypt_iv_null_gen
319}; 319};
320 320
321static int
322crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
323 struct scatterlist *in, unsigned int length,
324 int write, sector_t sector)
325{
326 u8 iv[cc->iv_size] __attribute__ ((aligned(__alignof__(u64))));
327 struct blkcipher_desc desc = {
328 .tfm = cc->tfm,
329 .info = iv,
330 .flags = CRYPTO_TFM_REQ_MAY_SLEEP,
331 };
332 int r;
333
334 if (cc->iv_gen_ops) {
335 r = cc->iv_gen_ops->generator(cc, iv, sector);
336 if (r < 0)
337 return r;
338
339 if (write)
340 r = crypto_blkcipher_encrypt_iv(&desc, out, in, length);
341 else
342 r = crypto_blkcipher_decrypt_iv(&desc, out, in, length);
343 } else {
344 if (write)
345 r = crypto_blkcipher_encrypt(&desc, out, in, length);
346 else
347 r = crypto_blkcipher_decrypt(&desc, out, in, length);
348 }
349
350 return r;
351}
352
353static void crypt_convert_init(struct crypt_config *cc, 321static void crypt_convert_init(struct crypt_config *cc,
354 struct convert_context *ctx, 322 struct convert_context *ctx,
355 struct bio *bio_out, struct bio *bio_in, 323 struct bio *bio_out, struct bio *bio_in,
@@ -374,18 +342,25 @@ static void crypt_convert_init(struct crypt_config *cc,
374} 342}
375 343
376static int crypt_convert_block(struct crypt_config *cc, 344static int crypt_convert_block(struct crypt_config *cc,
377 struct convert_context *ctx) 345 struct convert_context *ctx,
346 struct ablkcipher_request *req)
378{ 347{
379 struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in); 348 struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
380 struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out); 349 struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
381 struct dm_crypt_request dmreq; 350 struct dm_crypt_request *dmreq;
351 u8 *iv;
352 int r = 0;
382 353
383 sg_init_table(&dmreq.sg_in, 1); 354 dmreq = (struct dm_crypt_request *)((char *)req + cc->dmreq_start);
384 sg_set_page(&dmreq.sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, 355 iv = (u8 *)ALIGN((unsigned long)(dmreq + 1),
356 crypto_ablkcipher_alignmask(cc->tfm) + 1);
357
358 sg_init_table(&dmreq->sg_in, 1);
359 sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT,
385 bv_in->bv_offset + ctx->offset_in); 360 bv_in->bv_offset + ctx->offset_in);
386 361
387 sg_init_table(&dmreq.sg_out, 1); 362 sg_init_table(&dmreq->sg_out, 1);
388 sg_set_page(&dmreq.sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT, 363 sg_set_page(&dmreq->sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT,
389 bv_out->bv_offset + ctx->offset_out); 364 bv_out->bv_offset + ctx->offset_out);
390 365
391 ctx->offset_in += 1 << SECTOR_SHIFT; 366 ctx->offset_in += 1 << SECTOR_SHIFT;
@@ -400,10 +375,21 @@ static int crypt_convert_block(struct crypt_config *cc,
400 ctx->idx_out++; 375 ctx->idx_out++;
401 } 376 }
402 377
403 return crypt_convert_scatterlist(cc, &dmreq.sg_out, &dmreq.sg_in, 378 if (cc->iv_gen_ops) {
404 dmreq.sg_in.length, 379 r = cc->iv_gen_ops->generator(cc, iv, ctx->sector);
405 bio_data_dir(ctx->bio_in) == WRITE, 380 if (r < 0)
406 ctx->sector); 381 return r;
382 }
383
384 ablkcipher_request_set_crypt(req, &dmreq->sg_in, &dmreq->sg_out,
385 1 << SECTOR_SHIFT, iv);
386
387 if (bio_data_dir(ctx->bio_in) == WRITE)
388 r = crypto_ablkcipher_encrypt(req);
389 else
390 r = crypto_ablkcipher_decrypt(req);
391
392 return r;
407} 393}
408 394
409static void kcryptd_async_done(struct crypto_async_request *async_req, 395static void kcryptd_async_done(struct crypto_async_request *async_req,
@@ -429,11 +415,27 @@ static int crypt_convert(struct crypt_config *cc,
429 415
430 while(ctx->idx_in < ctx->bio_in->bi_vcnt && 416 while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
431 ctx->idx_out < ctx->bio_out->bi_vcnt) { 417 ctx->idx_out < ctx->bio_out->bi_vcnt) {
432 r = crypt_convert_block(cc, ctx);
433 if (r < 0)
434 break;
435 418
436 ctx->sector++; 419 crypt_alloc_req(cc, ctx);
420
421 r = crypt_convert_block(cc, ctx, cc->req);
422
423 switch (r) {
424 case -EBUSY:
425 wait_for_completion(&ctx->restart);
426 INIT_COMPLETION(ctx->restart);
427 /* fall through*/
428 case -EINPROGRESS:
429 atomic_inc(&ctx->pending);
430 cc->req = NULL;
431 r = 0;
432 /* fall through*/
433 case 0:
434 ctx->sector++;
435 continue;
436 }
437
438 break;
437 } 439 }
438 440
439 /* 441 /*
@@ -696,9 +698,12 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
696 698
697 r = crypt_convert(cc, &io->ctx); 699 r = crypt_convert(cc, &io->ctx);
698 700
699 kcryptd_crypt_write_io_submit(io, r, 0); 701 if (r != -EINPROGRESS) {
700 if (unlikely(r < 0)) 702 kcryptd_crypt_write_io_submit(io, r, 0);
701 return; 703 if (unlikely(r < 0))
704 return;
705 } else
706 atomic_inc(&io->pending);
702 707
703 /* out of memory -> run queues */ 708 /* out of memory -> run queues */
704 if (unlikely(remaining)) 709 if (unlikely(remaining))
@@ -734,12 +739,17 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
734 struct crypt_config *cc = io->target->private; 739 struct crypt_config *cc = io->target->private;
735 int r = 0; 740 int r = 0;
736 741
742 atomic_inc(&io->pending);
743
737 crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, 744 crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio,
738 io->sector); 745 io->sector);
739 746
740 r = crypt_convert(cc, &io->ctx); 747 r = crypt_convert(cc, &io->ctx);
741 748
742 kcryptd_crypt_read_done(io, r); 749 if (r != -EINPROGRESS)
750 kcryptd_crypt_read_done(io, r);
751
752 crypt_dec_pending(io);
743} 753}
744 754
745static void kcryptd_async_done(struct crypto_async_request *async_req, 755static void kcryptd_async_done(struct crypto_async_request *async_req,
@@ -856,7 +866,7 @@ static int crypt_wipe_key(struct crypt_config *cc)
856static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) 866static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
857{ 867{
858 struct crypt_config *cc; 868 struct crypt_config *cc;
859 struct crypto_blkcipher *tfm; 869 struct crypto_ablkcipher *tfm;
860 char *tmp; 870 char *tmp;
861 char *cipher; 871 char *cipher;
862 char *chainmode; 872 char *chainmode;
@@ -910,7 +920,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
910 goto bad_cipher; 920 goto bad_cipher;
911 } 921 }
912 922
913 tfm = crypto_alloc_blkcipher(cc->cipher, 0, CRYPTO_ALG_ASYNC); 923 tfm = crypto_alloc_ablkcipher(cc->cipher, 0, 0);
914 if (IS_ERR(tfm)) { 924 if (IS_ERR(tfm)) {
915 ti->error = "Error allocating crypto tfm"; 925 ti->error = "Error allocating crypto tfm";
916 goto bad_cipher; 926 goto bad_cipher;
@@ -944,7 +954,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
944 cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0) 954 cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
945 goto bad_ivmode; 955 goto bad_ivmode;
946 956
947 cc->iv_size = crypto_blkcipher_ivsize(tfm); 957 cc->iv_size = crypto_ablkcipher_ivsize(tfm);
948 if (cc->iv_size) 958 if (cc->iv_size)
949 /* at least a 64 bit sector number should fit in our buffer */ 959 /* at least a 64 bit sector number should fit in our buffer */
950 cc->iv_size = max(cc->iv_size, 960 cc->iv_size = max(cc->iv_size,
@@ -965,7 +975,10 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
965 } 975 }
966 976
967 cc->dmreq_start = sizeof(struct ablkcipher_request); 977 cc->dmreq_start = sizeof(struct ablkcipher_request);
978 cc->dmreq_start += crypto_ablkcipher_reqsize(tfm);
968 cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment()); 979 cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment());
980 cc->dmreq_start += crypto_ablkcipher_alignmask(tfm) &
981 ~(crypto_tfm_ctx_alignment() - 1);
969 982
970 cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start + 983 cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start +
971 sizeof(struct dm_crypt_request) + cc->iv_size); 984 sizeof(struct dm_crypt_request) + cc->iv_size);
@@ -987,7 +1000,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
987 goto bad_bs; 1000 goto bad_bs;
988 } 1001 }
989 1002
990 if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) { 1003 if (crypto_ablkcipher_setkey(tfm, cc->key, key_size) < 0) {
991 ti->error = "Error setting key"; 1004 ti->error = "Error setting key";
992 goto bad_device; 1005 goto bad_device;
993 } 1006 }
@@ -1055,7 +1068,7 @@ bad_slab_pool:
1055 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) 1068 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
1056 cc->iv_gen_ops->dtr(cc); 1069 cc->iv_gen_ops->dtr(cc);
1057bad_ivmode: 1070bad_ivmode:
1058 crypto_free_blkcipher(tfm); 1071 crypto_free_ablkcipher(tfm);
1059bad_cipher: 1072bad_cipher:
1060 /* Must zero key material before freeing */ 1073 /* Must zero key material before freeing */
1061 memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8)); 1074 memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
@@ -1081,7 +1094,7 @@ static void crypt_dtr(struct dm_target *ti)
1081 kfree(cc->iv_mode); 1094 kfree(cc->iv_mode);
1082 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) 1095 if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
1083 cc->iv_gen_ops->dtr(cc); 1096 cc->iv_gen_ops->dtr(cc);
1084 crypto_free_blkcipher(cc->tfm); 1097 crypto_free_ablkcipher(cc->tfm);
1085 dm_put_device(ti, cc->dev); 1098 dm_put_device(ti, cc->dev);
1086 1099
1087 /* Must zero key material before freeing */ 1100 /* Must zero key material before freeing */