diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/async_tx/Kconfig | 5 | ||||
-rw-r--r-- | crypto/async_tx/async_pq.c | 14 | ||||
-rw-r--r-- | crypto/async_tx/async_xor.c | 15 | ||||
-rw-r--r-- | crypto/gcm.c | 107 |
4 files changed, 101 insertions, 40 deletions
diff --git a/crypto/async_tx/Kconfig b/crypto/async_tx/Kconfig index e5aeb2b79e6f..e28e276ac611 100644 --- a/crypto/async_tx/Kconfig +++ b/crypto/async_tx/Kconfig | |||
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV | |||
23 | select ASYNC_CORE | 23 | select ASYNC_CORE |
24 | select ASYNC_PQ | 24 | select ASYNC_PQ |
25 | 25 | ||
26 | config ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
27 | bool | ||
28 | |||
29 | config ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
30 | bool | ||
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c index 6b5cc4fba59f..ec87f53d5059 100644 --- a/crypto/async_tx/async_pq.c +++ b/crypto/async_tx/async_pq.c | |||
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks, | |||
240 | } | 240 | } |
241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); | 241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); |
242 | 242 | ||
243 | static inline struct dma_chan * | ||
244 | pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len) | ||
245 | { | ||
246 | #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
247 | return NULL; | ||
248 | #endif | ||
249 | return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0, blocks, | ||
250 | disks, len); | ||
251 | } | ||
252 | |||
243 | /** | 253 | /** |
244 | * async_syndrome_val - asynchronously validate a raid6 syndrome | 254 | * async_syndrome_val - asynchronously validate a raid6 syndrome |
245 | * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 | 255 | * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 |
@@ -260,9 +270,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks, | |||
260 | size_t len, enum sum_check_flags *pqres, struct page *spare, | 270 | size_t len, enum sum_check_flags *pqres, struct page *spare, |
261 | struct async_submit_ctl *submit) | 271 | struct async_submit_ctl *submit) |
262 | { | 272 | { |
263 | struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL, | 273 | struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len); |
264 | NULL, 0, blocks, disks, | ||
265 | len); | ||
266 | struct dma_device *device = chan ? chan->device : NULL; | 274 | struct dma_device *device = chan ? chan->device : NULL; |
267 | struct dma_async_tx_descriptor *tx; | 275 | struct dma_async_tx_descriptor *tx; |
268 | unsigned char coefs[disks-2]; | 276 | unsigned char coefs[disks-2]; |
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 79182dcb91b7..079ae8ca590b 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c | |||
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len) | |||
234 | memcmp(a, a + 4, len - 4) == 0); | 234 | memcmp(a, a + 4, len - 4) == 0); |
235 | } | 235 | } |
236 | 236 | ||
237 | static inline struct dma_chan * | ||
238 | xor_val_chan(struct async_submit_ctl *submit, struct page *dest, | ||
239 | struct page **src_list, int src_cnt, size_t len) | ||
240 | { | ||
241 | #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
242 | return NULL; | ||
243 | #endif | ||
244 | return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list, | ||
245 | src_cnt, len); | ||
246 | } | ||
247 | |||
237 | /** | 248 | /** |
238 | * async_xor_val - attempt a xor parity check with a dma engine. | 249 | * async_xor_val - attempt a xor parity check with a dma engine. |
239 | * @dest: destination page used if the xor is performed synchronously | 250 | * @dest: destination page used if the xor is performed synchronously |
@@ -255,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset, | |||
255 | int src_cnt, size_t len, enum sum_check_flags *result, | 266 | int src_cnt, size_t len, enum sum_check_flags *result, |
256 | struct async_submit_ctl *submit) | 267 | struct async_submit_ctl *submit) |
257 | { | 268 | { |
258 | struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL, | 269 | struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len); |
259 | &dest, 1, src_list, | ||
260 | src_cnt, len); | ||
261 | struct dma_device *device = chan ? chan->device : NULL; | 270 | struct dma_device *device = chan ? chan->device : NULL; |
262 | struct dma_async_tx_descriptor *tx = NULL; | 271 | struct dma_async_tx_descriptor *tx = NULL; |
263 | dma_addr_t *dma_src = NULL; | 272 | dma_addr_t *dma_src = NULL; |
diff --git a/crypto/gcm.c b/crypto/gcm.c index 5fc3292483ef..c6547130624c 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c | |||
@@ -40,7 +40,7 @@ struct crypto_rfc4106_ctx { | |||
40 | struct crypto_gcm_ghash_ctx { | 40 | struct crypto_gcm_ghash_ctx { |
41 | unsigned int cryptlen; | 41 | unsigned int cryptlen; |
42 | struct scatterlist *src; | 42 | struct scatterlist *src; |
43 | crypto_completion_t complete; | 43 | void (*complete)(struct aead_request *req, int err); |
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct crypto_gcm_req_priv_ctx { | 46 | struct crypto_gcm_req_priv_ctx { |
@@ -267,23 +267,26 @@ static int gcm_hash_final(struct aead_request *req, | |||
267 | return crypto_ahash_final(ahreq); | 267 | return crypto_ahash_final(ahreq); |
268 | } | 268 | } |
269 | 269 | ||
270 | static void gcm_hash_final_done(struct crypto_async_request *areq, | 270 | static void __gcm_hash_final_done(struct aead_request *req, int err) |
271 | int err) | ||
272 | { | 271 | { |
273 | struct aead_request *req = areq->data; | ||
274 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 272 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
275 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 273 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
276 | 274 | ||
277 | if (!err) | 275 | if (!err) |
278 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); | 276 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); |
279 | 277 | ||
280 | gctx->complete(areq, err); | 278 | gctx->complete(req, err); |
281 | } | 279 | } |
282 | 280 | ||
283 | static void gcm_hash_len_done(struct crypto_async_request *areq, | 281 | static void gcm_hash_final_done(struct crypto_async_request *areq, int err) |
284 | int err) | ||
285 | { | 282 | { |
286 | struct aead_request *req = areq->data; | 283 | struct aead_request *req = areq->data; |
284 | |||
285 | __gcm_hash_final_done(req, err); | ||
286 | } | ||
287 | |||
288 | static void __gcm_hash_len_done(struct aead_request *req, int err) | ||
289 | { | ||
287 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 290 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
288 | 291 | ||
289 | if (!err) { | 292 | if (!err) { |
@@ -292,13 +295,18 @@ static void gcm_hash_len_done(struct crypto_async_request *areq, | |||
292 | return; | 295 | return; |
293 | } | 296 | } |
294 | 297 | ||
295 | gcm_hash_final_done(areq, err); | 298 | __gcm_hash_final_done(req, err); |
296 | } | 299 | } |
297 | 300 | ||
298 | static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, | 301 | static void gcm_hash_len_done(struct crypto_async_request *areq, int err) |
299 | int err) | ||
300 | { | 302 | { |
301 | struct aead_request *req = areq->data; | 303 | struct aead_request *req = areq->data; |
304 | |||
305 | __gcm_hash_len_done(req, err); | ||
306 | } | ||
307 | |||
308 | static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err) | ||
309 | { | ||
302 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 310 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
303 | 311 | ||
304 | if (!err) { | 312 | if (!err) { |
@@ -307,13 +315,19 @@ static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, | |||
307 | return; | 315 | return; |
308 | } | 316 | } |
309 | 317 | ||
310 | gcm_hash_len_done(areq, err); | 318 | __gcm_hash_len_done(req, err); |
311 | } | 319 | } |
312 | 320 | ||
313 | static void gcm_hash_crypt_done(struct crypto_async_request *areq, | 321 | static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, |
314 | int err) | 322 | int err) |
315 | { | 323 | { |
316 | struct aead_request *req = areq->data; | 324 | struct aead_request *req = areq->data; |
325 | |||
326 | __gcm_hash_crypt_remain_done(req, err); | ||
327 | } | ||
328 | |||
329 | static void __gcm_hash_crypt_done(struct aead_request *req, int err) | ||
330 | { | ||
317 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 331 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
318 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 332 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
319 | unsigned int remain; | 333 | unsigned int remain; |
@@ -327,13 +341,18 @@ static void gcm_hash_crypt_done(struct crypto_async_request *areq, | |||
327 | return; | 341 | return; |
328 | } | 342 | } |
329 | 343 | ||
330 | gcm_hash_crypt_remain_done(areq, err); | 344 | __gcm_hash_crypt_remain_done(req, err); |
331 | } | 345 | } |
332 | 346 | ||
333 | static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, | 347 | static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err) |
334 | int err) | ||
335 | { | 348 | { |
336 | struct aead_request *req = areq->data; | 349 | struct aead_request *req = areq->data; |
350 | |||
351 | __gcm_hash_crypt_done(req, err); | ||
352 | } | ||
353 | |||
354 | static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err) | ||
355 | { | ||
337 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 356 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
338 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 357 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
339 | crypto_completion_t complete; | 358 | crypto_completion_t complete; |
@@ -350,15 +369,21 @@ static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, | |||
350 | } | 369 | } |
351 | 370 | ||
352 | if (remain) | 371 | if (remain) |
353 | gcm_hash_crypt_done(areq, err); | 372 | __gcm_hash_crypt_done(req, err); |
354 | else | 373 | else |
355 | gcm_hash_crypt_remain_done(areq, err); | 374 | __gcm_hash_crypt_remain_done(req, err); |
356 | } | 375 | } |
357 | 376 | ||
358 | static void gcm_hash_assoc_done(struct crypto_async_request *areq, | 377 | static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, |
359 | int err) | 378 | int err) |
360 | { | 379 | { |
361 | struct aead_request *req = areq->data; | 380 | struct aead_request *req = areq->data; |
381 | |||
382 | __gcm_hash_assoc_remain_done(req, err); | ||
383 | } | ||
384 | |||
385 | static void __gcm_hash_assoc_done(struct aead_request *req, int err) | ||
386 | { | ||
362 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 387 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
363 | unsigned int remain; | 388 | unsigned int remain; |
364 | 389 | ||
@@ -371,13 +396,18 @@ static void gcm_hash_assoc_done(struct crypto_async_request *areq, | |||
371 | return; | 396 | return; |
372 | } | 397 | } |
373 | 398 | ||
374 | gcm_hash_assoc_remain_done(areq, err); | 399 | __gcm_hash_assoc_remain_done(req, err); |
375 | } | 400 | } |
376 | 401 | ||
377 | static void gcm_hash_init_done(struct crypto_async_request *areq, | 402 | static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err) |
378 | int err) | ||
379 | { | 403 | { |
380 | struct aead_request *req = areq->data; | 404 | struct aead_request *req = areq->data; |
405 | |||
406 | __gcm_hash_assoc_done(req, err); | ||
407 | } | ||
408 | |||
409 | static void __gcm_hash_init_done(struct aead_request *req, int err) | ||
410 | { | ||
381 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 411 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
382 | crypto_completion_t complete; | 412 | crypto_completion_t complete; |
383 | unsigned int remain = 0; | 413 | unsigned int remain = 0; |
@@ -393,9 +423,16 @@ static void gcm_hash_init_done(struct crypto_async_request *areq, | |||
393 | } | 423 | } |
394 | 424 | ||
395 | if (remain) | 425 | if (remain) |
396 | gcm_hash_assoc_done(areq, err); | 426 | __gcm_hash_assoc_done(req, err); |
397 | else | 427 | else |
398 | gcm_hash_assoc_remain_done(areq, err); | 428 | __gcm_hash_assoc_remain_done(req, err); |
429 | } | ||
430 | |||
431 | static void gcm_hash_init_done(struct crypto_async_request *areq, int err) | ||
432 | { | ||
433 | struct aead_request *req = areq->data; | ||
434 | |||
435 | __gcm_hash_init_done(req, err); | ||
399 | } | 436 | } |
400 | 437 | ||
401 | static int gcm_hash(struct aead_request *req, | 438 | static int gcm_hash(struct aead_request *req, |
@@ -457,10 +494,8 @@ static void gcm_enc_copy_hash(struct aead_request *req, | |||
457 | crypto_aead_authsize(aead), 1); | 494 | crypto_aead_authsize(aead), 1); |
458 | } | 495 | } |
459 | 496 | ||
460 | static void gcm_enc_hash_done(struct crypto_async_request *areq, | 497 | static void gcm_enc_hash_done(struct aead_request *req, int err) |
461 | int err) | ||
462 | { | 498 | { |
463 | struct aead_request *req = areq->data; | ||
464 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 499 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
465 | 500 | ||
466 | if (!err) | 501 | if (!err) |
@@ -469,8 +504,7 @@ static void gcm_enc_hash_done(struct crypto_async_request *areq, | |||
469 | aead_request_complete(req, err); | 504 | aead_request_complete(req, err); |
470 | } | 505 | } |
471 | 506 | ||
472 | static void gcm_encrypt_done(struct crypto_async_request *areq, | 507 | static void gcm_encrypt_done(struct crypto_async_request *areq, int err) |
473 | int err) | ||
474 | { | 508 | { |
475 | struct aead_request *req = areq->data; | 509 | struct aead_request *req = areq->data; |
476 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 510 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
@@ -479,9 +513,13 @@ static void gcm_encrypt_done(struct crypto_async_request *areq, | |||
479 | err = gcm_hash(req, pctx); | 513 | err = gcm_hash(req, pctx); |
480 | if (err == -EINPROGRESS || err == -EBUSY) | 514 | if (err == -EINPROGRESS || err == -EBUSY) |
481 | return; | 515 | return; |
516 | else if (!err) { | ||
517 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); | ||
518 | gcm_enc_copy_hash(req, pctx); | ||
519 | } | ||
482 | } | 520 | } |
483 | 521 | ||
484 | gcm_enc_hash_done(areq, err); | 522 | aead_request_complete(req, err); |
485 | } | 523 | } |
486 | 524 | ||
487 | static int crypto_gcm_encrypt(struct aead_request *req) | 525 | static int crypto_gcm_encrypt(struct aead_request *req) |
@@ -538,9 +576,8 @@ static void gcm_decrypt_done(struct crypto_async_request *areq, int err) | |||
538 | aead_request_complete(req, err); | 576 | aead_request_complete(req, err); |
539 | } | 577 | } |
540 | 578 | ||
541 | static void gcm_dec_hash_done(struct crypto_async_request *areq, int err) | 579 | static void gcm_dec_hash_done(struct aead_request *req, int err) |
542 | { | 580 | { |
543 | struct aead_request *req = areq->data; | ||
544 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 581 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
545 | struct ablkcipher_request *abreq = &pctx->u.abreq; | 582 | struct ablkcipher_request *abreq = &pctx->u.abreq; |
546 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 583 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
@@ -552,9 +589,11 @@ static void gcm_dec_hash_done(struct crypto_async_request *areq, int err) | |||
552 | err = crypto_ablkcipher_decrypt(abreq); | 589 | err = crypto_ablkcipher_decrypt(abreq); |
553 | if (err == -EINPROGRESS || err == -EBUSY) | 590 | if (err == -EINPROGRESS || err == -EBUSY) |
554 | return; | 591 | return; |
592 | else if (!err) | ||
593 | err = crypto_gcm_verify(req, pctx); | ||
555 | } | 594 | } |
556 | 595 | ||
557 | gcm_decrypt_done(areq, err); | 596 | aead_request_complete(req, err); |
558 | } | 597 | } |
559 | 598 | ||
560 | static int crypto_gcm_decrypt(struct aead_request *req) | 599 | static int crypto_gcm_decrypt(struct aead_request *req) |