summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto/s390x_arch.h1
-rw-r--r--providers/implementations/digests/sha3_prov.c13
2 files changed, 6 insertions, 8 deletions
diff --git a/crypto/s390x_arch.h b/crypto/s390x_arch.h
index cfb3460d5b..3f7dac2e74 100644
--- a/crypto/s390x_arch.h
+++ b/crypto/s390x_arch.h
@@ -182,5 +182,6 @@ extern int OPENSSL_s390xcex;
# define S390X_KMA_LAAD 0x200
# define S390X_KMA_HS 0x400
# define S390X_KDSA_D 0x80
+# define S390X_KLMD_PS 0x100
#endif
diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c
index 33dc6660bf..825d3249fa 100644
--- a/providers/implementations/digests/sha3_prov.c
+++ b/providers/implementations/digests/sha3_prov.c
@@ -183,7 +183,6 @@ static int s390x_keccakc_final(unsigned char *md, void *vctx, int padding)
size_t bsz = ctx->block_size;
size_t num = ctx->bufsz;
size_t needed = ctx->md_size;
- static const unsigned char empty[KECCAK1600_WIDTH / 8] = {0};
if (!ossl_prov_is_running())
return 0;
@@ -193,13 +192,11 @@ static int s390x_keccakc_final(unsigned char *md, void *vctx, int padding)
ctx->buf[num] = padding;
ctx->buf[bsz - 1] |= 0x80;
s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A);
- while (needed > bsz) {
- memcpy(md, ctx->A, bsz);
- needed -= bsz;
- md += bsz;
- s390x_kimd(empty, bsz, ctx->pad, ctx->A);
- }
- memcpy(md, ctx->A, needed);
+ num = needed > bsz ? bsz : needed;
+ memcpy(md, ctx->A, num);
+ needed -= num;
+ if (needed > 0)
+ s390x_klmd(NULL, 0, md + bsz, needed, ctx->pad | S390X_KLMD_PS, ctx->A);
return 1;
}