s390x: Fix s390x_shake_squeeze() when MSA 12 is available
On the first squeeze call, when finishing the absorb process, also set
the NIP flag, if we are still in XOF_STATE_INIT state. When MSA 12 is
available, the state buffer A has not been zeroed during initialization,
thus we must also pass the NIP flag here. This situation can happen
when a squeeze is performed without a preceding absorb (i.e. a SHAKE
of the empty message).
Add a test that performs a squeeze without a preceding absorb and check
if the result is correct.
Fixes: 25f5d7b85f
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25388)
This commit is contained in:
parent
979dc53001
commit
dc5afb7e87
@ -245,6 +245,7 @@ static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen)
|
|||||||
static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)
|
static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)
|
||||||
{
|
{
|
||||||
KECCAK1600_CTX *ctx = vctx;
|
KECCAK1600_CTX *ctx = vctx;
|
||||||
|
unsigned int fc;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (!ossl_prov_is_running())
|
if (!ossl_prov_is_running())
|
||||||
@ -255,8 +256,10 @@ static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen)
|
|||||||
* On the first squeeze call, finish the absorb process (incl. padding).
|
* On the first squeeze call, finish the absorb process (incl. padding).
|
||||||
*/
|
*/
|
||||||
if (ctx->xof_state != XOF_STATE_SQUEEZE) {
|
if (ctx->xof_state != XOF_STATE_SQUEEZE) {
|
||||||
|
fc = ctx->pad;
|
||||||
|
fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0;
|
||||||
ctx->xof_state = XOF_STATE_SQUEEZE;
|
ctx->xof_state = XOF_STATE_SQUEEZE;
|
||||||
s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, ctx->pad, ctx->A);
|
s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A);
|
||||||
ctx->bufsz = outlen % ctx->block_size;
|
ctx->bufsz = outlen % ctx->block_size;
|
||||||
/* reuse ctx->bufsz to count bytes squeezed from current sponge */
|
/* reuse ctx->bufsz to count bytes squeezed from current sponge */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -500,6 +500,34 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test that a squeeze without a preceding absorb works */
|
||||||
|
static int shake_squeeze_no_absorb_test(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
EVP_MD_CTX *ctx = NULL;
|
||||||
|
unsigned char out[1000];
|
||||||
|
unsigned char out2[1000];
|
||||||
|
const char *alg = "SHAKE128";
|
||||||
|
|
||||||
|
if (!TEST_ptr(ctx = shake_setup(alg))
|
||||||
|
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL))
|
||||||
|
|| !TEST_true(EVP_DigestSqueeze(ctx, out2, sizeof(out2) / 2))
|
||||||
|
|| !TEST_true(EVP_DigestSqueeze(ctx, out2 + sizeof(out2) / 2,
|
||||||
|
sizeof(out2) / 2)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!TEST_mem_eq(out2, sizeof(out2), out, sizeof(out)))
|
||||||
|
goto err;
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
EVP_MD_CTX_free(ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int xof_fail_test(void)
|
static int xof_fail_test(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -521,5 +549,6 @@ int setup_tests(void)
|
|||||||
ADD_ALL_TESTS(shake_squeeze_large_test, OSSL_NELEM(stride_tests));
|
ADD_ALL_TESTS(shake_squeeze_large_test, OSSL_NELEM(stride_tests));
|
||||||
ADD_ALL_TESTS(shake_squeeze_dup_test, OSSL_NELEM(dupoffset_tests));
|
ADD_ALL_TESTS(shake_squeeze_dup_test, OSSL_NELEM(dupoffset_tests));
|
||||||
ADD_TEST(xof_fail_test);
|
ADD_TEST(xof_fail_test);
|
||||||
|
ADD_TEST(shake_squeeze_no_absorb_test);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user