summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-verity-fec.c4
-rw-r--r--drivers/md/dm-verity-target.c201
-rw-r--r--drivers/md/dm-verity.h23
3 files changed, 157 insertions, 71 deletions
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 0f0eb8a3d922..dab98fee0754 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -188,7 +188,7 @@ error:
188static int fec_is_erasure(struct dm_verity *v, struct dm_verity_io *io, 188static int fec_is_erasure(struct dm_verity *v, struct dm_verity_io *io,
189 u8 *want_digest, u8 *data) 189 u8 *want_digest, u8 *data)
190{ 190{
191 if (unlikely(verity_hash(v, verity_io_hash_desc(v, io), 191 if (unlikely(verity_hash(v, verity_io_hash_req(v, io),
192 data, 1 << v->data_dev_block_bits, 192 data, 1 << v->data_dev_block_bits,
193 verity_io_real_digest(v, io)))) 193 verity_io_real_digest(v, io))))
194 return 0; 194 return 0;
@@ -397,7 +397,7 @@ static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io,
397 } 397 }
398 398
399 /* Always re-validate the corrected block against the expected hash */ 399 /* Always re-validate the corrected block against the expected hash */
400 r = verity_hash(v, verity_io_hash_desc(v, io), fio->output, 400 r = verity_hash(v, verity_io_hash_req(v, io), fio->output,
401 1 << v->data_dev_block_bits, 401 1 << v->data_dev_block_bits,
402 verity_io_real_digest(v, io)); 402 verity_io_real_digest(v, io));
403 if (unlikely(r < 0)) 403 if (unlikely(r < 0))
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 7335d8a3fc47..97de961a3bfc 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -93,81 +93,123 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
93} 93}
94 94
95/* 95/*
96 * Wrapper for crypto_shash_init, which handles verity salting. 96 * Callback function for asynchrnous crypto API completion notification
97 */ 97 */
98static int verity_hash_init(struct dm_verity *v, struct shash_desc *desc) 98static void verity_op_done(struct crypto_async_request *base, int err)
99{ 99{
100 int r; 100 struct verity_result *res = (struct verity_result *)base->data;
101 101
102 desc->tfm = v->tfm; 102 if (err == -EINPROGRESS)
103 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 103 return;
104 104
105 r = crypto_shash_init(desc); 105 res->err = err;
106 complete(&res->completion);
107}
106 108
107 if (unlikely(r < 0)) { 109/*
108 DMERR("crypto_shash_init failed: %d", r); 110 * Wait for async crypto API callback
109 return r; 111 */
110 } 112static inline int verity_complete_op(struct verity_result *res, int ret)
113{
114 switch (ret) {
115 case 0:
116 break;
111 117
112 if (likely(v->version >= 1)) { 118 case -EINPROGRESS:
113 r = crypto_shash_update(desc, v->salt, v->salt_size); 119 case -EBUSY:
120 ret = wait_for_completion_interruptible(&res->completion);
121 if (!ret)
122 ret = res->err;
123 reinit_completion(&res->completion);
124 break;
114 125
115 if (unlikely(r < 0)) { 126 default:
116 DMERR("crypto_shash_update failed: %d", r); 127 DMERR("verity_wait_hash: crypto op submission failed: %d", ret);
117 return r;
118 }
119 } 128 }
120 129
121 return 0; 130 if (unlikely(ret < 0))
131 DMERR("verity_wait_hash: crypto op failed: %d", ret);
132
133 return ret;
122} 134}
123 135
124static int verity_hash_update(struct dm_verity *v, struct shash_desc *desc, 136static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
125 const u8 *data, size_t len) 137 const u8 *data, size_t len,
138 struct verity_result *res)
126{ 139{
127 int r = crypto_shash_update(desc, data, len); 140 struct scatterlist sg;
128 141
129 if (unlikely(r < 0)) 142 sg_init_one(&sg, data, len);
130 DMERR("crypto_shash_update failed: %d", r); 143 ahash_request_set_crypt(req, &sg, NULL, len);
144
145 return verity_complete_op(res, crypto_ahash_update(req));
146}
147
148/*
149 * Wrapper for crypto_ahash_init, which handles verity salting.
150 */
151static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
152 struct verity_result *res)
153{
154 int r;
155
156 ahash_request_set_tfm(req, v->tfm);
157 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
158 CRYPTO_TFM_REQ_MAY_BACKLOG,
159 verity_op_done, (void *)res);
160 init_completion(&res->completion);
161
162 r = verity_complete_op(res, crypto_ahash_init(req));
163
164 if (unlikely(r < 0)) {
165 DMERR("crypto_ahash_init failed: %d", r);
166 return r;
167 }
168
169 if (likely(v->version >= 1))
170 r = verity_hash_update(v, req, v->salt, v->salt_size, res);
131 171
132 return r; 172 return r;
133} 173}
134 174
135static int verity_hash_final(struct dm_verity *v, struct shash_desc *desc, 175static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
136 u8 *digest) 176 u8 *digest, struct verity_result *res)
137{ 177{
138 int r; 178 int r;
139 179
140 if (unlikely(!v->version)) { 180 if (unlikely(!v->version)) {
141 r = crypto_shash_update(desc, v->salt, v->salt_size); 181 r = verity_hash_update(v, req, v->salt, v->salt_size, res);
142 182
143 if (r < 0) { 183 if (r < 0) {
144 DMERR("crypto_shash_update failed: %d", r); 184 DMERR("verity_hash_final failed updating salt: %d", r);
145 return r; 185 goto out;
146 } 186 }
147 } 187 }
148 188
149 r = crypto_shash_final(desc, digest); 189 ahash_request_set_crypt(req, NULL, digest, 0);
150 190 r = verity_complete_op(res, crypto_ahash_final(req));
151 if (unlikely(r < 0)) 191out:
152 DMERR("crypto_shash_final failed: %d", r);
153
154 return r; 192 return r;
155} 193}
156 194
157int verity_hash(struct dm_verity *v, struct shash_desc *desc, 195int verity_hash(struct dm_verity *v, struct ahash_request *req,
158 const u8 *data, size_t len, u8 *digest) 196 const u8 *data, size_t len, u8 *digest)
159{ 197{
160 int r; 198 int r;
199 struct verity_result res;
161 200
162 r = verity_hash_init(v, desc); 201 r = verity_hash_init(v, req, &res);
163 if (unlikely(r < 0)) 202 if (unlikely(r < 0))
164 return r; 203 goto out;
165 204
166 r = verity_hash_update(v, desc, data, len); 205 r = verity_hash_update(v, req, data, len, &res);
167 if (unlikely(r < 0)) 206 if (unlikely(r < 0))
168 return r; 207 goto out;
208
209 r = verity_hash_final(v, req, digest, &res);
169 210
170 return verity_hash_final(v, desc, digest); 211out:
212 return r;
171} 213}
172 214
173static void verity_hash_at_level(struct dm_verity *v, sector_t block, int level, 215static void verity_hash_at_level(struct dm_verity *v, sector_t block, int level,
@@ -275,7 +317,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
275 goto release_ret_r; 317 goto release_ret_r;
276 } 318 }
277 319
278 r = verity_hash(v, verity_io_hash_desc(v, io), 320 r = verity_hash(v, verity_io_hash_req(v, io),
279 data, 1 << v->hash_dev_block_bits, 321 data, 1 << v->hash_dev_block_bits,
280 verity_io_real_digest(v, io)); 322 verity_io_real_digest(v, io));
281 if (unlikely(r < 0)) 323 if (unlikely(r < 0))
@@ -344,6 +386,49 @@ out:
344} 386}
345 387
346/* 388/*
389 * Calculates the digest for the given bio
390 */
391int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
392 struct bvec_iter *iter, struct verity_result *res)
393{
394 unsigned int todo = 1 << v->data_dev_block_bits;
395 struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
396 struct scatterlist sg;
397 struct ahash_request *req = verity_io_hash_req(v, io);
398
399 do {
400 int r;
401 unsigned int len;
402 struct bio_vec bv = bio_iter_iovec(bio, *iter);
403
404 sg_init_table(&sg, 1);
405
406 len = bv.bv_len;
407
408 if (likely(len >= todo))
409 len = todo;
410 /*
411 * Operating on a single page at a time looks suboptimal
412 * until you consider the typical block size is 4,096B.
413 * Going through this loops twice should be very rare.
414 */
415 sg_set_page(&sg, bv.bv_page, len, bv.bv_offset);
416 ahash_request_set_crypt(req, &sg, NULL, len);
417 r = verity_complete_op(res, crypto_ahash_update(req));
418
419 if (unlikely(r < 0)) {
420 DMERR("verity_for_io_block crypto op failed: %d", r);
421 return r;
422 }
423
424 bio_advance_iter(bio, iter, len);
425 todo -= len;
426 } while (todo);
427
428 return 0;
429}
430
431/*
347 * Calls function process for 1 << v->data_dev_block_bits bytes in the bio_vec 432 * Calls function process for 1 << v->data_dev_block_bits bytes in the bio_vec
348 * starting from iter. 433 * starting from iter.
349 */ 434 */
@@ -381,12 +466,6 @@ int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io,
381 return 0; 466 return 0;
382} 467}
383 468
384static int verity_bv_hash_update(struct dm_verity *v, struct dm_verity_io *io,
385 u8 *data, size_t len)
386{
387 return verity_hash_update(v, verity_io_hash_desc(v, io), data, len);
388}
389
390static int verity_bv_zero(struct dm_verity *v, struct dm_verity_io *io, 469static int verity_bv_zero(struct dm_verity *v, struct dm_verity_io *io,
391 u8 *data, size_t len) 470 u8 *data, size_t len)
392{ 471{
@@ -403,10 +482,11 @@ static int verity_verify_io(struct dm_verity_io *io)
403 struct dm_verity *v = io->v; 482 struct dm_verity *v = io->v;
404 struct bvec_iter start; 483 struct bvec_iter start;
405 unsigned b; 484 unsigned b;
485 struct verity_result res;
406 486
407 for (b = 0; b < io->n_blocks; b++) { 487 for (b = 0; b < io->n_blocks; b++) {
408 int r; 488 int r;
409 struct shash_desc *desc = verity_io_hash_desc(v, io); 489 struct ahash_request *req = verity_io_hash_req(v, io);
410 490
411 r = verity_hash_for_block(v, io, io->block + b, 491 r = verity_hash_for_block(v, io, io->block + b,
412 verity_io_want_digest(v, io), 492 verity_io_want_digest(v, io),
@@ -427,16 +507,17 @@ static int verity_verify_io(struct dm_verity_io *io)
427 continue; 507 continue;
428 } 508 }
429 509
430 r = verity_hash_init(v, desc); 510 r = verity_hash_init(v, req, &res);
431 if (unlikely(r < 0)) 511 if (unlikely(r < 0))
432 return r; 512 return r;
433 513
434 start = io->iter; 514 start = io->iter;
435 r = verity_for_bv_block(v, io, &io->iter, verity_bv_hash_update); 515 r = verity_for_io_block(v, io, &io->iter, &res);
436 if (unlikely(r < 0)) 516 if (unlikely(r < 0))
437 return r; 517 return r;
438 518
439 r = verity_hash_final(v, desc, verity_io_real_digest(v, io)); 519 r = verity_hash_final(v, req, verity_io_real_digest(v, io),
520 &res);
440 if (unlikely(r < 0)) 521 if (unlikely(r < 0))
441 return r; 522 return r;
442 523
@@ -705,7 +786,7 @@ static void verity_dtr(struct dm_target *ti)
705 kfree(v->zero_digest); 786 kfree(v->zero_digest);
706 787
707 if (v->tfm) 788 if (v->tfm)
708 crypto_free_shash(v->tfm); 789 crypto_free_ahash(v->tfm);
709 790
710 kfree(v->alg_name); 791 kfree(v->alg_name);
711 792
@@ -723,7 +804,7 @@ static void verity_dtr(struct dm_target *ti)
723static int verity_alloc_zero_digest(struct dm_verity *v) 804static int verity_alloc_zero_digest(struct dm_verity *v)
724{ 805{
725 int r = -ENOMEM; 806 int r = -ENOMEM;
726 struct shash_desc *desc; 807 struct ahash_request *req;
727 u8 *zero_data; 808 u8 *zero_data;
728 809
729 v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL); 810 v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL);
@@ -731,9 +812,9 @@ static int verity_alloc_zero_digest(struct dm_verity *v)
731 if (!v->zero_digest) 812 if (!v->zero_digest)
732 return r; 813 return r;
733 814
734 desc = kmalloc(v->shash_descsize, GFP_KERNEL); 815 req = kmalloc(v->ahash_reqsize, GFP_KERNEL);
735 816
736 if (!desc) 817 if (!req)
737 return r; /* verity_dtr will free zero_digest */ 818 return r; /* verity_dtr will free zero_digest */
738 819
739 zero_data = kzalloc(1 << v->data_dev_block_bits, GFP_KERNEL); 820 zero_data = kzalloc(1 << v->data_dev_block_bits, GFP_KERNEL);
@@ -741,11 +822,11 @@ static int verity_alloc_zero_digest(struct dm_verity *v)
741 if (!zero_data) 822 if (!zero_data)
742 goto out; 823 goto out;
743 824
744 r = verity_hash(v, desc, zero_data, 1 << v->data_dev_block_bits, 825 r = verity_hash(v, req, zero_data, 1 << v->data_dev_block_bits,
745 v->zero_digest); 826 v->zero_digest);
746 827
747out: 828out:
748 kfree(desc); 829 kfree(req);
749 kfree(zero_data); 830 kfree(zero_data);
750 831
751 return r; 832 return r;
@@ -923,21 +1004,21 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
923 goto bad; 1004 goto bad;
924 } 1005 }
925 1006
926 v->tfm = crypto_alloc_shash(v->alg_name, 0, 0); 1007 v->tfm = crypto_alloc_ahash(v->alg_name, 0, 0);
927 if (IS_ERR(v->tfm)) { 1008 if (IS_ERR(v->tfm)) {
928 ti->error = "Cannot initialize hash function"; 1009 ti->error = "Cannot initialize hash function";
929 r = PTR_ERR(v->tfm); 1010 r = PTR_ERR(v->tfm);
930 v->tfm = NULL; 1011 v->tfm = NULL;
931 goto bad; 1012 goto bad;
932 } 1013 }
933 v->digest_size = crypto_shash_digestsize(v->tfm); 1014 v->digest_size = crypto_ahash_digestsize(v->tfm);
934 if ((1 << v->hash_dev_block_bits) < v->digest_size * 2) { 1015 if ((1 << v->hash_dev_block_bits) < v->digest_size * 2) {
935 ti->error = "Digest size too big"; 1016 ti->error = "Digest size too big";
936 r = -EINVAL; 1017 r = -EINVAL;
937 goto bad; 1018 goto bad;
938 } 1019 }
939 v->shash_descsize = 1020 v->ahash_reqsize = sizeof(struct ahash_request) +
940 sizeof(struct shash_desc) + crypto_shash_descsize(v->tfm); 1021 crypto_ahash_reqsize(v->tfm);
941 1022
942 v->root_digest = kmalloc(v->digest_size, GFP_KERNEL); 1023 v->root_digest = kmalloc(v->digest_size, GFP_KERNEL);
943 if (!v->root_digest) { 1024 if (!v->root_digest) {
@@ -1037,7 +1118,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
1037 } 1118 }
1038 1119
1039 ti->per_io_data_size = sizeof(struct dm_verity_io) + 1120 ti->per_io_data_size = sizeof(struct dm_verity_io) +
1040 v->shash_descsize + v->digest_size * 2; 1121 v->ahash_reqsize + v->digest_size * 2;
1041 1122
1042 r = verity_fec_ctr(v); 1123 r = verity_fec_ctr(v);
1043 if (r) 1124 if (r)
diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
index fb419f422d73..a59e0ada6fd3 100644
--- a/drivers/md/dm-verity.h
+++ b/drivers/md/dm-verity.h
@@ -37,7 +37,7 @@ struct dm_verity {
37 struct dm_target *ti; 37 struct dm_target *ti;
38 struct dm_bufio_client *bufio; 38 struct dm_bufio_client *bufio;
39 char *alg_name; 39 char *alg_name;
40 struct crypto_shash *tfm; 40 struct crypto_ahash *tfm;
41 u8 *root_digest; /* digest of the root block */ 41 u8 *root_digest; /* digest of the root block */
42 u8 *salt; /* salt: its size is salt_size */ 42 u8 *salt; /* salt: its size is salt_size */
43 u8 *zero_digest; /* digest for a zero block */ 43 u8 *zero_digest; /* digest for a zero block */
@@ -52,7 +52,7 @@ struct dm_verity {
52 unsigned char levels; /* the number of tree levels */ 52 unsigned char levels; /* the number of tree levels */
53 unsigned char version; 53 unsigned char version;
54 unsigned digest_size; /* digest size for the current hash algorithm */ 54 unsigned digest_size; /* digest size for the current hash algorithm */
55 unsigned shash_descsize;/* the size of temporary space for crypto */ 55 unsigned int ahash_reqsize;/* the size of temporary space for crypto */
56 int hash_failed; /* set to 1 if hash of any block failed */ 56 int hash_failed; /* set to 1 if hash of any block failed */
57 enum verity_mode mode; /* mode for handling verification errors */ 57 enum verity_mode mode; /* mode for handling verification errors */
58 unsigned corrupted_errs;/* Number of errors for corrupted blocks */ 58 unsigned corrupted_errs;/* Number of errors for corrupted blocks */
@@ -81,31 +81,36 @@ struct dm_verity_io {
81 /* 81 /*
82 * Three variably-size fields follow this struct: 82 * Three variably-size fields follow this struct:
83 * 83 *
84 * u8 hash_desc[v->shash_descsize]; 84 * u8 hash_req[v->ahash_reqsize];
85 * u8 real_digest[v->digest_size]; 85 * u8 real_digest[v->digest_size];
86 * u8 want_digest[v->digest_size]; 86 * u8 want_digest[v->digest_size];
87 * 87 *
88 * To access them use: verity_io_hash_desc(), verity_io_real_digest() 88 * To access them use: verity_io_hash_req(), verity_io_real_digest()
89 * and verity_io_want_digest(). 89 * and verity_io_want_digest().
90 */ 90 */
91}; 91};
92 92
93static inline struct shash_desc *verity_io_hash_desc(struct dm_verity *v, 93struct verity_result {
94 struct completion completion;
95 int err;
96};
97
98static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v,
94 struct dm_verity_io *io) 99 struct dm_verity_io *io)
95{ 100{
96 return (struct shash_desc *)(io + 1); 101 return (struct ahash_request *)(io + 1);
97} 102}
98 103
99static inline u8 *verity_io_real_digest(struct dm_verity *v, 104static inline u8 *verity_io_real_digest(struct dm_verity *v,
100 struct dm_verity_io *io) 105 struct dm_verity_io *io)
101{ 106{
102 return (u8 *)(io + 1) + v->shash_descsize; 107 return (u8 *)(io + 1) + v->ahash_reqsize;
103} 108}
104 109
105static inline u8 *verity_io_want_digest(struct dm_verity *v, 110static inline u8 *verity_io_want_digest(struct dm_verity *v,
106 struct dm_verity_io *io) 111 struct dm_verity_io *io)
107{ 112{
108 return (u8 *)(io + 1) + v->shash_descsize + v->digest_size; 113 return (u8 *)(io + 1) + v->ahash_reqsize + v->digest_size;
109} 114}
110 115
111static inline u8 *verity_io_digest_end(struct dm_verity *v, 116static inline u8 *verity_io_digest_end(struct dm_verity *v,
@@ -120,7 +125,7 @@ extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io,
120 struct dm_verity_io *io, 125 struct dm_verity_io *io,
121 u8 *data, size_t len)); 126 u8 *data, size_t len));
122 127
123extern int verity_hash(struct dm_verity *v, struct shash_desc *desc, 128extern int verity_hash(struct dm_verity *v, struct ahash_request *req,
124 const u8 *data, size_t len, u8 *digest); 129 const u8 *data, size_t len, u8 *digest);
125 130
126extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io, 131extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,