@@ -2590,11 +2590,22 @@ int chcr_aead_dma_map(struct device *dev,
2590
2590
struct chcr_aead_reqctx * reqctx = aead_request_ctx (req );
2591
2591
struct crypto_aead * tfm = crypto_aead_reqtfm (req );
2592
2592
unsigned int authsize = crypto_aead_authsize (tfm );
2593
- int dst_size ;
2593
+ int src_len , dst_len ;
2594
2594
2595
- dst_size = req -> assoclen + req -> cryptlen + (op_type ?
2596
- 0 : authsize );
2597
- if (!req -> cryptlen || !dst_size )
2595
+ /* calculate and handle src and dst sg length separately
2596
+ * for inplace and out-of place operations
2597
+ */
2598
+ if (req -> src == req -> dst ) {
2599
+ src_len = req -> assoclen + req -> cryptlen + (op_type ?
2600
+ 0 : authsize );
2601
+ dst_len = src_len ;
2602
+ } else {
2603
+ src_len = req -> assoclen + req -> cryptlen ;
2604
+ dst_len = req -> assoclen + req -> cryptlen + (op_type ?
2605
+ - authsize : authsize );
2606
+ }
2607
+
2608
+ if (!req -> cryptlen || !src_len || !dst_len )
2598
2609
return 0 ;
2599
2610
reqctx -> iv_dma = dma_map_single (dev , reqctx -> iv , (IV + reqctx -> b0_len ),
2600
2611
DMA_BIDIRECTIONAL );
@@ -2606,20 +2617,23 @@ int chcr_aead_dma_map(struct device *dev,
2606
2617
reqctx -> b0_dma = 0 ;
2607
2618
if (req -> src == req -> dst ) {
2608
2619
error = dma_map_sg (dev , req -> src ,
2609
- sg_nents_for_len (req -> src , dst_size ),
2620
+ sg_nents_for_len (req -> src , src_len ),
2610
2621
DMA_BIDIRECTIONAL );
2611
2622
if (!error )
2612
2623
goto err ;
2613
2624
} else {
2614
- error = dma_map_sg (dev , req -> src , sg_nents (req -> src ),
2625
+ error = dma_map_sg (dev , req -> src ,
2626
+ sg_nents_for_len (req -> src , src_len ),
2615
2627
DMA_TO_DEVICE );
2616
2628
if (!error )
2617
2629
goto err ;
2618
- error = dma_map_sg (dev , req -> dst , sg_nents (req -> dst ),
2630
+ error = dma_map_sg (dev , req -> dst ,
2631
+ sg_nents_for_len (req -> dst , dst_len ),
2619
2632
DMA_FROM_DEVICE );
2620
2633
if (!error ) {
2621
- dma_unmap_sg (dev , req -> src , sg_nents (req -> src ),
2622
- DMA_TO_DEVICE );
2634
+ dma_unmap_sg (dev , req -> src ,
2635
+ sg_nents_for_len (req -> src , src_len ),
2636
+ DMA_TO_DEVICE );
2623
2637
goto err ;
2624
2638
}
2625
2639
}
@@ -2637,24 +2651,37 @@ void chcr_aead_dma_unmap(struct device *dev,
2637
2651
struct chcr_aead_reqctx * reqctx = aead_request_ctx (req );
2638
2652
struct crypto_aead * tfm = crypto_aead_reqtfm (req );
2639
2653
unsigned int authsize = crypto_aead_authsize (tfm );
2640
- int dst_size ;
2654
+ int src_len , dst_len ;
2641
2655
2642
- dst_size = req -> assoclen + req -> cryptlen + (op_type ?
2643
- 0 : authsize );
2644
- if (!req -> cryptlen || !dst_size )
2656
+ /* calculate and handle src and dst sg length separately
2657
+ * for inplace and out-of place operations
2658
+ */
2659
+ if (req -> src == req -> dst ) {
2660
+ src_len = req -> assoclen + req -> cryptlen + (op_type ?
2661
+ 0 : authsize );
2662
+ dst_len = src_len ;
2663
+ } else {
2664
+ src_len = req -> assoclen + req -> cryptlen ;
2665
+ dst_len = req -> assoclen + req -> cryptlen + (op_type ?
2666
+ - authsize : authsize );
2667
+ }
2668
+
2669
+ if (!req -> cryptlen || !src_len || !dst_len )
2645
2670
return ;
2646
2671
2647
2672
dma_unmap_single (dev , reqctx -> iv_dma , (IV + reqctx -> b0_len ),
2648
2673
DMA_BIDIRECTIONAL );
2649
2674
if (req -> src == req -> dst ) {
2650
2675
dma_unmap_sg (dev , req -> src ,
2651
- sg_nents_for_len (req -> src , dst_size ),
2676
+ sg_nents_for_len (req -> src , src_len ),
2652
2677
DMA_BIDIRECTIONAL );
2653
2678
} else {
2654
- dma_unmap_sg (dev , req -> src , sg_nents (req -> src ),
2655
- DMA_TO_DEVICE );
2656
- dma_unmap_sg (dev , req -> dst , sg_nents (req -> dst ),
2657
- DMA_FROM_DEVICE );
2679
+ dma_unmap_sg (dev , req -> src ,
2680
+ sg_nents_for_len (req -> src , src_len ),
2681
+ DMA_TO_DEVICE );
2682
+ dma_unmap_sg (dev , req -> dst ,
2683
+ sg_nents_for_len (req -> dst , dst_len ),
2684
+ DMA_FROM_DEVICE );
2658
2685
}
2659
2686
}
2660
2687
@@ -4364,22 +4391,32 @@ static int chcr_unregister_alg(void)
4364
4391
for (i = 0 ; i < ARRAY_SIZE (driver_algs ); i ++ ) {
4365
4392
switch (driver_algs [i ].type & CRYPTO_ALG_TYPE_MASK ) {
4366
4393
case CRYPTO_ALG_TYPE_SKCIPHER :
4367
- if (driver_algs [i ].is_registered )
4394
+ if (driver_algs [i ].is_registered && refcount_read (
4395
+ & driver_algs [i ].alg .skcipher .base .cra_refcnt )
4396
+ == 1 ) {
4368
4397
crypto_unregister_skcipher (
4369
4398
& driver_algs [i ].alg .skcipher );
4399
+ driver_algs [i ].is_registered = 0 ;
4400
+ }
4370
4401
break ;
4371
4402
case CRYPTO_ALG_TYPE_AEAD :
4372
- if (driver_algs [i ].is_registered )
4403
+ if (driver_algs [i ].is_registered && refcount_read (
4404
+ & driver_algs [i ].alg .aead .base .cra_refcnt ) == 1 ) {
4373
4405
crypto_unregister_aead (
4374
4406
& driver_algs [i ].alg .aead );
4407
+ driver_algs [i ].is_registered = 0 ;
4408
+ }
4375
4409
break ;
4376
4410
case CRYPTO_ALG_TYPE_AHASH :
4377
- if (driver_algs [i ].is_registered )
4411
+ if (driver_algs [i ].is_registered && refcount_read (
4412
+ & driver_algs [i ].alg .hash .halg .base .cra_refcnt )
4413
+ == 1 ) {
4378
4414
crypto_unregister_ahash (
4379
4415
& driver_algs [i ].alg .hash );
4416
+ driver_algs [i ].is_registered = 0 ;
4417
+ }
4380
4418
break ;
4381
4419
}
4382
- driver_algs [i ].is_registered = 0 ;
4383
4420
}
4384
4421
return 0 ;
4385
4422
}
0 commit comments