]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/sha3: Fix SHA3 selftests failures
authorIngo Franzki <ifranzki@linux.ibm.com>
Wed, 4 Sep 2024 12:44:16 +0000 (14:44 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Thu, 5 Sep 2024 13:17:23 +0000 (15:17 +0200)
Since commit "s390/sha3: Support sha3 performance enhancements"
the selftests of the sha3_256_s390 and sha3_512_s390 kernel digests
sometimes fail with:

  alg: shash: sha3-256-s390 test failed (wrong result) on test vector 3,
              cfg="import/export"
  alg: self-tests for sha3-256 using sha3-256-s390 failed (rc=-22)

or with

  alg: ahash: sha3-256-s390 test failed (wrong result) on test vector 3,
              cfg="digest misaligned splits crossing pages"
  alg: self-tests for sha3-256 using sha3-256-s390 failed (rc=-22)

The first failure is because the newly introduced context field
'first_message_part' is not copied during export and import operations.
Because of that the value of 'first_message_part' is more or less random
after an import into a newly allocated context and may or may not fit to
the state of the imported SHA3 operation, causing an invalid hash when it
does not fit.

Save the 'first_message_part' field in the currently unused field 'partial'
of struct sha3_state, even though the meaning of 'partial' is not exactly
the same as 'first_message_part'. For the caller the returned state blob
is opaque and it must only be ensured that the state can be imported later
on by the module that exported it.

The second failure is when on entry of s390_sha_update() the flag
'first_message_part' is on, and kimd is called in the first 'if (index)'
block as well as in the second 'if (len >= bsize)' block. In this case,
the 'first_message_part' is turned off after the first kimd, but the
function code incorrectly retains the NIP flag. Reset the NIP flag after
the first kimd unconditionally besides turning 'first_message_part' off.

Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Fixes: 88c02b3f79a6 ("s390/sha3: Support sha3 performance enhancements")
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/crypto/sha3_256_s390.c
arch/s390/crypto/sha3_512_s390.c
arch/s390/crypto/sha_common.c

index 5bba972a2646c60b7bd34bbbff7b77ed52a657d4..a84ef692f572dafb64efca74f0bf1c9e3184ce82 100644 (file)
@@ -38,6 +38,7 @@ static int sha3_256_export(struct shash_desc *desc, void *out)
        octx->rsiz = sctx->count;
        memcpy(octx->st, sctx->state, sizeof(octx->st));
        memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
+       octx->partial = sctx->first_message_part;
 
        return 0;
 }
@@ -50,6 +51,7 @@ static int sha3_256_import(struct shash_desc *desc, const void *in)
        sctx->count = ictx->rsiz;
        memcpy(sctx->state, ictx->st, sizeof(ictx->st));
        memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
+       sctx->first_message_part = ictx->partial;
        sctx->func = CPACF_KIMD_SHA3_256;
 
        return 0;
@@ -63,6 +65,7 @@ static int sha3_224_import(struct shash_desc *desc, const void *in)
        sctx->count = ictx->rsiz;
        memcpy(sctx->state, ictx->st, sizeof(ictx->st));
        memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
+       sctx->first_message_part = ictx->partial;
        sctx->func = CPACF_KIMD_SHA3_224;
 
        return 0;
index 3554cbbafe9c83af90761b610a12d3f7a837375b..07528fc98ff7df4350b12631d4f89810fa9c424e 100644 (file)
@@ -39,6 +39,7 @@ static int sha3_512_export(struct shash_desc *desc, void *out)
 
        memcpy(octx->st, sctx->state, sizeof(octx->st));
        memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
+       octx->partial = sctx->first_message_part;
 
        return 0;
 }
@@ -54,6 +55,7 @@ static int sha3_512_import(struct shash_desc *desc, const void *in)
 
        memcpy(sctx->state, ictx->st, sizeof(ictx->st));
        memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
+       sctx->first_message_part = ictx->partial;
        sctx->func = CPACF_KIMD_SHA3_512;
 
        return 0;
@@ -70,6 +72,7 @@ static int sha3_384_import(struct shash_desc *desc, const void *in)
 
        memcpy(sctx->state, ictx->st, sizeof(ictx->st));
        memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
+       sctx->first_message_part = ictx->partial;
        sctx->func = CPACF_KIMD_SHA3_384;
 
        return 0;
index f6c7fda21abc82624340bdd95027b1769a0a70e8..961d7d522af157cda3ee489d338eef516f6d5979 100644 (file)
@@ -36,6 +36,7 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
                memcpy(ctx->buf + index, data, bsize - index);
                cpacf_kimd(fc, ctx->state, ctx->buf, bsize);
                ctx->first_message_part = 0;
+               fc &= ~CPACF_KIMD_NIP;
                data += bsize - index;
                len -= bsize - index;
                index = 0;