Commit 04965549 authored by Antoine Ténart's avatar Antoine Ténart Committed by Herbert Xu

crypto: sun4i-ss - fix large block size support

The run-time self-tests fail quite early, as soon as the input block
size is larger than 64 bytes:

  alg: hash: Test 4 failed for sha1-sun4i-ss
  00000000: b9 c9 1e 52 c0 26 d8 39 81 ff f2 3c 99 b1 27 b2
  00000010: 30 d6 c9 85

One thing to notice is the value of the last word, which is the one
expected (it can sometime be the last two words). The datasheet isn't
very clear about when the digest is ready to retrieve and is seems the
bit SS_DATA_END is cleared when the digest was computed *but* that
doesn't mean the digest is ready to retrieve in the registers.

A ndelay(1) is added before reading the computed digest to ensure it is
available in the SS_MD[] registers.
Signed-off-by: default avatarAntoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: default avatarCorentin Labbe <clabbe.montjoie@gmail.com>
Acked-by: default avatarCorentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 0d9c68a9
...@@ -358,6 +358,15 @@ static int sun4i_hash(struct ahash_request *areq) ...@@ -358,6 +358,15 @@ static int sun4i_hash(struct ahash_request *areq)
goto release_ss; goto release_ss;
} }
/*
* The datasheet isn't very clear about when to retrieve the digest. The
* bit SS_DATA_END is cleared when the engine has processed the data and
* when the digest is computed *but* it doesn't mean the digest is
* available in the digest registers. Hence the delay to be sure we can
* read it.
*/
ndelay(1);
for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++)
op->hash[i] = readl(ss->base + SS_MD0 + i * 4); op->hash[i] = readl(ss->base + SS_MD0 + i * 4);
...@@ -446,6 +455,15 @@ static int sun4i_hash(struct ahash_request *areq) ...@@ -446,6 +455,15 @@ static int sun4i_hash(struct ahash_request *areq)
goto release_ss; goto release_ss;
} }
/*
* The datasheet isn't very clear about when to retrieve the digest. The
* bit SS_DATA_END is cleared when the engine has processed the data and
* when the digest is computed *but* it doesn't mean the digest is
* available in the digest registers. Hence the delay to be sure we can
* read it.
*/
ndelay(1);
/* Get the hash from the device */ /* Get the hash from the device */
if (op->mode == SS_OP_SHA1) { if (op->mode == SS_OP_SHA1) {
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment