crypto: s390/sha3 - Use cpu byte-order when exporting

The sha3 partial hash on s390 is in little-endian just like the
final hash.  However the generic implementation produces native
or big-endian partial hashes.

Make s390 sha3 conform to that by doing the byte-swap on export
and import.

Reported-by: Ingo Franzki <ifranzki@linux.ibm.com>
Fixes: 6f90ba7065 ("crypto: s390/sha3 - Use API partial block handling")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Herbert Xu 2025-05-23 20:28:56 +08:00
parent 1b39bc4a70
commit 73c2437109
3 changed files with 35 additions and 13 deletions

View File

@ -27,6 +27,9 @@ struct s390_sha_ctx {
u64 state[SHA512_DIGEST_SIZE / sizeof(u64)];
u64 count_hi;
} sha512;
struct {
__le64 state[SHA3_STATE_SIZE / sizeof(u64)];
} sha3;
};
int func; /* KIMD function to use */
bool first_message_part;

View File

@ -35,23 +35,33 @@ static int sha3_256_init(struct shash_desc *desc)
static int sha3_256_export(struct shash_desc *desc, void *out)
{
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
struct sha3_state *octx = out;
union {
u8 *u8;
u64 *u64;
} p = { .u8 = out };
int i;
if (sctx->first_message_part) {
memset(sctx->state, 0, sizeof(sctx->state));
sctx->first_message_part = 0;
memset(out, 0, SHA3_STATE_SIZE);
return 0;
}
memcpy(octx->st, sctx->state, sizeof(octx->st));
for (i = 0; i < SHA3_STATE_SIZE / 8; i++)
put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++);
return 0;
}
static int sha3_256_import(struct shash_desc *desc, const void *in)
{
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
const struct sha3_state *ictx = in;
union {
const u8 *u8;
const u64 *u64;
} p = { .u8 = in };
int i;
for (i = 0; i < SHA3_STATE_SIZE / 8; i++)
sctx->sha3.state[i] = cpu_to_le64(get_unaligned(p.u64++));
sctx->count = 0;
memcpy(sctx->state, ictx->st, sizeof(ictx->st));
sctx->first_message_part = 0;
sctx->func = CPACF_KIMD_SHA3_256;

View File

@ -34,24 +34,33 @@ static int sha3_512_init(struct shash_desc *desc)
static int sha3_512_export(struct shash_desc *desc, void *out)
{
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
struct sha3_state *octx = out;
union {
u8 *u8;
u64 *u64;
} p = { .u8 = out };
int i;
if (sctx->first_message_part) {
memset(sctx->state, 0, sizeof(sctx->state));
sctx->first_message_part = 0;
memset(out, 0, SHA3_STATE_SIZE);
return 0;
}
memcpy(octx->st, sctx->state, sizeof(octx->st));
for (i = 0; i < SHA3_STATE_SIZE / 8; i++)
put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++);
return 0;
}
static int sha3_512_import(struct shash_desc *desc, const void *in)
{
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
const struct sha3_state *ictx = in;
union {
const u8 *u8;
const u64 *u64;
} p = { .u8 = in };
int i;
for (i = 0; i < SHA3_STATE_SIZE / 8; i++)
sctx->sha3.state[i] = cpu_to_le64(get_unaligned(p.u64++));
sctx->count = 0;
memcpy(sctx->state, ictx->st, sizeof(ictx->st));
sctx->first_message_part = 0;
sctx->func = CPACF_KIMD_SHA3_512;