Skip to content

Commit b911fef

Browse files
committed
Intentionally break EVP_DigestFinal for SHAKE128 and SHAKE256
It will work only if OSSL_DIGEST_PARAM_XOFLEN is set. Reviewed-by: Paul Dale <ppzgs1@gmail.com> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from #24105)
1 parent 1706206 commit b911fef

6 files changed

Lines changed: 43 additions & 19 deletions

File tree

crypto/evp/digest.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
454454
if (ctx->digest->prov == NULL)
455455
goto legacy;
456456

457+
if (sz == 0) /* Assuming a xoflen must have been set. */
458+
mdsize = SIZE_MAX;
457459
if (ctx->digest->gettable_ctx_params != NULL) {
458460
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
459461

crypto/sha/sha3.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen)
3434
return 0;
3535
}
3636

37-
int ossl_keccak_kmac_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen)
37+
int ossl_keccak_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen, size_t mdlen)
3838
{
3939
int ret = ossl_sha3_init(ctx, pad, bitlen);
4040

4141
if (ret)
42-
ctx->md_size *= 2;
42+
ctx->md_size = mdlen / 8;
4343
return ret;
4444
}
4545

include/internal/sha3.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ struct keccak_st {
5151

5252
void ossl_sha3_reset(KECCAK1600_CTX *ctx);
5353
int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen);
54-
int ossl_keccak_kmac_init(KECCAK1600_CTX *ctx, unsigned char pad,
55-
size_t bitlen);
54+
int ossl_keccak_init(KECCAK1600_CTX *ctx, unsigned char pad,
55+
size_t typelen, size_t mdlen);
5656
int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
5757
int ossl_sha3_final(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen);
5858
int ossl_sha3_squeeze(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen);

providers/implementations/digests/sha3_prov.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <openssl/params.h>
1515
#include <openssl/err.h>
1616
#include <openssl/proverr.h>
17+
#include "internal/numbers.h"
1718
#include "internal/sha3.h"
1819
#include "prov/digestcommon.h"
1920
#include "prov/implementations.h"
@@ -112,6 +113,10 @@ static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
112113

113114
if (!ossl_prov_is_running())
114115
return 0;
116+
if (ctx->md_size == SIZE_MAX) {
117+
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
118+
return 0;
119+
}
115120
if (outlen > 0)
116121
ret = ctx->meth.final(ctx, out, ctx->md_size);
117122

@@ -474,7 +479,7 @@ static void *name##_newctx(void *provctx) \
474479
return ctx; \
475480
}
476481

477-
#define SHAKE_newctx(typ, uname, name, bitlen, pad) \
482+
#define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad) \
478483
static OSSL_FUNC_digest_newctx_fn name##_newctx; \
479484
static void *name##_newctx(void *provctx) \
480485
{ \
@@ -483,7 +488,9 @@ static void *name##_newctx(void *provctx) \
483488
\
484489
if (ctx == NULL) \
485490
return NULL; \
486-
ossl_sha3_init(ctx, pad, bitlen); \
491+
ossl_keccak_init(ctx, pad, bitlen, mdlen); \
492+
if (mdlen == 0) \
493+
ctx->md_size = SIZE_MAX; \
487494
SHAKE_SET_MD(uname, typ) \
488495
return ctx; \
489496
}
@@ -497,7 +504,7 @@ static void *uname##_newctx(void *provctx) \
497504
\
498505
if (ctx == NULL) \
499506
return NULL; \
500-
ossl_keccak_kmac_init(ctx, pad, bitlen); \
507+
ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen); \
501508
KMAC_SET_MD(bitlen) \
502509
return ctx; \
503510
}
@@ -585,10 +592,12 @@ static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
585592
SHA3_FLAGS)
586593

587594
#define IMPLEMENT_SHAKE_functions(bitlen) \
588-
SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f') \
595+
SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, \
596+
0 /* no default md length */, '\x1f') \
589597
PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \
590-
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
598+
SHA3_BLOCKSIZE(bitlen), 0, \
591599
SHAKE_FLAGS)
600+
592601
#define IMPLEMENT_KMAC_functions(bitlen) \
593602
KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \
594603
PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen, \

test/evp_xof_test.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,29 @@ static int shake_kat_digestfinal_test(void)
206206
EVP_MD_CTX *ctx = NULL;
207207
unsigned char out[sizeof(shake256_output)];
208208

209+
/* Test that EVP_DigestFinal without setting XOFLEN fails */
209210
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
210211
return 0;
211212
if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
212-
sizeof(shake256_input)))
213-
|| !TEST_true(EVP_DigestFinal(ctx, out, &digest_length))
214-
|| !TEST_uint_eq(digest_length, 32)
215-
|| !TEST_mem_eq(out, digest_length,
216-
shake256_output, digest_length)
213+
sizeof(shake256_input))))
214+
return 0;
215+
ERR_set_mark();
216+
if (!TEST_false(EVP_DigestFinal(ctx, out, &digest_length))) {
217+
ERR_clear_last_mark();
218+
return 0;
219+
}
220+
ERR_pop_to_mark();
221+
EVP_MD_CTX_free(ctx);
222+
223+
/* However EVP_DigestFinalXOF must work */
224+
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
225+
return 0;
226+
if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
227+
sizeof(shake256_input))))
228+
return 0;
229+
if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
230+
|| !TEST_mem_eq(out, sizeof(out),
231+
shake256_output, sizeof(shake256_output))
217232
|| !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
218233
goto err;
219234
ret = 1;

test/recipes/20-test_dgst.t

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,11 @@ subtest "Custom length XOF digest generation with `dgst` CLI" => sub {
223223
};
224224

225225
subtest "SHAKE digest generation with no xoflen set `dgst` CLI" => sub {
226-
plan tests => 1;
226+
plan tests => 2;
227227

228228
my $testdata = srctop_file('test', 'data.bin');
229-
my @xofdata = run(app(['openssl', 'dgst', '-shake128', $testdata], stderr => "outerr.txt"), capture => 1);
230-
chomp(@xofdata);
231-
my $expected = qr/SHAKE-128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa6/;
232-
ok($xofdata[0] =~ $expected, "Check short digest is output");
229+
ok(!run(app(['openssl', 'dgst', '-shake128', $testdata])), "SHAKE128 must fail without xoflen");
230+
ok(!run(app(['openssl', 'dgst', '-shake256', $testdata])), "SHAKE256 must fail without xoflen");
233231
};
234232

235233
SKIP: {

0 commit comments

Comments
 (0)