Blame view

drivers/md/dm-crypt.c 44.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
   * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
542da3176   Milan Broz   dm crypt: make wi...
4
   * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
   *
   * This file is released under the GPL.
   */
43d690348   Milan Broz   dm crypt: add com...
8
  #include <linux/completion.h>
d1806f6a9   Herbert Xu   [BLOCK] dm-crypt:...
9
  #include <linux/err.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
13
14
15
16
17
18
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/bio.h>
  #include <linux/blkdev.h>
  #include <linux/mempool.h>
  #include <linux/slab.h>
  #include <linux/crypto.h>
  #include <linux/workqueue.h>
3fcfab16c   Andrew Morton   [PATCH] separate ...
19
  #include <linux/backing-dev.h>
c02977212   Andi Kleen   dm crypt: scale t...
20
  #include <linux/percpu.h>
60063497a   Arun Sharma   atomic: use <linu...
21
  #include <linux/atomic.h>
378f058cc   David Hardeman   [PATCH] Use sg_se...
22
  #include <linux/scatterlist.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  #include <asm/page.h>
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
24
  #include <asm/unaligned.h>
347457859   Milan Broz   dm crypt: add loo...
25
26
27
  #include <crypto/hash.h>
  #include <crypto/md5.h>
  #include <crypto/algapi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

586e80e6e   Mikulas Patocka   dm: remove dm hea...
29
  #include <linux/device-mapper.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30

72d948616   Alasdair G Kergon   [PATCH] dm: impro...
31
  #define DM_MSG_PREFIX "crypt"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
   * context holding the current state of a multi-part conversion
   */
  struct convert_context {
43d690348   Milan Broz   dm crypt: add com...
37
  	struct completion restart;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
41
42
43
44
  	struct bio *bio_in;
  	struct bio *bio_out;
  	unsigned int offset_in;
  	unsigned int offset_out;
  	unsigned int idx_in;
  	unsigned int idx_out;
  	sector_t sector;
43d690348   Milan Broz   dm crypt: add com...
45
  	atomic_t pending;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  };
53017030e   Milan Broz   dm crypt: move co...
47
48
49
50
51
52
53
54
55
56
57
58
  /*
   * per bio private data
   */
  struct dm_crypt_io {
  	struct dm_target *target;
  	struct bio *base_bio;
  	struct work_struct work;
  
  	struct convert_context ctx;
  
  	atomic_t pending;
  	int error;
0c395b0f8   Milan Broz   dm crypt: store s...
59
  	sector_t sector;
393b47ef2   Milan Broz   dm crypt: fix asy...
60
  	struct dm_crypt_io *base_io;
53017030e   Milan Broz   dm crypt: move co...
61
  };
01482b767   Milan Broz   dm crypt: extract...
62
  struct dm_crypt_request {
b2174eebd   Huang Ying   dm crypt: fix kcr...
63
  	struct convert_context *ctx;
01482b767   Milan Broz   dm crypt: extract...
64
65
  	struct scatterlist sg_in;
  	struct scatterlist sg_out;
2dc5327d3   Milan Broz   dm crypt: add pos...
66
  	sector_t iv_sector;
01482b767   Milan Broz   dm crypt: extract...
67
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
71
  struct crypt_config;
  
  struct crypt_iv_operations {
  	int (*ctr)(struct crypt_config *cc, struct dm_target *ti,
d469f8419   Milan Broz   dm crypt: tidy wh...
72
  		   const char *opts);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  	void (*dtr)(struct crypt_config *cc);
b95bf2d3d   Milan Broz   dm crypt: separat...
74
  	int (*init)(struct crypt_config *cc);
542da3176   Milan Broz   dm crypt: make wi...
75
  	int (*wipe)(struct crypt_config *cc);
2dc5327d3   Milan Broz   dm crypt: add pos...
76
77
78
79
  	int (*generator)(struct crypt_config *cc, u8 *iv,
  			 struct dm_crypt_request *dmreq);
  	int (*post)(struct crypt_config *cc, u8 *iv,
  		    struct dm_crypt_request *dmreq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
  };
604735927   Milan Broz   dm crypt: move pr...
81
  struct iv_essiv_private {
b95bf2d3d   Milan Broz   dm crypt: separat...
82
83
  	struct crypto_hash *hash_tfm;
  	u8 *salt;
604735927   Milan Broz   dm crypt: move pr...
84
85
86
87
88
  };
  
  struct iv_benbi_private {
  	int shift;
  };
347457859   Milan Broz   dm crypt: add loo...
89
90
91
92
93
  #define LMK_SEED_SIZE 64 /* hash + 0 */
  struct iv_lmk_private {
  	struct crypto_shash *hash_tfm;
  	u8 *seed;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
  /*
   * Crypt: maps a linear range of a block device
   * and encrypts / decrypts at the same time.
   */
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
98
  enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
c02977212   Andi Kleen   dm crypt: scale t...
99
100
101
102
103
104
  
  /*
   * Duplicated per-CPU state for cipher.
   */
  struct crypt_cpu {
  	struct ablkcipher_request *req;
c02977212   Andi Kleen   dm crypt: scale t...
105
106
  	/* ESSIV: struct crypto_cipher *essiv_tfm */
  	void *iv_private;
d1f964238   Milan Broz   dm crypt: add mul...
107
  	struct crypto_ablkcipher *tfms[0];
c02977212   Andi Kleen   dm crypt: scale t...
108
109
110
111
112
113
  };
  
  /*
   * The fields in here must be read only after initialization,
   * changing state should be in crypt_cpu.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
116
117
118
  struct crypt_config {
  	struct dm_dev *dev;
  	sector_t start;
  
  	/*
ddd42edfd   Milan Broz   dm crypt: add asy...
119
120
  	 * pool for per bio private data, crypto requests and
  	 * encryption requeusts/buffer pages
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
  	 */
  	mempool_t *io_pool;
ddd42edfd   Milan Broz   dm crypt: add asy...
123
  	mempool_t *req_pool;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  	mempool_t *page_pool;
6a24c7184   Milan Broz   [PATCH] dm crypt:...
125
  	struct bio_set *bs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126

cabf08e4d   Milan Broz   dm crypt: add pos...
127
128
  	struct workqueue_struct *io_queue;
  	struct workqueue_struct *crypt_queue;
3f1e9070f   Milan Broz   dm crypt: fix ctx...
129

5ebaee6d2   Milan Broz   dm crypt: simplif...
130
  	char *cipher;
7dbcd1374   Milan Broz   dm crypt: simplif...
131
  	char *cipher_string;
5ebaee6d2   Milan Broz   dm crypt: simplif...
132

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  	struct crypt_iv_operations *iv_gen_ops;
79066ad32   Herbert Xu   [CRYPTO] dm-crypt...
134
  	union {
604735927   Milan Broz   dm crypt: move pr...
135
136
  		struct iv_essiv_private essiv;
  		struct iv_benbi_private benbi;
347457859   Milan Broz   dm crypt: add loo...
137
  		struct iv_lmk_private lmk;
79066ad32   Herbert Xu   [CRYPTO] dm-crypt...
138
  	} iv_gen_private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
  	sector_t iv_offset;
  	unsigned int iv_size;
ddd42edfd   Milan Broz   dm crypt: add asy...
141
  	/*
c02977212   Andi Kleen   dm crypt: scale t...
142
143
144
145
  	 * Duplicated per cpu state. Access through
  	 * per_cpu_ptr() only.
  	 */
  	struct crypt_cpu __percpu *cpu;
d1f964238   Milan Broz   dm crypt: add mul...
146
  	unsigned tfms_count;
c02977212   Andi Kleen   dm crypt: scale t...
147
148
  
  	/*
ddd42edfd   Milan Broz   dm crypt: add asy...
149
150
151
152
153
154
155
156
157
158
159
160
161
  	 * Layout of each crypto request:
  	 *
  	 *   struct ablkcipher_request
  	 *      context
  	 *      padding
  	 *   struct dm_crypt_request
  	 *      padding
  	 *   IV
  	 *
  	 * The padding is added so that dm_crypt_request and the IV are
  	 * correctly aligned.
  	 */
  	unsigned int dmreq_start;
ddd42edfd   Milan Broz   dm crypt: add asy...
162

e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
163
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
  	unsigned int key_size;
d1f964238   Milan Broz   dm crypt: add mul...
165
  	unsigned int key_parts;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
  	u8 key[0];
  };
6a24c7184   Milan Broz   [PATCH] dm crypt:...
168
  #define MIN_IOS        16
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
170
  #define MIN_POOL_PAGES 32
  #define MIN_BIO_PAGES  8
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
171
  static struct kmem_cache *_crypt_io_pool;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172

028867ac2   Alasdair G Kergon   dm: use kmem_cach...
173
  static void clone_init(struct dm_crypt_io *, struct bio *);
395b167ca   Alasdair G Kergon   dm crypt: move qu...
174
  static void kcryptd_queue_crypt(struct dm_crypt_io *io);
2dc5327d3   Milan Broz   dm crypt: add pos...
175
  static u8 *iv_of_dmreq(struct crypt_config *cc, struct dm_crypt_request *dmreq);
027581f35   Olaf Kirch   dm crypt: fix cal...
176

c02977212   Andi Kleen   dm crypt: scale t...
177
178
179
180
181
182
183
184
185
186
  static struct crypt_cpu *this_crypt_config(struct crypt_config *cc)
  {
  	return this_cpu_ptr(cc->cpu);
  }
  
  /*
   * Use this to access cipher attributes that are the same for each CPU.
   */
  static struct crypto_ablkcipher *any_tfm(struct crypt_config *cc)
  {
d1f964238   Milan Broz   dm crypt: add mul...
187
  	return __this_cpu_ptr(cc->cpu)->tfms[0];
c02977212   Andi Kleen   dm crypt: scale t...
188
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
   * Different IV generation algorithms:
   *
3c164bd81   Rik Snel   [BLOCK] dm-crypt:...
192
   * plain: the initial vector is the 32-bit little-endian version of the sector
3a4fa0a25   Robert P. J. Day   Fix misspellings ...
193
   *        number, padded with zeros if necessary.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
   *
61afef614   Milan Broz   dm crypt: add pla...
195
196
197
   * plain64: the initial vector is the 64-bit little-endian version of the sector
   *        number, padded with zeros if necessary.
   *
3c164bd81   Rik Snel   [BLOCK] dm-crypt:...
198
199
200
   * essiv: "encrypted sector|salt initial vector", the sector number is
   *        encrypted with the bulk cipher using a salt as key. The salt
   *        should be derived from the bulk cipher's key via hashing.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
   *
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
202
203
204
   * benbi: the 64-bit "big-endian 'narrow block'-count", starting at 1
   *        (needed for LRW-32-AES and possible other narrow block modes)
   *
46b477306   Ludwig Nussel   dm crypt: add nul...
205
206
207
   * null: the initial vector is always zero.  Provides compatibility with
   *       obsolete loop_fish2 devices.  Do not use for new devices.
   *
347457859   Milan Broz   dm crypt: add loo...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
   * lmk:  Compatible implementation of the block chaining mode used
   *       by the Loop-AES block device encryption system
   *       designed by Jari Ruusu. See http://loop-aes.sourceforge.net/
   *       It operates on full 512 byte sectors and uses CBC
   *       with an IV derived from the sector number, the data and
   *       optionally extra IV seed.
   *       This means that after decryption the first block
   *       of sector must be tweaked according to decrypted data.
   *       Loop-AES can use three encryption schemes:
   *         version 1: is plain aes-cbc mode
   *         version 2: uses 64 multikey scheme with lmk IV generator
   *         version 3: the same as version 2 with additional IV seed
   *                   (it uses 65 keys, last key is used as IV seed)
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
223
224
   * plumb: unimplemented, see:
   * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454
   */
2dc5327d3   Milan Broz   dm crypt: add pos...
225
226
  static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv,
  			      struct dm_crypt_request *dmreq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
228
  {
  	memset(iv, 0, cc->iv_size);
283a8328c   Alasdair G Kergon   dm: suppress endi...
229
  	*(__le32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
  
  	return 0;
  }
61afef614   Milan Broz   dm crypt: add pla...
233
  static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv,
2dc5327d3   Milan Broz   dm crypt: add pos...
234
  				struct dm_crypt_request *dmreq)
61afef614   Milan Broz   dm crypt: add pla...
235
236
  {
  	memset(iv, 0, cc->iv_size);
283a8328c   Alasdair G Kergon   dm: suppress endi...
237
  	*(__le64 *)iv = cpu_to_le64(dmreq->iv_sector);
61afef614   Milan Broz   dm crypt: add pla...
238
239
240
  
  	return 0;
  }
b95bf2d3d   Milan Broz   dm crypt: separat...
241
242
243
244
245
246
  /* Initialise ESSIV - compute salt but no local memory allocations */
  static int crypt_iv_essiv_init(struct crypt_config *cc)
  {
  	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
  	struct hash_desc desc;
  	struct scatterlist sg;
c02977212   Andi Kleen   dm crypt: scale t...
247
248
  	struct crypto_cipher *essiv_tfm;
  	int err, cpu;
b95bf2d3d   Milan Broz   dm crypt: separat...
249
250
251
252
253
254
255
256
  
  	sg_init_one(&sg, cc->key, cc->key_size);
  	desc.tfm = essiv->hash_tfm;
  	desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
  
  	err = crypto_hash_digest(&desc, &sg, cc->key_size, essiv->salt);
  	if (err)
  		return err;
c02977212   Andi Kleen   dm crypt: scale t...
257
258
259
260
  	for_each_possible_cpu(cpu) {
  		essiv_tfm = per_cpu_ptr(cc->cpu, cpu)->iv_private,
  
  		err = crypto_cipher_setkey(essiv_tfm, essiv->salt,
b95bf2d3d   Milan Broz   dm crypt: separat...
261
  				    crypto_hash_digestsize(essiv->hash_tfm));
c02977212   Andi Kleen   dm crypt: scale t...
262
263
264
265
266
  		if (err)
  			return err;
  	}
  
  	return 0;
b95bf2d3d   Milan Broz   dm crypt: separat...
267
  }
542da3176   Milan Broz   dm crypt: make wi...
268
269
270
271
272
  /* Wipe salt and reset key derived from volume key */
  static int crypt_iv_essiv_wipe(struct crypt_config *cc)
  {
  	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
  	unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm);
c02977212   Andi Kleen   dm crypt: scale t...
273
274
  	struct crypto_cipher *essiv_tfm;
  	int cpu, r, err = 0;
542da3176   Milan Broz   dm crypt: make wi...
275
276
  
  	memset(essiv->salt, 0, salt_size);
c02977212   Andi Kleen   dm crypt: scale t...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
  	for_each_possible_cpu(cpu) {
  		essiv_tfm = per_cpu_ptr(cc->cpu, cpu)->iv_private;
  		r = crypto_cipher_setkey(essiv_tfm, essiv->salt, salt_size);
  		if (r)
  			err = r;
  	}
  
  	return err;
  }
  
  /* Set up per cpu cipher state */
  static struct crypto_cipher *setup_essiv_cpu(struct crypt_config *cc,
  					     struct dm_target *ti,
  					     u8 *salt, unsigned saltsize)
  {
  	struct crypto_cipher *essiv_tfm;
  	int err;
  
  	/* Setup the essiv_tfm with the given salt */
  	essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
  	if (IS_ERR(essiv_tfm)) {
  		ti->error = "Error allocating crypto tfm for ESSIV";
  		return essiv_tfm;
  	}
  
  	if (crypto_cipher_blocksize(essiv_tfm) !=
  	    crypto_ablkcipher_ivsize(any_tfm(cc))) {
  		ti->error = "Block size of ESSIV cipher does "
  			    "not match IV size of block cipher";
  		crypto_free_cipher(essiv_tfm);
  		return ERR_PTR(-EINVAL);
  	}
  
  	err = crypto_cipher_setkey(essiv_tfm, salt, saltsize);
  	if (err) {
  		ti->error = "Failed to set key for ESSIV cipher";
  		crypto_free_cipher(essiv_tfm);
  		return ERR_PTR(err);
  	}
  
  	return essiv_tfm;
542da3176   Milan Broz   dm crypt: make wi...
318
  }
604735927   Milan Broz   dm crypt: move pr...
319
320
  static void crypt_iv_essiv_dtr(struct crypt_config *cc)
  {
c02977212   Andi Kleen   dm crypt: scale t...
321
322
323
  	int cpu;
  	struct crypt_cpu *cpu_cc;
  	struct crypto_cipher *essiv_tfm;
604735927   Milan Broz   dm crypt: move pr...
324
  	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
b95bf2d3d   Milan Broz   dm crypt: separat...
325
326
327
328
329
  	crypto_free_hash(essiv->hash_tfm);
  	essiv->hash_tfm = NULL;
  
  	kzfree(essiv->salt);
  	essiv->salt = NULL;
c02977212   Andi Kleen   dm crypt: scale t...
330
331
332
333
334
335
336
337
338
339
  
  	for_each_possible_cpu(cpu) {
  		cpu_cc = per_cpu_ptr(cc->cpu, cpu);
  		essiv_tfm = cpu_cc->iv_private;
  
  		if (essiv_tfm)
  			crypto_free_cipher(essiv_tfm);
  
  		cpu_cc->iv_private = NULL;
  	}
604735927   Milan Broz   dm crypt: move pr...
340
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
  static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
d469f8419   Milan Broz   dm crypt: tidy wh...
342
  			      const char *opts)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
  {
5861f1be0   Milan Broz   dm crypt: restruc...
344
345
  	struct crypto_cipher *essiv_tfm = NULL;
  	struct crypto_hash *hash_tfm = NULL;
5861f1be0   Milan Broz   dm crypt: restruc...
346
  	u8 *salt = NULL;
c02977212   Andi Kleen   dm crypt: scale t...
347
  	int err, cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348

5861f1be0   Milan Broz   dm crypt: restruc...
349
  	if (!opts) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
350
  		ti->error = "Digest algorithm missing for ESSIV mode";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
  		return -EINVAL;
  	}
b95bf2d3d   Milan Broz   dm crypt: separat...
353
  	/* Allocate hash algorithm */
350586879   Herbert Xu   [CRYPTO] users: U...
354
355
  	hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC);
  	if (IS_ERR(hash_tfm)) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
356
  		ti->error = "Error initializing ESSIV hash";
5861f1be0   Milan Broz   dm crypt: restruc...
357
358
  		err = PTR_ERR(hash_tfm);
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
  	}
b95bf2d3d   Milan Broz   dm crypt: separat...
360
  	salt = kzalloc(crypto_hash_digestsize(hash_tfm), GFP_KERNEL);
5861f1be0   Milan Broz   dm crypt: restruc...
361
  	if (!salt) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
362
  		ti->error = "Error kmallocing salt storage in ESSIV";
5861f1be0   Milan Broz   dm crypt: restruc...
363
364
  		err = -ENOMEM;
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  	}
b95bf2d3d   Milan Broz   dm crypt: separat...
366
  	cc->iv_gen_private.essiv.salt = salt;
b95bf2d3d   Milan Broz   dm crypt: separat...
367
  	cc->iv_gen_private.essiv.hash_tfm = hash_tfm;
c02977212   Andi Kleen   dm crypt: scale t...
368
369
370
371
372
373
374
375
376
  	for_each_possible_cpu(cpu) {
  		essiv_tfm = setup_essiv_cpu(cc, ti, salt,
  					crypto_hash_digestsize(hash_tfm));
  		if (IS_ERR(essiv_tfm)) {
  			crypt_iv_essiv_dtr(cc);
  			return PTR_ERR(essiv_tfm);
  		}
  		per_cpu_ptr(cc->cpu, cpu)->iv_private = essiv_tfm;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  	return 0;
5861f1be0   Milan Broz   dm crypt: restruc...
378
379
  
  bad:
5861f1be0   Milan Broz   dm crypt: restruc...
380
381
  	if (hash_tfm && !IS_ERR(hash_tfm))
  		crypto_free_hash(hash_tfm);
b95bf2d3d   Milan Broz   dm crypt: separat...
382
  	kfree(salt);
5861f1be0   Milan Broz   dm crypt: restruc...
383
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
  }
2dc5327d3   Milan Broz   dm crypt: add pos...
385
386
  static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv,
  			      struct dm_crypt_request *dmreq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
  {
c02977212   Andi Kleen   dm crypt: scale t...
388
  	struct crypto_cipher *essiv_tfm = this_crypt_config(cc)->iv_private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  	memset(iv, 0, cc->iv_size);
283a8328c   Alasdair G Kergon   dm: suppress endi...
390
  	*(__le64 *)iv = cpu_to_le64(dmreq->iv_sector);
c02977212   Andi Kleen   dm crypt: scale t...
391
  	crypto_cipher_encrypt_one(essiv_tfm, iv, iv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
393
  	return 0;
  }
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
394
395
396
  static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
  			      const char *opts)
  {
c02977212   Andi Kleen   dm crypt: scale t...
397
  	unsigned bs = crypto_ablkcipher_blocksize(any_tfm(cc));
f0d1b0b30   David Howells   [PATCH] LOG2: Imp...
398
  	int log = ilog2(bs);
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
399
400
401
402
403
404
405
406
407
408
409
410
411
  
  	/* we need to calculate how far we must shift the sector count
  	 * to get the cipher block count, we use this shift in _gen */
  
  	if (1 << log != bs) {
  		ti->error = "cypher blocksize is not a power of 2";
  		return -EINVAL;
  	}
  
  	if (log > 9) {
  		ti->error = "cypher blocksize is > 512";
  		return -EINVAL;
  	}
604735927   Milan Broz   dm crypt: move pr...
412
  	cc->iv_gen_private.benbi.shift = 9 - log;
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
413
414
415
416
417
418
  
  	return 0;
  }
  
  static void crypt_iv_benbi_dtr(struct crypt_config *cc)
  {
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
419
  }
2dc5327d3   Milan Broz   dm crypt: add pos...
420
421
  static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv,
  			      struct dm_crypt_request *dmreq)
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
422
  {
79066ad32   Herbert Xu   [CRYPTO] dm-crypt...
423
  	__be64 val;
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
424
  	memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */
79066ad32   Herbert Xu   [CRYPTO] dm-crypt...
425

2dc5327d3   Milan Broz   dm crypt: add pos...
426
  	val = cpu_to_be64(((u64)dmreq->iv_sector << cc->iv_gen_private.benbi.shift) + 1);
79066ad32   Herbert Xu   [CRYPTO] dm-crypt...
427
  	put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64)));
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
428

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
429
430
  	return 0;
  }
2dc5327d3   Milan Broz   dm crypt: add pos...
431
432
  static int crypt_iv_null_gen(struct crypt_config *cc, u8 *iv,
  			     struct dm_crypt_request *dmreq)
46b477306   Ludwig Nussel   dm crypt: add nul...
433
434
435
436
437
  {
  	memset(iv, 0, cc->iv_size);
  
  	return 0;
  }
347457859   Milan Broz   dm crypt: add loo...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
  static void crypt_iv_lmk_dtr(struct crypt_config *cc)
  {
  	struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;
  
  	if (lmk->hash_tfm && !IS_ERR(lmk->hash_tfm))
  		crypto_free_shash(lmk->hash_tfm);
  	lmk->hash_tfm = NULL;
  
  	kzfree(lmk->seed);
  	lmk->seed = NULL;
  }
  
  static int crypt_iv_lmk_ctr(struct crypt_config *cc, struct dm_target *ti,
  			    const char *opts)
  {
  	struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;
  
  	lmk->hash_tfm = crypto_alloc_shash("md5", 0, 0);
  	if (IS_ERR(lmk->hash_tfm)) {
  		ti->error = "Error initializing LMK hash";
  		return PTR_ERR(lmk->hash_tfm);
  	}
  
  	/* No seed in LMK version 2 */
  	if (cc->key_parts == cc->tfms_count) {
  		lmk->seed = NULL;
  		return 0;
  	}
  
  	lmk->seed = kzalloc(LMK_SEED_SIZE, GFP_KERNEL);
  	if (!lmk->seed) {
  		crypt_iv_lmk_dtr(cc);
  		ti->error = "Error kmallocing seed storage in LMK";
  		return -ENOMEM;
  	}
  
  	return 0;
  }
  
  static int crypt_iv_lmk_init(struct crypt_config *cc)
  {
  	struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;
  	int subkey_size = cc->key_size / cc->key_parts;
  
  	/* LMK seed is on the position of LMK_KEYS + 1 key */
  	if (lmk->seed)
  		memcpy(lmk->seed, cc->key + (cc->tfms_count * subkey_size),
  		       crypto_shash_digestsize(lmk->hash_tfm));
  
  	return 0;
  }
  
  static int crypt_iv_lmk_wipe(struct crypt_config *cc)
  {
  	struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;
  
  	if (lmk->seed)
  		memset(lmk->seed, 0, LMK_SEED_SIZE);
  
  	return 0;
  }
  
  static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,
  			    struct dm_crypt_request *dmreq,
  			    u8 *data)
  {
  	struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;
  	struct {
  		struct shash_desc desc;
  		char ctx[crypto_shash_descsize(lmk->hash_tfm)];
  	} sdesc;
  	struct md5_state md5state;
  	u32 buf[4];
  	int i, r;
  
  	sdesc.desc.tfm = lmk->hash_tfm;
  	sdesc.desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
  
  	r = crypto_shash_init(&sdesc.desc);
  	if (r)
  		return r;
  
  	if (lmk->seed) {
  		r = crypto_shash_update(&sdesc.desc, lmk->seed, LMK_SEED_SIZE);
  		if (r)
  			return r;
  	}
  
  	/* Sector is always 512B, block size 16, add data of blocks 1-31 */
  	r = crypto_shash_update(&sdesc.desc, data + 16, 16 * 31);
  	if (r)
  		return r;
  
  	/* Sector is cropped to 56 bits here */
  	buf[0] = cpu_to_le32(dmreq->iv_sector & 0xFFFFFFFF);
  	buf[1] = cpu_to_le32((((u64)dmreq->iv_sector >> 32) & 0x00FFFFFF) | 0x80000000);
  	buf[2] = cpu_to_le32(4024);
  	buf[3] = 0;
  	r = crypto_shash_update(&sdesc.desc, (u8 *)buf, sizeof(buf));
  	if (r)
  		return r;
  
  	/* No MD5 padding here */
  	r = crypto_shash_export(&sdesc.desc, &md5state);
  	if (r)
  		return r;
  
  	for (i = 0; i < MD5_HASH_WORDS; i++)
  		__cpu_to_le32s(&md5state.hash[i]);
  	memcpy(iv, &md5state.hash, cc->iv_size);
  
  	return 0;
  }
  
  static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv,
  			    struct dm_crypt_request *dmreq)
  {
  	u8 *src;
  	int r = 0;
  
  	if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) {
  		src = kmap_atomic(sg_page(&dmreq->sg_in), KM_USER0);
  		r = crypt_iv_lmk_one(cc, iv, dmreq, src + dmreq->sg_in.offset);
  		kunmap_atomic(src, KM_USER0);
  	} else
  		memset(iv, 0, cc->iv_size);
  
  	return r;
  }
  
  static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv,
  			     struct dm_crypt_request *dmreq)
  {
  	u8 *dst;
  	int r;
  
  	if (bio_data_dir(dmreq->ctx->bio_in) == WRITE)
  		return 0;
  
  	dst = kmap_atomic(sg_page(&dmreq->sg_out), KM_USER0);
  	r = crypt_iv_lmk_one(cc, iv, dmreq, dst + dmreq->sg_out.offset);
  
  	/* Tweak the first block of plaintext sector */
  	if (!r)
  		crypto_xor(dst + dmreq->sg_out.offset, iv, cc->iv_size);
  
  	kunmap_atomic(dst, KM_USER0);
  	return r;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
589
  static struct crypt_iv_operations crypt_iv_plain_ops = {
  	.generator = crypt_iv_plain_gen
  };
61afef614   Milan Broz   dm crypt: add pla...
590
591
592
  static struct crypt_iv_operations crypt_iv_plain64_ops = {
  	.generator = crypt_iv_plain64_gen
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
595
  static struct crypt_iv_operations crypt_iv_essiv_ops = {
  	.ctr       = crypt_iv_essiv_ctr,
  	.dtr       = crypt_iv_essiv_dtr,
b95bf2d3d   Milan Broz   dm crypt: separat...
596
  	.init      = crypt_iv_essiv_init,
542da3176   Milan Broz   dm crypt: make wi...
597
  	.wipe      = crypt_iv_essiv_wipe,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
  	.generator = crypt_iv_essiv_gen
  };
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
600
601
602
603
604
  static struct crypt_iv_operations crypt_iv_benbi_ops = {
  	.ctr	   = crypt_iv_benbi_ctr,
  	.dtr	   = crypt_iv_benbi_dtr,
  	.generator = crypt_iv_benbi_gen
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605

46b477306   Ludwig Nussel   dm crypt: add nul...
606
607
608
  static struct crypt_iv_operations crypt_iv_null_ops = {
  	.generator = crypt_iv_null_gen
  };
347457859   Milan Broz   dm crypt: add loo...
609
610
611
612
613
614
615
616
  static struct crypt_iv_operations crypt_iv_lmk_ops = {
  	.ctr	   = crypt_iv_lmk_ctr,
  	.dtr	   = crypt_iv_lmk_dtr,
  	.init	   = crypt_iv_lmk_init,
  	.wipe	   = crypt_iv_lmk_wipe,
  	.generator = crypt_iv_lmk_gen,
  	.post	   = crypt_iv_lmk_post
  };
d469f8419   Milan Broz   dm crypt: tidy wh...
617
618
619
  static void crypt_convert_init(struct crypt_config *cc,
  			       struct convert_context *ctx,
  			       struct bio *bio_out, struct bio *bio_in,
fcd369daa   Milan Broz   dm crypt: remove ...
620
  			       sector_t sector)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621
622
623
624
625
626
627
628
  {
  	ctx->bio_in = bio_in;
  	ctx->bio_out = bio_out;
  	ctx->offset_in = 0;
  	ctx->offset_out = 0;
  	ctx->idx_in = bio_in ? bio_in->bi_idx : 0;
  	ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
  	ctx->sector = sector + cc->iv_offset;
43d690348   Milan Broz   dm crypt: add com...
629
  	init_completion(&ctx->restart);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
  }
b2174eebd   Huang Ying   dm crypt: fix kcr...
631
632
633
634
635
636
637
638
639
640
641
  static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc,
  					     struct ablkcipher_request *req)
  {
  	return (struct dm_crypt_request *)((char *)req + cc->dmreq_start);
  }
  
  static struct ablkcipher_request *req_of_dmreq(struct crypt_config *cc,
  					       struct dm_crypt_request *dmreq)
  {
  	return (struct ablkcipher_request *)((char *)dmreq - cc->dmreq_start);
  }
2dc5327d3   Milan Broz   dm crypt: add pos...
642
643
644
645
646
647
  static u8 *iv_of_dmreq(struct crypt_config *cc,
  		       struct dm_crypt_request *dmreq)
  {
  	return (u8 *)ALIGN((unsigned long)(dmreq + 1),
  		crypto_ablkcipher_alignmask(any_tfm(cc)) + 1);
  }
01482b767   Milan Broz   dm crypt: extract...
648
  static int crypt_convert_block(struct crypt_config *cc,
3a7f6c990   Milan Broz   dm crypt: use asy...
649
650
  			       struct convert_context *ctx,
  			       struct ablkcipher_request *req)
01482b767   Milan Broz   dm crypt: extract...
651
652
653
  {
  	struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
  	struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
3a7f6c990   Milan Broz   dm crypt: use asy...
654
655
656
  	struct dm_crypt_request *dmreq;
  	u8 *iv;
  	int r = 0;
b2174eebd   Huang Ying   dm crypt: fix kcr...
657
  	dmreq = dmreq_of_req(cc, req);
2dc5327d3   Milan Broz   dm crypt: add pos...
658
  	iv = iv_of_dmreq(cc, dmreq);
01482b767   Milan Broz   dm crypt: extract...
659

2dc5327d3   Milan Broz   dm crypt: add pos...
660
  	dmreq->iv_sector = ctx->sector;
b2174eebd   Huang Ying   dm crypt: fix kcr...
661
  	dmreq->ctx = ctx;
3a7f6c990   Milan Broz   dm crypt: use asy...
662
663
  	sg_init_table(&dmreq->sg_in, 1);
  	sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT,
01482b767   Milan Broz   dm crypt: extract...
664
  		    bv_in->bv_offset + ctx->offset_in);
3a7f6c990   Milan Broz   dm crypt: use asy...
665
666
  	sg_init_table(&dmreq->sg_out, 1);
  	sg_set_page(&dmreq->sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT,
01482b767   Milan Broz   dm crypt: extract...
667
668
669
670
671
672
673
674
675
676
677
678
679
  		    bv_out->bv_offset + ctx->offset_out);
  
  	ctx->offset_in += 1 << SECTOR_SHIFT;
  	if (ctx->offset_in >= bv_in->bv_len) {
  		ctx->offset_in = 0;
  		ctx->idx_in++;
  	}
  
  	ctx->offset_out += 1 << SECTOR_SHIFT;
  	if (ctx->offset_out >= bv_out->bv_len) {
  		ctx->offset_out = 0;
  		ctx->idx_out++;
  	}
3a7f6c990   Milan Broz   dm crypt: use asy...
680
  	if (cc->iv_gen_ops) {
2dc5327d3   Milan Broz   dm crypt: add pos...
681
  		r = cc->iv_gen_ops->generator(cc, iv, dmreq);
3a7f6c990   Milan Broz   dm crypt: use asy...
682
683
684
685
686
687
688
689
690
691
692
  		if (r < 0)
  			return r;
  	}
  
  	ablkcipher_request_set_crypt(req, &dmreq->sg_in, &dmreq->sg_out,
  				     1 << SECTOR_SHIFT, iv);
  
  	if (bio_data_dir(ctx->bio_in) == WRITE)
  		r = crypto_ablkcipher_encrypt(req);
  	else
  		r = crypto_ablkcipher_decrypt(req);
2dc5327d3   Milan Broz   dm crypt: add pos...
693
694
  	if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post)
  		r = cc->iv_gen_ops->post(cc, iv, dmreq);
3a7f6c990   Milan Broz   dm crypt: use asy...
695
  	return r;
01482b767   Milan Broz   dm crypt: extract...
696
  }
95497a960   Milan Broz   dm crypt: prepare...
697
698
  static void kcryptd_async_done(struct crypto_async_request *async_req,
  			       int error);
c02977212   Andi Kleen   dm crypt: scale t...
699

ddd42edfd   Milan Broz   dm crypt: add asy...
700
701
702
  static void crypt_alloc_req(struct crypt_config *cc,
  			    struct convert_context *ctx)
  {
c02977212   Andi Kleen   dm crypt: scale t...
703
  	struct crypt_cpu *this_cc = this_crypt_config(cc);
d1f964238   Milan Broz   dm crypt: add mul...
704
  	unsigned key_index = ctx->sector & (cc->tfms_count - 1);
c02977212   Andi Kleen   dm crypt: scale t...
705
706
707
  
  	if (!this_cc->req)
  		this_cc->req = mempool_alloc(cc->req_pool, GFP_NOIO);
d1f964238   Milan Broz   dm crypt: add mul...
708
  	ablkcipher_request_set_tfm(this_cc->req, this_cc->tfms[key_index]);
c02977212   Andi Kleen   dm crypt: scale t...
709
710
711
  	ablkcipher_request_set_callback(this_cc->req,
  	    CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
  	    kcryptd_async_done, dmreq_of_req(cc, this_cc->req));
ddd42edfd   Milan Broz   dm crypt: add asy...
712
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
714
715
716
  /*
   * Encrypt / decrypt data from one bio to another one (can be the same one)
   */
  static int crypt_convert(struct crypt_config *cc,
d469f8419   Milan Broz   dm crypt: tidy wh...
717
  			 struct convert_context *ctx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718
  {
c02977212   Andi Kleen   dm crypt: scale t...
719
  	struct crypt_cpu *this_cc = this_crypt_config(cc);
3f1e9070f   Milan Broz   dm crypt: fix ctx...
720
  	int r;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721

c8081618a   Milan Broz   dm crypt: tidy ct...
722
  	atomic_set(&ctx->pending, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
724
  	while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
  	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
725

3a7f6c990   Milan Broz   dm crypt: use asy...
726
  		crypt_alloc_req(cc, ctx);
3f1e9070f   Milan Broz   dm crypt: fix ctx...
727
  		atomic_inc(&ctx->pending);
c02977212   Andi Kleen   dm crypt: scale t...
728
  		r = crypt_convert_block(cc, ctx, this_cc->req);
3a7f6c990   Milan Broz   dm crypt: use asy...
729
730
  
  		switch (r) {
3f1e9070f   Milan Broz   dm crypt: fix ctx...
731
  		/* async */
3a7f6c990   Milan Broz   dm crypt: use asy...
732
733
734
735
736
  		case -EBUSY:
  			wait_for_completion(&ctx->restart);
  			INIT_COMPLETION(ctx->restart);
  			/* fall through*/
  		case -EINPROGRESS:
c02977212   Andi Kleen   dm crypt: scale t...
737
  			this_cc->req = NULL;
3f1e9070f   Milan Broz   dm crypt: fix ctx...
738
739
740
741
  			ctx->sector++;
  			continue;
  
  		/* sync */
3a7f6c990   Milan Broz   dm crypt: use asy...
742
  		case 0:
3f1e9070f   Milan Broz   dm crypt: fix ctx...
743
  			atomic_dec(&ctx->pending);
3a7f6c990   Milan Broz   dm crypt: use asy...
744
  			ctx->sector++;
c7f1b2044   Milan Broz   dm crypt: use con...
745
  			cond_resched();
3a7f6c990   Milan Broz   dm crypt: use asy...
746
  			continue;
3a7f6c990   Milan Broz   dm crypt: use asy...
747

3f1e9070f   Milan Broz   dm crypt: fix ctx...
748
749
750
751
752
  		/* error */
  		default:
  			atomic_dec(&ctx->pending);
  			return r;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
753
  	}
3f1e9070f   Milan Broz   dm crypt: fix ctx...
754
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755
  }
d469f8419   Milan Broz   dm crypt: tidy wh...
756
757
  static void dm_crypt_bio_destructor(struct bio *bio)
  {
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
758
  	struct dm_crypt_io *io = bio->bi_private;
6a24c7184   Milan Broz   [PATCH] dm crypt:...
759
760
761
  	struct crypt_config *cc = io->target->private;
  
  	bio_free(bio, cc->bs);
d469f8419   Milan Broz   dm crypt: tidy wh...
762
  }
6a24c7184   Milan Broz   [PATCH] dm crypt:...
763

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
765
766
  /*
   * Generate a new unfragmented bio with the given size
   * This should never violate the device limitations
933f01d43   Milan Broz   dm crypt: avoid u...
767
768
   * May return a smaller bio when running out of pages, indicated by
   * *out_of_pages set to 1.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
   */
933f01d43   Milan Broz   dm crypt: avoid u...
770
771
  static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size,
  				      unsigned *out_of_pages)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
772
  {
027581f35   Olaf Kirch   dm crypt: fix cal...
773
  	struct crypt_config *cc = io->target->private;
8b0044571   Milan Broz   [PATCH] dm crypt:...
774
  	struct bio *clone;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
  	unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
b4e3ca1ab   Al Viro   [PATCH] gfp_t: re...
776
  	gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
91e106259   Milan Broz   dm crypt: use bio...
777
778
  	unsigned i, len;
  	struct page *page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779

2f9941b6c   Olaf Kirch   dm crypt: fix rem...
780
  	clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
8b0044571   Milan Broz   [PATCH] dm crypt:...
781
  	if (!clone)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783

027581f35   Olaf Kirch   dm crypt: fix cal...
784
  	clone_init(io, clone);
933f01d43   Milan Broz   dm crypt: avoid u...
785
  	*out_of_pages = 0;
6a24c7184   Milan Broz   [PATCH] dm crypt:...
786

f97380bca   Olaf Kirch   dm crypt: use sma...
787
  	for (i = 0; i < nr_iovecs; i++) {
91e106259   Milan Broz   dm crypt: use bio...
788
  		page = mempool_alloc(cc->page_pool, gfp_mask);
933f01d43   Milan Broz   dm crypt: avoid u...
789
790
  		if (!page) {
  			*out_of_pages = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
  			break;
933f01d43   Milan Broz   dm crypt: avoid u...
792
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
794
795
796
797
798
  
  		/*
  		 * if additional pages cannot be allocated without waiting,
  		 * return a partially allocated bio, the caller will then try
  		 * to allocate additional bios while submitting this partial bio
  		 */
f97380bca   Olaf Kirch   dm crypt: use sma...
799
  		if (i == (MIN_BIO_PAGES - 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
  			gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
91e106259   Milan Broz   dm crypt: use bio...
801
802
803
804
805
806
  		len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
  
  		if (!bio_add_page(clone, page, len, 0)) {
  			mempool_free(page, cc->page_pool);
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
807

91e106259   Milan Broz   dm crypt: use bio...
808
  		size -= len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
809
  	}
8b0044571   Milan Broz   [PATCH] dm crypt:...
810
811
  	if (!clone->bi_size) {
  		bio_put(clone);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
813
  		return NULL;
  	}
8b0044571   Milan Broz   [PATCH] dm crypt:...
814
  	return clone;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  }
644bd2f04   Neil Brown   Fix memory leak i...
816
  static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
  {
644bd2f04   Neil Brown   Fix memory leak i...
818
  	unsigned int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
  	struct bio_vec *bv;
644bd2f04   Neil Brown   Fix memory leak i...
820
  	for (i = 0; i < clone->bi_vcnt; i++) {
8b0044571   Milan Broz   [PATCH] dm crypt:...
821
  		bv = bio_iovec_idx(clone, i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
824
825
826
  		BUG_ON(!bv->bv_page);
  		mempool_free(bv->bv_page, cc->page_pool);
  		bv->bv_page = NULL;
  	}
  }
dc440d1e5   Milan Broz   dm crypt: tidy cr...
827
828
829
830
831
832
833
834
835
836
837
  static struct dm_crypt_io *crypt_io_alloc(struct dm_target *ti,
  					  struct bio *bio, sector_t sector)
  {
  	struct crypt_config *cc = ti->private;
  	struct dm_crypt_io *io;
  
  	io = mempool_alloc(cc->io_pool, GFP_NOIO);
  	io->target = ti;
  	io->base_bio = bio;
  	io->sector = sector;
  	io->error = 0;
393b47ef2   Milan Broz   dm crypt: fix asy...
838
  	io->base_io = NULL;
dc440d1e5   Milan Broz   dm crypt: tidy cr...
839
840
841
842
  	atomic_set(&io->pending, 0);
  
  	return io;
  }
3e1a8bdd0   Milan Broz   dm crypt: tidy in...
843
844
845
846
  static void crypt_inc_pending(struct dm_crypt_io *io)
  {
  	atomic_inc(&io->pending);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
849
  /*
   * One of the bios was finished. Check for completion of
   * the whole request and correctly clean up the buffer.
393b47ef2   Milan Broz   dm crypt: fix asy...
850
   * If base_io is set, wait for the last fragment to complete.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
   */
5742fd777   Milan Broz   dm crypt: move er...
852
  static void crypt_dec_pending(struct dm_crypt_io *io)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
  {
5742fd777   Milan Broz   dm crypt: move er...
854
  	struct crypt_config *cc = io->target->private;
b35f8caa0   Milan Broz   dm crypt: wait fo...
855
856
857
  	struct bio *base_bio = io->base_bio;
  	struct dm_crypt_io *base_io = io->base_io;
  	int error = io->error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
859
860
  
  	if (!atomic_dec_and_test(&io->pending))
  		return;
b35f8caa0   Milan Broz   dm crypt: wait fo...
861
862
863
864
  	mempool_free(io, cc->io_pool);
  
  	if (likely(!base_io))
  		bio_endio(base_bio, error);
393b47ef2   Milan Broz   dm crypt: fix asy...
865
  	else {
b35f8caa0   Milan Broz   dm crypt: wait fo...
866
867
868
  		if (error && !base_io->error)
  			base_io->error = error;
  		crypt_dec_pending(base_io);
393b47ef2   Milan Broz   dm crypt: fix asy...
869
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
871
872
  }
  
  /*
cabf08e4d   Milan Broz   dm crypt: add pos...
873
   * kcryptd/kcryptd_io:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
   *
   * Needed because it would be very unwise to do decryption in an
23541d2d2   Milan Broz   [PATCH] dm crypt:...
876
   * interrupt context.
cabf08e4d   Milan Broz   dm crypt: add pos...
877
878
879
880
881
882
883
884
   *
   * kcryptd performs the actual encryption or decryption.
   *
   * kcryptd_io performs the IO submission.
   *
   * They must be separated as otherwise the final stages could be
   * starved by new requests which can block in the first stages due
   * to memory allocation.
c02977212   Andi Kleen   dm crypt: scale t...
885
886
887
   *
   * The work is done per CPU global for all dm-crypt instances.
   * They should not depend on each other and do not block.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
   */
6712ecf8f   NeilBrown   Drop 'size' argum...
889
  static void crypt_endio(struct bio *clone, int error)
8b0044571   Milan Broz   [PATCH] dm crypt:...
890
  {
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
891
  	struct dm_crypt_io *io = clone->bi_private;
8b0044571   Milan Broz   [PATCH] dm crypt:...
892
  	struct crypt_config *cc = io->target->private;
ee7a491e6   Milan Broz   dm crypt: tidy cr...
893
  	unsigned rw = bio_data_dir(clone);
8b0044571   Milan Broz   [PATCH] dm crypt:...
894

adfe47702   Milan Broz   dm crypt: fix wri...
895
896
  	if (unlikely(!bio_flagged(clone, BIO_UPTODATE) && !error))
  		error = -EIO;
8b0044571   Milan Broz   [PATCH] dm crypt:...
897
  	/*
6712ecf8f   NeilBrown   Drop 'size' argum...
898
  	 * free the processed pages
8b0044571   Milan Broz   [PATCH] dm crypt:...
899
  	 */
ee7a491e6   Milan Broz   dm crypt: tidy cr...
900
  	if (rw == WRITE)
644bd2f04   Neil Brown   Fix memory leak i...
901
  		crypt_free_buffer_pages(cc, clone);
8b0044571   Milan Broz   [PATCH] dm crypt:...
902
903
  
  	bio_put(clone);
8b0044571   Milan Broz   [PATCH] dm crypt:...
904

ee7a491e6   Milan Broz   dm crypt: tidy cr...
905
906
907
908
  	if (rw == READ && !error) {
  		kcryptd_queue_crypt(io);
  		return;
  	}
5742fd777   Milan Broz   dm crypt: move er...
909
910
911
912
913
  
  	if (unlikely(error))
  		io->error = error;
  
  	crypt_dec_pending(io);
8b0044571   Milan Broz   [PATCH] dm crypt:...
914
  }
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
915
  static void clone_init(struct dm_crypt_io *io, struct bio *clone)
8b0044571   Milan Broz   [PATCH] dm crypt:...
916
917
918
919
920
921
922
  {
  	struct crypt_config *cc = io->target->private;
  
  	clone->bi_private = io;
  	clone->bi_end_io  = crypt_endio;
  	clone->bi_bdev    = cc->dev->bdev;
  	clone->bi_rw      = io->base_bio->bi_rw;
027581f35   Olaf Kirch   dm crypt: fix cal...
923
  	clone->bi_destructor = dm_crypt_bio_destructor;
8b0044571   Milan Broz   [PATCH] dm crypt:...
924
  }
20c82538e   Milan Broz   dm crypt: use io ...
925
  static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
8b0044571   Milan Broz   [PATCH] dm crypt:...
926
927
928
929
  {
  	struct crypt_config *cc = io->target->private;
  	struct bio *base_bio = io->base_bio;
  	struct bio *clone;
93e605c23   Milan Broz   [PATCH] dm crypt:...
930

8b0044571   Milan Broz   [PATCH] dm crypt:...
931
932
933
934
935
  	/*
  	 * The block layer might modify the bvec array, so always
  	 * copy the required bvecs because we need the original
  	 * one in order to decrypt the whole bio data *afterwards*.
  	 */
20c82538e   Milan Broz   dm crypt: use io ...
936
  	clone = bio_alloc_bioset(gfp, bio_segments(base_bio), cc->bs);
7eaceacca   Jens Axboe   block: remove per...
937
  	if (!clone)
20c82538e   Milan Broz   dm crypt: use io ...
938
  		return 1;
8b0044571   Milan Broz   [PATCH] dm crypt:...
939

20c82538e   Milan Broz   dm crypt: use io ...
940
  	crypt_inc_pending(io);
8b0044571   Milan Broz   [PATCH] dm crypt:...
941
942
943
944
  	clone_init(io, clone);
  	clone->bi_idx = 0;
  	clone->bi_vcnt = bio_segments(base_bio);
  	clone->bi_size = base_bio->bi_size;
0c395b0f8   Milan Broz   dm crypt: store s...
945
  	clone->bi_sector = cc->start + io->sector;
8b0044571   Milan Broz   [PATCH] dm crypt:...
946
947
  	memcpy(clone->bi_io_vec, bio_iovec(base_bio),
  	       sizeof(struct bio_vec) * clone->bi_vcnt);
8b0044571   Milan Broz   [PATCH] dm crypt:...
948

93e605c23   Milan Broz   [PATCH] dm crypt:...
949
  	generic_make_request(clone);
20c82538e   Milan Broz   dm crypt: use io ...
950
  	return 0;
8b0044571   Milan Broz   [PATCH] dm crypt:...
951
  }
4e4eef64e   Milan Broz   dm crypt: adjust ...
952
953
  static void kcryptd_io_write(struct dm_crypt_io *io)
  {
95497a960   Milan Broz   dm crypt: prepare...
954
  	struct bio *clone = io->ctx.bio_out;
95497a960   Milan Broz   dm crypt: prepare...
955
  	generic_make_request(clone);
4e4eef64e   Milan Broz   dm crypt: adjust ...
956
  }
395b167ca   Alasdair G Kergon   dm crypt: move qu...
957
958
959
  static void kcryptd_io(struct work_struct *work)
  {
  	struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
20c82538e   Milan Broz   dm crypt: use io ...
960
961
962
963
964
965
  	if (bio_data_dir(io->base_bio) == READ) {
  		crypt_inc_pending(io);
  		if (kcryptd_io_read(io, GFP_NOIO))
  			io->error = -ENOMEM;
  		crypt_dec_pending(io);
  	} else
395b167ca   Alasdair G Kergon   dm crypt: move qu...
966
967
968
969
970
971
972
973
974
975
  		kcryptd_io_write(io);
  }
  
  static void kcryptd_queue_io(struct dm_crypt_io *io)
  {
  	struct crypt_config *cc = io->target->private;
  
  	INIT_WORK(&io->work, kcryptd_io);
  	queue_work(cc->io_queue, &io->work);
  }
95497a960   Milan Broz   dm crypt: prepare...
976
977
  static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
  					  int error, int async)
4e4eef64e   Milan Broz   dm crypt: adjust ...
978
  {
dec1cedf9   Milan Broz   dm crypt: abstrac...
979
980
981
982
983
984
985
  	struct bio *clone = io->ctx.bio_out;
  	struct crypt_config *cc = io->target->private;
  
  	if (unlikely(error < 0)) {
  		crypt_free_buffer_pages(cc, clone);
  		bio_put(clone);
  		io->error = -EIO;
6c031f41d   Milan Broz   dm crypt: move de...
986
  		crypt_dec_pending(io);
dec1cedf9   Milan Broz   dm crypt: abstrac...
987
988
989
990
991
992
993
  		return;
  	}
  
  	/* crypt_convert should have filled the clone bio */
  	BUG_ON(io->ctx.idx_out < clone->bi_vcnt);
  
  	clone->bi_sector = cc->start + io->sector;
899c95d36   Milan Broz   dm crypt: tidy io...
994

95497a960   Milan Broz   dm crypt: prepare...
995
996
  	if (async)
  		kcryptd_queue_io(io);
1e37bb8e5   Alasdair G Kergon   dm crypt: remove ...
997
  	else
95497a960   Milan Broz   dm crypt: prepare...
998
  		generic_make_request(clone);
4e4eef64e   Milan Broz   dm crypt: adjust ...
999
  }
fc5a5e9aa   Milan Broz   dm crypt: tidy wr...
1000
  static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
8b0044571   Milan Broz   [PATCH] dm crypt:...
1001
1002
  {
  	struct crypt_config *cc = io->target->private;
8b0044571   Milan Broz   [PATCH] dm crypt:...
1003
  	struct bio *clone;
393b47ef2   Milan Broz   dm crypt: fix asy...
1004
  	struct dm_crypt_io *new_io;
c8081618a   Milan Broz   dm crypt: tidy ct...
1005
  	int crypt_finished;
933f01d43   Milan Broz   dm crypt: avoid u...
1006
  	unsigned out_of_pages = 0;
dec1cedf9   Milan Broz   dm crypt: abstrac...
1007
  	unsigned remaining = io->base_bio->bi_size;
b635b00e0   Milan Broz   dm crypt: tidy se...
1008
  	sector_t sector = io->sector;
dec1cedf9   Milan Broz   dm crypt: abstrac...
1009
  	int r;
8b0044571   Milan Broz   [PATCH] dm crypt:...
1010

93e605c23   Milan Broz   [PATCH] dm crypt:...
1011
  	/*
fc5a5e9aa   Milan Broz   dm crypt: tidy wr...
1012
1013
1014
  	 * Prevent io from disappearing until this function completes.
  	 */
  	crypt_inc_pending(io);
b635b00e0   Milan Broz   dm crypt: tidy se...
1015
  	crypt_convert_init(cc, &io->ctx, NULL, io->base_bio, sector);
fc5a5e9aa   Milan Broz   dm crypt: tidy wr...
1016
1017
  
  	/*
93e605c23   Milan Broz   [PATCH] dm crypt:...
1018
1019
1020
1021
  	 * The allocated buffers can be smaller than the whole bio,
  	 * so repeat the whole process until all the data can be handled.
  	 */
  	while (remaining) {
933f01d43   Milan Broz   dm crypt: avoid u...
1022
  		clone = crypt_alloc_buffer(io, remaining, &out_of_pages);
23541d2d2   Milan Broz   [PATCH] dm crypt:...
1023
  		if (unlikely(!clone)) {
5742fd777   Milan Broz   dm crypt: move er...
1024
  			io->error = -ENOMEM;
fc5a5e9aa   Milan Broz   dm crypt: tidy wr...
1025
  			break;
23541d2d2   Milan Broz   [PATCH] dm crypt:...
1026
  		}
93e605c23   Milan Broz   [PATCH] dm crypt:...
1027

53017030e   Milan Broz   dm crypt: move co...
1028
1029
  		io->ctx.bio_out = clone;
  		io->ctx.idx_out = 0;
93e605c23   Milan Broz   [PATCH] dm crypt:...
1030

dec1cedf9   Milan Broz   dm crypt: abstrac...
1031
  		remaining -= clone->bi_size;
b635b00e0   Milan Broz   dm crypt: tidy se...
1032
  		sector += bio_sectors(clone);
93e605c23   Milan Broz   [PATCH] dm crypt:...
1033

4e5940989   Milan Broz   dm crypt: fix asy...
1034
  		crypt_inc_pending(io);
dec1cedf9   Milan Broz   dm crypt: abstrac...
1035
  		r = crypt_convert(cc, &io->ctx);
c8081618a   Milan Broz   dm crypt: tidy ct...
1036
  		crypt_finished = atomic_dec_and_test(&io->ctx.pending);
f97380bca   Olaf Kirch   dm crypt: use sma...
1037

c8081618a   Milan Broz   dm crypt: tidy ct...
1038
1039
  		/* Encryption was already finished, submit io now */
  		if (crypt_finished) {
3a7f6c990   Milan Broz   dm crypt: use asy...
1040
  			kcryptd_crypt_write_io_submit(io, r, 0);
c8081618a   Milan Broz   dm crypt: tidy ct...
1041
1042
1043
1044
1045
  
  			/*
  			 * If there was an error, do not try next fragments.
  			 * For async, error is processed in async handler.
  			 */
6c031f41d   Milan Broz   dm crypt: move de...
1046
  			if (unlikely(r < 0))
fc5a5e9aa   Milan Broz   dm crypt: tidy wr...
1047
  				break;
b635b00e0   Milan Broz   dm crypt: tidy se...
1048
1049
  
  			io->sector = sector;
4e5940989   Milan Broz   dm crypt: fix asy...
1050
  		}
93e605c23   Milan Broz   [PATCH] dm crypt:...
1051

933f01d43   Milan Broz   dm crypt: avoid u...
1052
1053
1054
1055
1056
  		/*
  		 * Out of memory -> run queues
  		 * But don't wait if split was due to the io size restriction
  		 */
  		if (unlikely(out_of_pages))
8aa7e847d   Jens Axboe   Fix congestion_wa...
1057
  			congestion_wait(BLK_RW_ASYNC, HZ/100);
933f01d43   Milan Broz   dm crypt: avoid u...
1058

393b47ef2   Milan Broz   dm crypt: fix asy...
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
  		/*
  		 * With async crypto it is unsafe to share the crypto context
  		 * between fragments, so switch to a new dm_crypt_io structure.
  		 */
  		if (unlikely(!crypt_finished && remaining)) {
  			new_io = crypt_io_alloc(io->target, io->base_bio,
  						sector);
  			crypt_inc_pending(new_io);
  			crypt_convert_init(cc, &new_io->ctx, NULL,
  					   io->base_bio, sector);
  			new_io->ctx.idx_in = io->ctx.idx_in;
  			new_io->ctx.offset_in = io->ctx.offset_in;
  
  			/*
  			 * Fragments after the first use the base_io
  			 * pending count.
  			 */
  			if (!io->base_io)
  				new_io->base_io = io;
  			else {
  				new_io->base_io = io->base_io;
  				crypt_inc_pending(io->base_io);
  				crypt_dec_pending(io);
  			}
  
  			io = new_io;
  		}
93e605c23   Milan Broz   [PATCH] dm crypt:...
1086
  	}
899c95d36   Milan Broz   dm crypt: tidy io...
1087
1088
  
  	crypt_dec_pending(io);
84131db68   Milan Broz   dm crypt: introdu...
1089
  }
4e4eef64e   Milan Broz   dm crypt: adjust ...
1090
  static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error)
5742fd777   Milan Broz   dm crypt: move er...
1091
1092
1093
1094
1095
1096
  {
  	if (unlikely(error < 0))
  		io->error = -EIO;
  
  	crypt_dec_pending(io);
  }
4e4eef64e   Milan Broz   dm crypt: adjust ...
1097
  static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
8b0044571   Milan Broz   [PATCH] dm crypt:...
1098
1099
  {
  	struct crypt_config *cc = io->target->private;
5742fd777   Milan Broz   dm crypt: move er...
1100
  	int r = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101

3e1a8bdd0   Milan Broz   dm crypt: tidy in...
1102
  	crypt_inc_pending(io);
3a7f6c990   Milan Broz   dm crypt: use asy...
1103

53017030e   Milan Broz   dm crypt: move co...
1104
  	crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio,
0c395b0f8   Milan Broz   dm crypt: store s...
1105
  			   io->sector);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106

5742fd777   Milan Broz   dm crypt: move er...
1107
  	r = crypt_convert(cc, &io->ctx);
3f1e9070f   Milan Broz   dm crypt: fix ctx...
1108
  	if (atomic_dec_and_test(&io->ctx.pending))
3a7f6c990   Milan Broz   dm crypt: use asy...
1109
1110
1111
  		kcryptd_crypt_read_done(io, r);
  
  	crypt_dec_pending(io);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1112
  }
95497a960   Milan Broz   dm crypt: prepare...
1113
1114
1115
  static void kcryptd_async_done(struct crypto_async_request *async_req,
  			       int error)
  {
b2174eebd   Huang Ying   dm crypt: fix kcr...
1116
1117
  	struct dm_crypt_request *dmreq = async_req->data;
  	struct convert_context *ctx = dmreq->ctx;
95497a960   Milan Broz   dm crypt: prepare...
1118
1119
1120
1121
1122
1123
1124
  	struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx);
  	struct crypt_config *cc = io->target->private;
  
  	if (error == -EINPROGRESS) {
  		complete(&ctx->restart);
  		return;
  	}
2dc5327d3   Milan Broz   dm crypt: add pos...
1125
1126
  	if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post)
  		error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq);
b2174eebd   Huang Ying   dm crypt: fix kcr...
1127
  	mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
95497a960   Milan Broz   dm crypt: prepare...
1128
1129
1130
1131
1132
1133
1134
1135
1136
  
  	if (!atomic_dec_and_test(&ctx->pending))
  		return;
  
  	if (bio_data_dir(io->base_bio) == READ)
  		kcryptd_crypt_read_done(io, error);
  	else
  		kcryptd_crypt_write_io_submit(io, error, 1);
  }
395b167ca   Alasdair G Kergon   dm crypt: move qu...
1137
  static void kcryptd_crypt(struct work_struct *work)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
  {
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1139
  	struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
8b0044571   Milan Broz   [PATCH] dm crypt:...
1140

cabf08e4d   Milan Broz   dm crypt: add pos...
1141
  	if (bio_data_dir(io->base_bio) == READ)
395b167ca   Alasdair G Kergon   dm crypt: move qu...
1142
  		kcryptd_crypt_read_convert(io);
4e4eef64e   Milan Broz   dm crypt: adjust ...
1143
  	else
395b167ca   Alasdair G Kergon   dm crypt: move qu...
1144
  		kcryptd_crypt_write_convert(io);
cabf08e4d   Milan Broz   dm crypt: add pos...
1145
  }
395b167ca   Alasdair G Kergon   dm crypt: move qu...
1146
  static void kcryptd_queue_crypt(struct dm_crypt_io *io)
cabf08e4d   Milan Broz   dm crypt: add pos...
1147
  {
395b167ca   Alasdair G Kergon   dm crypt: move qu...
1148
  	struct crypt_config *cc = io->target->private;
cabf08e4d   Milan Broz   dm crypt: add pos...
1149

395b167ca   Alasdair G Kergon   dm crypt: move qu...
1150
1151
  	INIT_WORK(&io->work, kcryptd_crypt);
  	queue_work(cc->crypt_queue, &io->work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
  }
  
  /*
   * Decode key from its hex representation
   */
  static int crypt_decode_key(u8 *key, char *hex, unsigned int size)
  {
  	char buffer[3];
  	char *endp;
  	unsigned int i;
  
  	buffer[2] = '\0';
8b0044571   Milan Broz   [PATCH] dm crypt:...
1164
  	for (i = 0; i < size; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
  		buffer[0] = *hex++;
  		buffer[1] = *hex++;
  
  		key[i] = (u8)simple_strtoul(buffer, &endp, 16);
  
  		if (endp != &buffer[2])
  			return -EINVAL;
  	}
  
  	if (*hex != '\0')
  		return -EINVAL;
  
  	return 0;
  }
  
  /*
   * Encode key into its hex representation
   */
  static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
  {
  	unsigned int i;
8b0044571   Milan Broz   [PATCH] dm crypt:...
1186
  	for (i = 0; i < size; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1187
1188
1189
1190
1191
  		sprintf(hex, "%02x", *key);
  		hex += 2;
  		key++;
  	}
  }
d1f964238   Milan Broz   dm crypt: add mul...
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
  static void crypt_free_tfms(struct crypt_config *cc, int cpu)
  {
  	struct crypt_cpu *cpu_cc = per_cpu_ptr(cc->cpu, cpu);
  	unsigned i;
  
  	for (i = 0; i < cc->tfms_count; i++)
  		if (cpu_cc->tfms[i] && !IS_ERR(cpu_cc->tfms[i])) {
  			crypto_free_ablkcipher(cpu_cc->tfms[i]);
  			cpu_cc->tfms[i] = NULL;
  		}
  }
  
  static int crypt_alloc_tfms(struct crypt_config *cc, int cpu, char *ciphermode)
  {
  	struct crypt_cpu *cpu_cc = per_cpu_ptr(cc->cpu, cpu);
  	unsigned i;
  	int err;
  
  	for (i = 0; i < cc->tfms_count; i++) {
  		cpu_cc->tfms[i] = crypto_alloc_ablkcipher(ciphermode, 0, 0);
  		if (IS_ERR(cpu_cc->tfms[i])) {
  			err = PTR_ERR(cpu_cc->tfms[i]);
  			crypt_free_tfms(cc, cpu);
  			return err;
  		}
  	}
  
  	return 0;
  }
c02977212   Andi Kleen   dm crypt: scale t...
1221
1222
  static int crypt_setkey_allcpus(struct crypt_config *cc)
  {
d1f964238   Milan Broz   dm crypt: add mul...
1223
1224
  	unsigned subkey_size = cc->key_size >> ilog2(cc->tfms_count);
  	int cpu, err = 0, i, r;
c02977212   Andi Kleen   dm crypt: scale t...
1225
1226
  
  	for_each_possible_cpu(cpu) {
d1f964238   Milan Broz   dm crypt: add mul...
1227
1228
1229
1230
1231
1232
  		for (i = 0; i < cc->tfms_count; i++) {
  			r = crypto_ablkcipher_setkey(per_cpu_ptr(cc->cpu, cpu)->tfms[i],
  						     cc->key + (i * subkey_size), subkey_size);
  			if (r)
  				err = r;
  		}
c02977212   Andi Kleen   dm crypt: scale t...
1233
1234
1235
1236
  	}
  
  	return err;
  }
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1237
1238
  static int crypt_set_key(struct crypt_config *cc, char *key)
  {
de8be5ac7   Milan Broz   dm crypt: wipe ke...
1239
1240
  	int r = -EINVAL;
  	int key_string_len = strlen(key);
69a8cfcda   Milan Broz   dm crypt: set key...
1241
  	/* The key size may not be changed. */
de8be5ac7   Milan Broz   dm crypt: wipe ke...
1242
1243
  	if (cc->key_size != (key_string_len >> 1))
  		goto out;
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1244

69a8cfcda   Milan Broz   dm crypt: set key...
1245
1246
  	/* Hyphen (which gives a key_size of zero) means there is no key. */
  	if (!cc->key_size && strcmp(key, "-"))
de8be5ac7   Milan Broz   dm crypt: wipe ke...
1247
  		goto out;
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1248

69a8cfcda   Milan Broz   dm crypt: set key...
1249
  	if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0)
de8be5ac7   Milan Broz   dm crypt: wipe ke...
1250
  		goto out;
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1251
1252
  
  	set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
de8be5ac7   Milan Broz   dm crypt: wipe ke...
1253
1254
1255
1256
1257
1258
1259
  	r = crypt_setkey_allcpus(cc);
  
  out:
  	/* Hex key string not needed after here, so wipe it. */
  	memset(key, '0', key_string_len);
  
  	return r;
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1260
1261
1262
1263
1264
1265
  }
  
  static int crypt_wipe_key(struct crypt_config *cc)
  {
  	clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
  	memset(&cc->key, 0, cc->key_size * sizeof(u8));
c02977212   Andi Kleen   dm crypt: scale t...
1266
1267
  
  	return crypt_setkey_allcpus(cc);
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1268
  }
28513fccf   Milan Broz   dm crypt: simplif...
1269
1270
1271
  static void crypt_dtr(struct dm_target *ti)
  {
  	struct crypt_config *cc = ti->private;
c02977212   Andi Kleen   dm crypt: scale t...
1272
1273
  	struct crypt_cpu *cpu_cc;
  	int cpu;
28513fccf   Milan Broz   dm crypt: simplif...
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
  
  	ti->private = NULL;
  
  	if (!cc)
  		return;
  
  	if (cc->io_queue)
  		destroy_workqueue(cc->io_queue);
  	if (cc->crypt_queue)
  		destroy_workqueue(cc->crypt_queue);
c02977212   Andi Kleen   dm crypt: scale t...
1284
1285
1286
1287
1288
  	if (cc->cpu)
  		for_each_possible_cpu(cpu) {
  			cpu_cc = per_cpu_ptr(cc->cpu, cpu);
  			if (cpu_cc->req)
  				mempool_free(cpu_cc->req, cc->req_pool);
d1f964238   Milan Broz   dm crypt: add mul...
1289
  			crypt_free_tfms(cc, cpu);
c02977212   Andi Kleen   dm crypt: scale t...
1290
  		}
28513fccf   Milan Broz   dm crypt: simplif...
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
  	if (cc->bs)
  		bioset_free(cc->bs);
  
  	if (cc->page_pool)
  		mempool_destroy(cc->page_pool);
  	if (cc->req_pool)
  		mempool_destroy(cc->req_pool);
  	if (cc->io_pool)
  		mempool_destroy(cc->io_pool);
  
  	if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
  		cc->iv_gen_ops->dtr(cc);
28513fccf   Milan Broz   dm crypt: simplif...
1303
1304
  	if (cc->dev)
  		dm_put_device(ti, cc->dev);
c02977212   Andi Kleen   dm crypt: scale t...
1305
1306
  	if (cc->cpu)
  		free_percpu(cc->cpu);
5ebaee6d2   Milan Broz   dm crypt: simplif...
1307
  	kzfree(cc->cipher);
7dbcd1374   Milan Broz   dm crypt: simplif...
1308
  	kzfree(cc->cipher_string);
28513fccf   Milan Broz   dm crypt: simplif...
1309
1310
1311
1312
  
  	/* Must zero key material before freeing */
  	kzfree(cc);
  }
5ebaee6d2   Milan Broz   dm crypt: simplif...
1313
1314
  static int crypt_ctr_cipher(struct dm_target *ti,
  			    char *cipher_in, char *key)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1315
  {
5ebaee6d2   Milan Broz   dm crypt: simplif...
1316
  	struct crypt_config *cc = ti->private;
d1f964238   Milan Broz   dm crypt: add mul...
1317
  	char *tmp, *cipher, *chainmode, *ivmode, *ivopts, *keycount;
5ebaee6d2   Milan Broz   dm crypt: simplif...
1318
  	char *cipher_api = NULL;
c02977212   Andi Kleen   dm crypt: scale t...
1319
  	int cpu, ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320

5ebaee6d2   Milan Broz   dm crypt: simplif...
1321
1322
1323
  	/* Convert to crypto api definition? */
  	if (strchr(cipher_in, '(')) {
  		ti->error = "Bad cipher specification";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1324
1325
  		return -EINVAL;
  	}
7dbcd1374   Milan Broz   dm crypt: simplif...
1326
1327
1328
  	cc->cipher_string = kstrdup(cipher_in, GFP_KERNEL);
  	if (!cc->cipher_string)
  		goto bad_mem;
5ebaee6d2   Milan Broz   dm crypt: simplif...
1329
1330
  	/*
  	 * Legacy dm-crypt cipher specification
d1f964238   Milan Broz   dm crypt: add mul...
1331
  	 * cipher[:keycount]-mode-iv:ivopts
5ebaee6d2   Milan Broz   dm crypt: simplif...
1332
1333
  	 */
  	tmp = cipher_in;
d1f964238   Milan Broz   dm crypt: add mul...
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  	keycount = strsep(&tmp, "-");
  	cipher = strsep(&keycount, ":");
  
  	if (!keycount)
  		cc->tfms_count = 1;
  	else if (sscanf(keycount, "%u", &cc->tfms_count) != 1 ||
  		 !is_power_of_2(cc->tfms_count)) {
  		ti->error = "Bad cipher key count specification";
  		return -EINVAL;
  	}
  	cc->key_parts = cc->tfms_count;
5ebaee6d2   Milan Broz   dm crypt: simplif...
1345
1346
1347
1348
  
  	cc->cipher = kstrdup(cipher, GFP_KERNEL);
  	if (!cc->cipher)
  		goto bad_mem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1349
1350
1351
1352
1353
  	chainmode = strsep(&tmp, "-");
  	ivopts = strsep(&tmp, "-");
  	ivmode = strsep(&ivopts, ":");
  
  	if (tmp)
5ebaee6d2   Milan Broz   dm crypt: simplif...
1354
  		DMWARN("Ignoring unexpected additional cipher options");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1355

d1f964238   Milan Broz   dm crypt: add mul...
1356
1357
1358
  	cc->cpu = __alloc_percpu(sizeof(*(cc->cpu)) +
  				 cc->tfms_count * sizeof(*(cc->cpu->tfms)),
  				 __alignof__(struct crypt_cpu));
c02977212   Andi Kleen   dm crypt: scale t...
1359
1360
1361
1362
  	if (!cc->cpu) {
  		ti->error = "Cannot allocate per cpu state";
  		goto bad_mem;
  	}
7dbcd1374   Milan Broz   dm crypt: simplif...
1363
1364
1365
1366
  	/*
  	 * For compatibility with the original dm-crypt mapping format, if
  	 * only the cipher name is supplied, use cbc-plain.
  	 */
5ebaee6d2   Milan Broz   dm crypt: simplif...
1367
  	if (!chainmode || (!strcmp(chainmode, "plain") && !ivmode)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1368
1369
1370
  		chainmode = "cbc";
  		ivmode = "plain";
  	}
d1806f6a9   Herbert Xu   [BLOCK] dm-crypt:...
1371
  	if (strcmp(chainmode, "ecb") && !ivmode) {
5ebaee6d2   Milan Broz   dm crypt: simplif...
1372
1373
  		ti->error = "IV mechanism required";
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374
  	}
5ebaee6d2   Milan Broz   dm crypt: simplif...
1375
1376
1377
1378
1379
1380
1381
1382
1383
  	cipher_api = kmalloc(CRYPTO_MAX_ALG_NAME, GFP_KERNEL);
  	if (!cipher_api)
  		goto bad_mem;
  
  	ret = snprintf(cipher_api, CRYPTO_MAX_ALG_NAME,
  		       "%s(%s)", chainmode, cipher);
  	if (ret < 0) {
  		kfree(cipher_api);
  		goto bad_mem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1384
  	}
5ebaee6d2   Milan Broz   dm crypt: simplif...
1385
  	/* Allocate cipher */
c02977212   Andi Kleen   dm crypt: scale t...
1386
  	for_each_possible_cpu(cpu) {
d1f964238   Milan Broz   dm crypt: add mul...
1387
1388
  		ret = crypt_alloc_tfms(cc, cpu, cipher_api);
  		if (ret < 0) {
c02977212   Andi Kleen   dm crypt: scale t...
1389
1390
1391
  			ti->error = "Error allocating crypto tfm";
  			goto bad;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1392
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1393

5ebaee6d2   Milan Broz   dm crypt: simplif...
1394
1395
  	/* Initialize and set key */
  	ret = crypt_set_key(cc, key);
28513fccf   Milan Broz   dm crypt: simplif...
1396
  	if (ret < 0) {
0b4309581   Milan Broz   dm crypt: make wi...
1397
  		ti->error = "Error decoding and setting key";
28513fccf   Milan Broz   dm crypt: simplif...
1398
  		goto bad;
0b4309581   Milan Broz   dm crypt: make wi...
1399
  	}
5ebaee6d2   Milan Broz   dm crypt: simplif...
1400
  	/* Initialize IV */
c02977212   Andi Kleen   dm crypt: scale t...
1401
  	cc->iv_size = crypto_ablkcipher_ivsize(any_tfm(cc));
5ebaee6d2   Milan Broz   dm crypt: simplif...
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
  	if (cc->iv_size)
  		/* at least a 64 bit sector number should fit in our buffer */
  		cc->iv_size = max(cc->iv_size,
  				  (unsigned int)(sizeof(u64) / sizeof(u8)));
  	else if (ivmode) {
  		DMWARN("Selected cipher does not support IVs");
  		ivmode = NULL;
  	}
  
  	/* Choose ivmode, see comments at iv code. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1412
1413
1414
1415
  	if (ivmode == NULL)
  		cc->iv_gen_ops = NULL;
  	else if (strcmp(ivmode, "plain") == 0)
  		cc->iv_gen_ops = &crypt_iv_plain_ops;
61afef614   Milan Broz   dm crypt: add pla...
1416
1417
  	else if (strcmp(ivmode, "plain64") == 0)
  		cc->iv_gen_ops = &crypt_iv_plain64_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
1419
  	else if (strcmp(ivmode, "essiv") == 0)
  		cc->iv_gen_ops = &crypt_iv_essiv_ops;
48527fa7c   Rik Snel   [BLOCK] dm-crypt:...
1420
1421
  	else if (strcmp(ivmode, "benbi") == 0)
  		cc->iv_gen_ops = &crypt_iv_benbi_ops;
46b477306   Ludwig Nussel   dm crypt: add nul...
1422
1423
  	else if (strcmp(ivmode, "null") == 0)
  		cc->iv_gen_ops = &crypt_iv_null_ops;
347457859   Milan Broz   dm crypt: add loo...
1424
1425
1426
1427
1428
1429
1430
1431
1432
  	else if (strcmp(ivmode, "lmk") == 0) {
  		cc->iv_gen_ops = &crypt_iv_lmk_ops;
  		/* Version 2 and 3 is recognised according
  		 * to length of provided multi-key string.
  		 * If present (version 3), last key is used as IV seed.
  		 */
  		if (cc->key_size % cc->key_parts)
  			cc->key_parts++;
  	} else {
5ebaee6d2   Milan Broz   dm crypt: simplif...
1433
  		ret = -EINVAL;
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1434
  		ti->error = "Invalid IV mode";
28513fccf   Milan Broz   dm crypt: simplif...
1435
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1436
  	}
28513fccf   Milan Broz   dm crypt: simplif...
1437
1438
1439
1440
1441
1442
1443
1444
  	/* Allocate IV */
  	if (cc->iv_gen_ops && cc->iv_gen_ops->ctr) {
  		ret = cc->iv_gen_ops->ctr(cc, ti, ivopts);
  		if (ret < 0) {
  			ti->error = "Error creating IV";
  			goto bad;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1445

28513fccf   Milan Broz   dm crypt: simplif...
1446
1447
1448
1449
1450
1451
1452
  	/* Initialize IV (set keys for ESSIV etc) */
  	if (cc->iv_gen_ops && cc->iv_gen_ops->init) {
  		ret = cc->iv_gen_ops->init(cc);
  		if (ret < 0) {
  			ti->error = "Error initialising IV";
  			goto bad;
  		}
b95bf2d3d   Milan Broz   dm crypt: separat...
1453
  	}
5ebaee6d2   Milan Broz   dm crypt: simplif...
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
  	ret = 0;
  bad:
  	kfree(cipher_api);
  	return ret;
  
  bad_mem:
  	ti->error = "Cannot allocate cipher strings";
  	return -ENOMEM;
  }
  
  /*
   * Construct an encryption mapping:
   * <cipher> <key> <iv_offset> <dev_path> <start>
   */
  static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
  {
  	struct crypt_config *cc;
772ae5f54   Milan Broz   dm crypt: optiona...
1471
  	unsigned int key_size, opt_params;
5ebaee6d2   Milan Broz   dm crypt: simplif...
1472
1473
  	unsigned long long tmpll;
  	int ret;
772ae5f54   Milan Broz   dm crypt: optiona...
1474
1475
1476
1477
1478
1479
  	struct dm_arg_set as;
  	const char *opt_string;
  
  	static struct dm_arg _args[] = {
  		{0, 1, "Invalid number of feature args"},
  	};
5ebaee6d2   Milan Broz   dm crypt: simplif...
1480

772ae5f54   Milan Broz   dm crypt: optiona...
1481
  	if (argc < 5) {
5ebaee6d2   Milan Broz   dm crypt: simplif...
1482
1483
  		ti->error = "Not enough arguments";
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484
  	}
5ebaee6d2   Milan Broz   dm crypt: simplif...
1485
1486
1487
1488
1489
1490
1491
  	key_size = strlen(argv[1]) >> 1;
  
  	cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
  	if (!cc) {
  		ti->error = "Cannot allocate encryption context";
  		return -ENOMEM;
  	}
69a8cfcda   Milan Broz   dm crypt: set key...
1492
  	cc->key_size = key_size;
5ebaee6d2   Milan Broz   dm crypt: simplif...
1493
1494
1495
1496
1497
  
  	ti->private = cc;
  	ret = crypt_ctr_cipher(ti, argv[0], argv[1]);
  	if (ret < 0)
  		goto bad;
28513fccf   Milan Broz   dm crypt: simplif...
1498
  	ret = -ENOMEM;
93d2341c7   Matthew Dobson   [PATCH] mempool: ...
1499
  	cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
  	if (!cc->io_pool) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1501
  		ti->error = "Cannot allocate crypt io mempool";
28513fccf   Milan Broz   dm crypt: simplif...
1502
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  	}
ddd42edfd   Milan Broz   dm crypt: add asy...
1504
  	cc->dmreq_start = sizeof(struct ablkcipher_request);
c02977212   Andi Kleen   dm crypt: scale t...
1505
  	cc->dmreq_start += crypto_ablkcipher_reqsize(any_tfm(cc));
ddd42edfd   Milan Broz   dm crypt: add asy...
1506
  	cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment());
c02977212   Andi Kleen   dm crypt: scale t...
1507
  	cc->dmreq_start += crypto_ablkcipher_alignmask(any_tfm(cc)) &
3a7f6c990   Milan Broz   dm crypt: use asy...
1508
  			   ~(crypto_tfm_ctx_alignment() - 1);
ddd42edfd   Milan Broz   dm crypt: add asy...
1509
1510
1511
1512
1513
  
  	cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start +
  			sizeof(struct dm_crypt_request) + cc->iv_size);
  	if (!cc->req_pool) {
  		ti->error = "Cannot allocate crypt request mempool";
28513fccf   Milan Broz   dm crypt: simplif...
1514
  		goto bad;
ddd42edfd   Milan Broz   dm crypt: add asy...
1515
  	}
ddd42edfd   Milan Broz   dm crypt: add asy...
1516

a19b27ce3   Matthew Dobson   [PATCH] mempool: ...
1517
  	cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1518
  	if (!cc->page_pool) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1519
  		ti->error = "Cannot allocate page mempool";
28513fccf   Milan Broz   dm crypt: simplif...
1520
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1521
  	}
bb799ca02   Jens Axboe   bio: allow indivi...
1522
  	cc->bs = bioset_create(MIN_IOS, 0);
6a24c7184   Milan Broz   [PATCH] dm crypt:...
1523
1524
  	if (!cc->bs) {
  		ti->error = "Cannot allocate crypt bioset";
28513fccf   Milan Broz   dm crypt: simplif...
1525
  		goto bad;
6a24c7184   Milan Broz   [PATCH] dm crypt:...
1526
  	}
28513fccf   Milan Broz   dm crypt: simplif...
1527
  	ret = -EINVAL;
4ee218cd6   Andrew Morton   [PATCH] dm: remov...
1528
  	if (sscanf(argv[2], "%llu", &tmpll) != 1) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1529
  		ti->error = "Invalid iv_offset sector";
28513fccf   Milan Broz   dm crypt: simplif...
1530
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531
  	}
4ee218cd6   Andrew Morton   [PATCH] dm: remov...
1532
  	cc->iv_offset = tmpll;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1533

28513fccf   Milan Broz   dm crypt: simplif...
1534
1535
1536
1537
  	if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &cc->dev)) {
  		ti->error = "Device lookup failed";
  		goto bad;
  	}
4ee218cd6   Andrew Morton   [PATCH] dm: remov...
1538
  	if (sscanf(argv[4], "%llu", &tmpll) != 1) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1539
  		ti->error = "Invalid device sector";
28513fccf   Milan Broz   dm crypt: simplif...
1540
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541
  	}
4ee218cd6   Andrew Morton   [PATCH] dm: remov...
1542
  	cc->start = tmpll;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1543

772ae5f54   Milan Broz   dm crypt: optiona...
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
  	argv += 5;
  	argc -= 5;
  
  	/* Optional parameters */
  	if (argc) {
  		as.argc = argc;
  		as.argv = argv;
  
  		ret = dm_read_arg_group(_args, &as, &opt_params, &ti->error);
  		if (ret)
  			goto bad;
  
  		opt_string = dm_shift_arg(&as);
  
  		if (opt_params == 1 && opt_string &&
  		    !strcasecmp(opt_string, "allow_discards"))
  			ti->num_discard_requests = 1;
  		else if (opt_params) {
  			ret = -EINVAL;
  			ti->error = "Invalid feature arguments";
  			goto bad;
  		}
  	}
28513fccf   Milan Broz   dm crypt: simplif...
1567
  	ret = -ENOMEM;
c02977212   Andi Kleen   dm crypt: scale t...
1568
1569
1570
1571
  	cc->io_queue = alloc_workqueue("kcryptd_io",
  				       WQ_NON_REENTRANT|
  				       WQ_MEM_RECLAIM,
  				       1);
cabf08e4d   Milan Broz   dm crypt: add pos...
1572
1573
  	if (!cc->io_queue) {
  		ti->error = "Couldn't create kcryptd io queue";
28513fccf   Milan Broz   dm crypt: simplif...
1574
  		goto bad;
cabf08e4d   Milan Broz   dm crypt: add pos...
1575
  	}
c02977212   Andi Kleen   dm crypt: scale t...
1576
1577
1578
1579
1580
  	cc->crypt_queue = alloc_workqueue("kcryptd",
  					  WQ_NON_REENTRANT|
  					  WQ_CPU_INTENSIVE|
  					  WQ_MEM_RECLAIM,
  					  1);
cabf08e4d   Milan Broz   dm crypt: add pos...
1581
  	if (!cc->crypt_queue) {
9934a8bea   Milan Broz   dm crypt: use per...
1582
  		ti->error = "Couldn't create kcryptd queue";
28513fccf   Milan Broz   dm crypt: simplif...
1583
  		goto bad;
9934a8bea   Milan Broz   dm crypt: use per...
1584
  	}
647c7db14   Mikulas Patocka   dm crypt: support...
1585
  	ti->num_flush_requests = 1;
983c7db34   Milan Broz   dm crypt: always ...
1586
  	ti->discard_zeroes_data_unsupported = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1587
  	return 0;
28513fccf   Milan Broz   dm crypt: simplif...
1588
1589
1590
  bad:
  	crypt_dtr(ti);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1591
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1592
1593
1594
  static int crypt_map(struct dm_target *ti, struct bio *bio,
  		     union map_info *map_context)
  {
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1595
  	struct dm_crypt_io *io;
647c7db14   Mikulas Patocka   dm crypt: support...
1596
  	struct crypt_config *cc;
772ae5f54   Milan Broz   dm crypt: optiona...
1597
1598
1599
1600
1601
1602
  	/*
  	 * If bio is REQ_FLUSH or REQ_DISCARD, just bypass crypt queues.
  	 * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight
  	 * - for REQ_DISCARD caller must use flush if IO ordering matters
  	 */
  	if (unlikely(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) {
647c7db14   Mikulas Patocka   dm crypt: support...
1603
1604
  		cc = ti->private;
  		bio->bi_bdev = cc->dev->bdev;
772ae5f54   Milan Broz   dm crypt: optiona...
1605
1606
  		if (bio_sectors(bio))
  			bio->bi_sector = cc->start + dm_target_offset(ti, bio->bi_sector);
647c7db14   Mikulas Patocka   dm crypt: support...
1607
1608
  		return DM_MAPIO_REMAPPED;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1609

b441a262e   Alasdair G Kergon   dm: use dm_target...
1610
  	io = crypt_io_alloc(ti, bio, dm_target_offset(ti, bio->bi_sector));
cabf08e4d   Milan Broz   dm crypt: add pos...
1611

20c82538e   Milan Broz   dm crypt: use io ...
1612
1613
1614
1615
  	if (bio_data_dir(io->base_bio) == READ) {
  		if (kcryptd_io_read(io, GFP_NOWAIT))
  			kcryptd_queue_io(io);
  	} else
cabf08e4d   Milan Broz   dm crypt: add pos...
1616
  		kcryptd_queue_crypt(io);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1617

d2a7ad29a   Kiyoshi Ueda   [PATCH] dm: map a...
1618
  	return DM_MAPIO_SUBMITTED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1619
1620
1621
1622
1623
  }
  
  static int crypt_status(struct dm_target *ti, status_type_t type,
  			char *result, unsigned int maxlen)
  {
5ebaee6d2   Milan Broz   dm crypt: simplif...
1624
  	struct crypt_config *cc = ti->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1625
1626
1627
1628
1629
1630
1631
1632
  	unsigned int sz = 0;
  
  	switch (type) {
  	case STATUSTYPE_INFO:
  		result[0] = '\0';
  		break;
  
  	case STATUSTYPE_TABLE:
7dbcd1374   Milan Broz   dm crypt: simplif...
1633
  		DMEMIT("%s ", cc->cipher_string);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
  
  		if (cc->key_size > 0) {
  			if ((maxlen - sz) < ((cc->key_size << 1) + 1))
  				return -ENOMEM;
  
  			crypt_encode_key(result + sz, cc->key, cc->key_size);
  			sz += cc->key_size << 1;
  		} else {
  			if (sz >= maxlen)
  				return -ENOMEM;
  			result[sz++] = '-';
  		}
4ee218cd6   Andrew Morton   [PATCH] dm: remov...
1646
1647
  		DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
  				cc->dev->name, (unsigned long long)cc->start);
772ae5f54   Milan Broz   dm crypt: optiona...
1648
1649
1650
  
  		if (ti->num_discard_requests)
  			DMEMIT(" 1 allow_discards");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651
1652
1653
1654
  		break;
  	}
  	return 0;
  }
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
  static void crypt_postsuspend(struct dm_target *ti)
  {
  	struct crypt_config *cc = ti->private;
  
  	set_bit(DM_CRYPT_SUSPENDED, &cc->flags);
  }
  
  static int crypt_preresume(struct dm_target *ti)
  {
  	struct crypt_config *cc = ti->private;
  
  	if (!test_bit(DM_CRYPT_KEY_VALID, &cc->flags)) {
  		DMERR("aborting resume - crypt key is not set.");
  		return -EAGAIN;
  	}
  
  	return 0;
  }
  
  static void crypt_resume(struct dm_target *ti)
  {
  	struct crypt_config *cc = ti->private;
  
  	clear_bit(DM_CRYPT_SUSPENDED, &cc->flags);
  }
  
  /* Message interface
   *	key set <key>
   *	key wipe
   */
  static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
  {
  	struct crypt_config *cc = ti->private;
542da3176   Milan Broz   dm crypt: make wi...
1688
  	int ret = -EINVAL;
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1689
1690
1691
  
  	if (argc < 2)
  		goto error;
498f0103e   Mike Snitzer   dm table: share t...
1692
  	if (!strcasecmp(argv[0], "key")) {
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1693
1694
1695
1696
  		if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) {
  			DMWARN("not suspended during key manipulation.");
  			return -EINVAL;
  		}
498f0103e   Mike Snitzer   dm table: share t...
1697
  		if (argc == 3 && !strcasecmp(argv[1], "set")) {
542da3176   Milan Broz   dm crypt: make wi...
1698
1699
1700
1701
1702
1703
1704
  			ret = crypt_set_key(cc, argv[2]);
  			if (ret)
  				return ret;
  			if (cc->iv_gen_ops && cc->iv_gen_ops->init)
  				ret = cc->iv_gen_ops->init(cc);
  			return ret;
  		}
498f0103e   Mike Snitzer   dm table: share t...
1705
  		if (argc == 2 && !strcasecmp(argv[1], "wipe")) {
542da3176   Milan Broz   dm crypt: make wi...
1706
1707
1708
1709
1710
  			if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) {
  				ret = cc->iv_gen_ops->wipe(cc);
  				if (ret)
  					return ret;
  			}
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1711
  			return crypt_wipe_key(cc);
542da3176   Milan Broz   dm crypt: make wi...
1712
  		}
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1713
1714
1715
1716
1717
1718
  	}
  
  error:
  	DMWARN("unrecognised message received.");
  	return -EINVAL;
  }
d41e26b90   Milan Broz   dm crypt: add merge
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
  static int crypt_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
  		       struct bio_vec *biovec, int max_size)
  {
  	struct crypt_config *cc = ti->private;
  	struct request_queue *q = bdev_get_queue(cc->dev->bdev);
  
  	if (!q->merge_bvec_fn)
  		return max_size;
  
  	bvm->bi_bdev = cc->dev->bdev;
b441a262e   Alasdair G Kergon   dm: use dm_target...
1729
  	bvm->bi_sector = cc->start + dm_target_offset(ti, bvm->bi_sector);
d41e26b90   Milan Broz   dm crypt: add merge
1730
1731
1732
  
  	return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
  }
af4874e03   Mike Snitzer   dm target:s intro...
1733
1734
1735
1736
  static int crypt_iterate_devices(struct dm_target *ti,
  				 iterate_devices_callout_fn fn, void *data)
  {
  	struct crypt_config *cc = ti->private;
5dea271b6   Mike Snitzer   dm table: pass co...
1737
  	return fn(ti, cc->dev, cc->start, ti->len, data);
af4874e03   Mike Snitzer   dm target:s intro...
1738
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1739
1740
  static struct target_type crypt_target = {
  	.name   = "crypt",
772ae5f54   Milan Broz   dm crypt: optiona...
1741
  	.version = {1, 11, 0},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1742
1743
1744
1745
1746
  	.module = THIS_MODULE,
  	.ctr    = crypt_ctr,
  	.dtr    = crypt_dtr,
  	.map    = crypt_map,
  	.status = crypt_status,
e48d4bbf9   Milan Broz   [PATCH] dm crypt:...
1747
1748
1749
1750
  	.postsuspend = crypt_postsuspend,
  	.preresume = crypt_preresume,
  	.resume = crypt_resume,
  	.message = crypt_message,
d41e26b90   Milan Broz   dm crypt: add merge
1751
  	.merge  = crypt_merge,
af4874e03   Mike Snitzer   dm target:s intro...
1752
  	.iterate_devices = crypt_iterate_devices,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
1754
1755
1756
1757
  };
  
  static int __init dm_crypt_init(void)
  {
  	int r;
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1758
  	_crypt_io_pool = KMEM_CACHE(dm_crypt_io, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1759
1760
  	if (!_crypt_io_pool)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1761
1762
  	r = dm_register_target(&crypt_target);
  	if (r < 0) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1763
  		DMERR("register failed %d", r);
9934a8bea   Milan Broz   dm crypt: use per...
1764
  		kmem_cache_destroy(_crypt_io_pool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1765
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1766
1767
1768
1769
1770
  	return r;
  }
  
  static void __exit dm_crypt_exit(void)
  {
10d3bd09a   Mikulas Patocka   dm: consolidate t...
1771
  	dm_unregister_target(&crypt_target);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1772
1773
1774
1775
1776
1777
1778
1779
1780
  	kmem_cache_destroy(_crypt_io_pool);
  }
  
  module_init(dm_crypt_init);
  module_exit(dm_crypt_exit);
  
  MODULE_AUTHOR("Christophe Saout <christophe@saout.de>");
  MODULE_DESCRIPTION(DM_NAME " target for transparent encryption / decryption");
  MODULE_LICENSE("GPL");