53
53
54
54
#define SHA_FLAGS_FINUP BIT(16)
55
55
#define SHA_FLAGS_SG BIT(17)
56
+ #define SHA_FLAGS_ALGO_MASK GENMASK(22, 18)
56
57
#define SHA_FLAGS_SHA1 BIT(18)
57
58
#define SHA_FLAGS_SHA224 BIT(19)
58
59
#define SHA_FLAGS_SHA256 BIT(20)
59
60
#define SHA_FLAGS_SHA384 BIT(21)
60
61
#define SHA_FLAGS_SHA512 BIT(22)
61
62
#define SHA_FLAGS_ERROR BIT(23)
62
63
#define SHA_FLAGS_PAD BIT(24)
64
+ #define SHA_FLAGS_RESTORE BIT(25)
63
65
64
66
#define SHA_OP_UPDATE 1
65
67
#define SHA_OP_FINAL 2
@@ -73,6 +75,7 @@ struct atmel_sha_caps {
73
75
bool has_dualbuff ;
74
76
bool has_sha224 ;
75
77
bool has_sha_384_512 ;
78
+ bool has_uihv ;
76
79
};
77
80
78
81
struct atmel_sha_dev ;
@@ -318,7 +321,8 @@ static int atmel_sha_init(struct ahash_request *req)
318
321
static void atmel_sha_write_ctrl (struct atmel_sha_dev * dd , int dma )
319
322
{
320
323
struct atmel_sha_reqctx * ctx = ahash_request_ctx (dd -> req );
321
- u32 valcr = 0 , valmr = SHA_MR_MODE_AUTO ;
324
+ u32 valmr = SHA_MR_MODE_AUTO ;
325
+ unsigned int i , hashsize = 0 ;
322
326
323
327
if (likely (dma )) {
324
328
if (!dd -> caps .has_dma )
@@ -330,22 +334,62 @@ static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma)
330
334
atmel_sha_write (dd , SHA_IER , SHA_INT_DATARDY );
331
335
}
332
336
333
- if (ctx -> flags & SHA_FLAGS_SHA1 )
337
+ switch (ctx -> flags & SHA_FLAGS_ALGO_MASK ) {
338
+ case SHA_FLAGS_SHA1 :
334
339
valmr |= SHA_MR_ALGO_SHA1 ;
335
- else if (ctx -> flags & SHA_FLAGS_SHA224 )
340
+ hashsize = SHA1_DIGEST_SIZE ;
341
+ break ;
342
+
343
+ case SHA_FLAGS_SHA224 :
336
344
valmr |= SHA_MR_ALGO_SHA224 ;
337
- else if (ctx -> flags & SHA_FLAGS_SHA256 )
345
+ hashsize = SHA256_DIGEST_SIZE ;
346
+ break ;
347
+
348
+ case SHA_FLAGS_SHA256 :
338
349
valmr |= SHA_MR_ALGO_SHA256 ;
339
- else if (ctx -> flags & SHA_FLAGS_SHA384 )
350
+ hashsize = SHA256_DIGEST_SIZE ;
351
+ break ;
352
+
353
+ case SHA_FLAGS_SHA384 :
340
354
valmr |= SHA_MR_ALGO_SHA384 ;
341
- else if (ctx -> flags & SHA_FLAGS_SHA512 )
355
+ hashsize = SHA512_DIGEST_SIZE ;
356
+ break ;
357
+
358
+ case SHA_FLAGS_SHA512 :
342
359
valmr |= SHA_MR_ALGO_SHA512 ;
360
+ hashsize = SHA512_DIGEST_SIZE ;
361
+ break ;
362
+
363
+ default :
364
+ break ;
365
+ }
343
366
344
367
/* Setting CR_FIRST only for the first iteration */
345
- if (!(ctx -> digcnt [0 ] || ctx -> digcnt [1 ]))
346
- valcr = SHA_CR_FIRST ;
368
+ if (!(ctx -> digcnt [0 ] || ctx -> digcnt [1 ])) {
369
+ atmel_sha_write (dd , SHA_CR , SHA_CR_FIRST );
370
+ } else if (dd -> caps .has_uihv && (ctx -> flags & SHA_FLAGS_RESTORE )) {
371
+ const u32 * hash = (const u32 * )ctx -> digest ;
372
+
373
+ /*
374
+ * Restore the hardware context: update the User Initialize
375
+ * Hash Value (UIHV) with the value saved when the latest
376
+ * 'update' operation completed on this very same crypto
377
+ * request.
378
+ */
379
+ ctx -> flags &= ~SHA_FLAGS_RESTORE ;
380
+ atmel_sha_write (dd , SHA_CR , SHA_CR_WUIHV );
381
+ for (i = 0 ; i < hashsize / sizeof (u32 ); ++ i )
382
+ atmel_sha_write (dd , SHA_REG_DIN (i ), hash [i ]);
383
+ atmel_sha_write (dd , SHA_CR , SHA_CR_FIRST );
384
+ valmr |= SHA_MR_UIHV ;
385
+ }
386
+ /*
387
+ * WARNING: If the UIHV feature is not available, the hardware CANNOT
388
+ * process concurrent requests: the internal registers used to store
389
+ * the hash/digest are still set to the partial digest output values
390
+ * computed during the latest round.
391
+ */
347
392
348
- atmel_sha_write (dd , SHA_CR , valcr );
349
393
atmel_sha_write (dd , SHA_MR , valmr );
350
394
}
351
395
@@ -714,23 +758,31 @@ static void atmel_sha_copy_hash(struct ahash_request *req)
714
758
{
715
759
struct atmel_sha_reqctx * ctx = ahash_request_ctx (req );
716
760
u32 * hash = (u32 * )ctx -> digest ;
717
- int i ;
761
+ unsigned int i , hashsize ;
718
762
719
- if (ctx -> flags & SHA_FLAGS_SHA1 )
720
- for (i = 0 ; i < SHA1_DIGEST_SIZE / sizeof (u32 ); i ++ )
721
- hash [i ] = atmel_sha_read (ctx -> dd , SHA_REG_DIGEST (i ));
722
- else if (ctx -> flags & SHA_FLAGS_SHA224 )
723
- for (i = 0 ; i < SHA224_DIGEST_SIZE / sizeof (u32 ); i ++ )
724
- hash [i ] = atmel_sha_read (ctx -> dd , SHA_REG_DIGEST (i ));
725
- else if (ctx -> flags & SHA_FLAGS_SHA256 )
726
- for (i = 0 ; i < SHA256_DIGEST_SIZE / sizeof (u32 ); i ++ )
727
- hash [i ] = atmel_sha_read (ctx -> dd , SHA_REG_DIGEST (i ));
728
- else if (ctx -> flags & SHA_FLAGS_SHA384 )
729
- for (i = 0 ; i < SHA384_DIGEST_SIZE / sizeof (u32 ); i ++ )
730
- hash [i ] = atmel_sha_read (ctx -> dd , SHA_REG_DIGEST (i ));
731
- else
732
- for (i = 0 ; i < SHA512_DIGEST_SIZE / sizeof (u32 ); i ++ )
733
- hash [i ] = atmel_sha_read (ctx -> dd , SHA_REG_DIGEST (i ));
763
+ switch (ctx -> flags & SHA_FLAGS_ALGO_MASK ) {
764
+ case SHA_FLAGS_SHA1 :
765
+ hashsize = SHA1_DIGEST_SIZE ;
766
+ break ;
767
+
768
+ case SHA_FLAGS_SHA224 :
769
+ case SHA_FLAGS_SHA256 :
770
+ hashsize = SHA256_DIGEST_SIZE ;
771
+ break ;
772
+
773
+ case SHA_FLAGS_SHA384 :
774
+ case SHA_FLAGS_SHA512 :
775
+ hashsize = SHA512_DIGEST_SIZE ;
776
+ break ;
777
+
778
+ default :
779
+ /* Should not happen... */
780
+ return ;
781
+ }
782
+
783
+ for (i = 0 ; i < hashsize / sizeof (u32 ); ++ i )
784
+ hash [i ] = atmel_sha_read (ctx -> dd , SHA_REG_DIGEST (i ));
785
+ ctx -> flags |= SHA_FLAGS_RESTORE ;
734
786
}
735
787
736
788
static void atmel_sha_copy_ready_hash (struct ahash_request * req )
@@ -1276,6 +1328,7 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
1276
1328
dd -> caps .has_dualbuff = 0 ;
1277
1329
dd -> caps .has_sha224 = 0 ;
1278
1330
dd -> caps .has_sha_384_512 = 0 ;
1331
+ dd -> caps .has_uihv = 0 ;
1279
1332
1280
1333
/* keep only major version number */
1281
1334
switch (dd -> hw_version & 0xff0 ) {
@@ -1284,12 +1337,14 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
1284
1337
dd -> caps .has_dualbuff = 1 ;
1285
1338
dd -> caps .has_sha224 = 1 ;
1286
1339
dd -> caps .has_sha_384_512 = 1 ;
1340
+ dd -> caps .has_uihv = 1 ;
1287
1341
break ;
1288
1342
case 0x420 :
1289
1343
dd -> caps .has_dma = 1 ;
1290
1344
dd -> caps .has_dualbuff = 1 ;
1291
1345
dd -> caps .has_sha224 = 1 ;
1292
1346
dd -> caps .has_sha_384_512 = 1 ;
1347
+ dd -> caps .has_uihv = 1 ;
1293
1348
break ;
1294
1349
case 0x410 :
1295
1350
dd -> caps .has_dma = 1 ;
0 commit comments