From 195c600873c95b3a01b8724354e28fe753119ea2 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Mon, 19 Oct 2026 14:18:55 -0700 Subject: [PATCH 1/3] digest: SHAKE squeeze and output length parity Add the squeeze call OpenSSL 3.3+ uses (ML-KEM, ML-DSA) and match the default provider's output length handling: no default length or digest size from 3.4, xoflen/size readable from the context. Mark the AlgorithmIdentifier parameters absent; no absorbing after output starts. --- src/wp_digests.c | 231 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 209 insertions(+), 22 deletions(-) diff --git a/src/wp_digests.c b/src/wp_digests.c index fb027688..8d37c067 100644 --- a/src/wp_digests.c +++ b/src/wp_digests.c @@ -584,10 +584,44 @@ IMPLEMENT_DIGEST(wp_sha3_512, wc_Sha3, * XOF ******************************************************************************/ +/** XOF is absorbing input. */ +#define WP_XOF_ABSORB 0 +/** XOF output is being squeezed. */ +#define WP_XOF_SQUEEZE 1 +/** XOF has been finalized. */ +#define WP_XOF_FINAL 2 + +/* OpenSSL 3.4+ SHAKE has no default output length or digest size. */ +#if OPENSSL_VERSION_NUMBER >= 0x30400000L + #define WP_XOF_DEFAULT_LEN(len) SIZE_MAX + #define WP_XOF_SIZE(len) 0 +#else + #define WP_XOF_DEFAULT_LEN(len) (len) + #define WP_XOF_SIZE(len) (len) +#endif + +/** Implement creating a new XOF object. */ +#define IMPLEMENT_XOF_NEWCTX(alg, name, CTX, dgstSize) \ +/** \ + * Create a new XOF context object with the default output length. \ + * \ + * @param [in] provCtx Provider context. \ + * @return NULL on error. \ + * @return XOF context object on success. \ + */ \ +static CTX* name##_newctx(WOLFPROV_CTX* provCtx) \ +{ \ + CTX* ctx = wp_##alg##_newctx(provCtx); \ + if (ctx != NULL) { \ + ctx->outLen = WP_XOF_DEFAULT_LEN(dgstSize); \ + } \ + return ctx; \ +} + /** Implement initialization of an XOF object. */ #define IMPLEMENT_XOF_INIT(alg, name, CTX, init) \ /** \ - * Initialize the XOF context object. \ + * Initialize the XOF context object. Absorbing restarts; output length kept. \ * \ * @param [in] ctx XOF context object. \ * @param [in, out] params Parameters to be set. \ @@ -608,6 +642,9 @@ static int name##_init(CTX* ctx, const OSSL_PARAM params[]) \ WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, #init, rc); \ ok = 0; \ } \ + ctx->state = WP_XOF_ABSORB; \ + ctx->bufLen = 0; \ + OPENSSL_cleanse(ctx->buf, sizeof(ctx->buf)); \ } \ if (ok && (!wp_##alg##_set_ctx_params(ctx, params))) { \ ok = 0; \ @@ -616,10 +653,34 @@ static int name##_init(CTX* ctx, const OSSL_PARAM params[]) \ return ok; \ } \ +/** Implement updating an XOF object with data. */ +#define IMPLEMENT_XOF_UPDATE(name, WC_CTX, CTX, upd) \ +IMPLEMENT_DIGEST_UPDATE(name##_absorb, WC_CTX, upd) \ +/** \ + * Update the XOF context object with data. Fails once output has started. \ + * \ + * @param [in, out] ctx XOF context object. \ + * @param [in] in Data to be absorbed. \ + * @param [in] inLen Length of data in bytes. \ + * @return 1 on success. \ + * @return 0 on failure. \ + */ \ +static int name##_update(CTX* ctx, const unsigned char* in, size_t inLen) \ +{ \ + int ok = (ctx != NULL) && (ctx->state == WP_XOF_ABSORB); \ + WOLFPROV_ENTER(WP_LOG_COMP_DIGEST, #name "_update"); \ + if (ok) { \ + ok = name##_absorb_update(&ctx->obj, in, inLen); \ + } \ + WOLFPROV_LEAVE(WP_LOG_COMP_DIGEST, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);\ + return ok; \ +} + /** Implement finalizing an XOF object to produce output. */ #define IMPLEMENT_XOF_FINAL(name, CTX, dgstSize, fin) \ /** \ - * Finalize the XOF operation. \ + * Finalize the XOF operation. Fails once squeezed or finalized, or when the \ + * output length is unset (OpenSSL 3.4+) or larger than outSize. \ * \ * @param [in, out] ctx XOF context object. \ * @param [out] out Output buffer. \ @@ -636,22 +697,93 @@ static int name##_final(CTX* ctx, unsigned char* out, size_t* outLen, \ if (!wolfssl_prov_is_running()) { \ ok = 0; \ } \ - if (ok && ((outSize < ctx->outLen) || (!WP_FITS_WORD32(ctx->outLen)))) { \ + if (ok && ((ctx->state != WP_XOF_ABSORB) || (outSize < ctx->outLen) || \ + (!WP_FITS_WORD32(ctx->outLen)))) { \ ok = 0; \ } \ if (ok) { \ - int rc = fin(&ctx->obj, out, (word32)ctx->outLen); \ + int rc = (ctx->outLen == 0) ? 0 : \ + fin(&ctx->obj, out, (word32)ctx->outLen); \ if (rc != 0) { \ WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, #fin, rc); \ ok = 0; \ } \ else { \ *outLen = ctx->outLen; \ + ctx->state = WP_XOF_FINAL; \ + } \ + } \ + WOLFPROV_LEAVE(WP_LOG_COMP_DIGEST, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);\ + return ok; \ +} + +#if defined(OSSL_FUNC_DIGEST_SQUEEZE) && (LIBWOLFSSL_VERSION_HEX >= 0x05005001) +/** Implement squeezing output from an XOF object. */ +#define IMPLEMENT_XOF_SQUEEZE(name, CTX, blkSize, absorb, squeeze) \ +/** \ + * Squeeze output from the XOF. Can be called repeatedly until finalized. \ + * \ + * @param [in, out] ctx XOF context object. \ + * @param [out] out Output buffer. \ + * @param [out] outLen Length of output in bytes. \ + * @param [in] outSize Number of bytes to squeeze. \ + * @return 1 on success. \ + * @return 0 on failure. \ + */ \ +static int name##_squeeze(CTX* ctx, unsigned char* out, size_t* outLen, \ + size_t outSize) \ +{ \ + int ok = 1; \ + int rc; \ + size_t len = outSize; \ + size_t n; \ + WOLFPROV_ENTER(WP_LOG_COMP_DIGEST, #name "_squeeze"); \ + if ((!wolfssl_prov_is_running()) || (ctx == NULL) || \ + ((len > 0) && (ctx->state == WP_XOF_FINAL))) { \ + ok = 0; \ + } \ + if (ok && (len > 0) && (ctx->state == WP_XOF_ABSORB)) { \ + /* Pad the absorbed data; output comes from whole squeezed blocks. */ \ + rc = absorb(&ctx->obj, ctx->buf, 0); \ + if (rc != 0) { \ + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, #absorb, rc); \ + ctx->state = WP_XOF_FINAL; \ + ok = 0; \ + } \ + else { \ + ctx->state = WP_XOF_SQUEEZE; \ + ctx->bufLen = 0; \ + } \ + } \ + while (ok && (len > 0)) { \ + if (ctx->bufLen == 0) { \ + rc = squeeze(&ctx->obj, ctx->buf, 1); \ + if (rc != 0) { \ + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, #squeeze, rc); \ + ok = 0; \ + break; \ + } \ + ctx->bufLen = blkSize; \ } \ + n = (len < ctx->bufLen) ? len : ctx->bufLen; \ + XMEMCPY(out, ctx->buf + blkSize - ctx->bufLen, n); \ + out += n; \ + len -= n; \ + ctx->bufLen -= n; \ + } \ + if (ok) { \ + *outLen = outSize; \ } \ WOLFPROV_LEAVE(WP_LOG_COMP_DIGEST, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);\ return ok; \ } +/** Dispatch table entry for squeezing. */ +#define WP_XOF_SQUEEZE_FUNC(name) \ + { OSSL_FUNC_DIGEST_SQUEEZE, (DFUNC)name##_squeeze }, +#else +#define IMPLEMENT_XOF_SQUEEZE(name, CTX, blkSize, absorb, squeeze) +#define WP_XOF_SQUEEZE_FUNC(name) +#endif /** Implement disposing of an XOF object. */ #define IMPLEMENT_XOF_FREECTX(name, CTX, free) \ @@ -694,6 +826,9 @@ static CTX* name##_dupctx(CTX* src) \ } \ else { \ dst->outLen = src->outLen; \ + dst->state = src->state; \ + dst->bufLen = src->bufLen; \ + XMEMCPY(dst->buf, src->buf, sizeof(dst->buf)); \ } \ } \ return dst; \ @@ -716,30 +851,68 @@ static int name##_set_ctx_params(CTX* ctx, const OSSL_PARAM params[]) \ if (!wolfssl_prov_is_running()) { \ ok = 0; \ } \ - if (ok && (params != NULL) && (!wp_params_get_size_t(params, \ - OSSL_DIGEST_PARAM_XOFLEN, &ctx->outLen))) { \ - ok = 0; \ + if (ok && (params != NULL)) { \ + /* Size is an alias of XOF length. */ \ + const OSSL_PARAM* p = OSSL_PARAM_locate_const(params, \ + OSSL_DIGEST_PARAM_XOFLEN); \ + if (p == NULL) { \ + p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE); \ + } \ + if ((p != NULL) && (!OSSL_PARAM_get_size_t(p, &ctx->outLen))) { \ + ok = 0; \ + } \ } \ WOLFPROV_LEAVE(WP_LOG_COMP_DIGEST, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);\ return ok; \ } +/** Implement getting the context parameters. */ +#define IMPLEMENT_XOF_GET_CTX_PARAMS(name, CTX) \ +/** \ + * Get the output length from the context. \ + * \ + * @param [in] ctx XOF context. \ + * @param [in, out] params Parameters to be filled. \ + * @return 1 on success. \ + * @return 0 on failure. \ + */ \ +static int name##_get_ctx_params(CTX* ctx, OSSL_PARAM params[]) \ +{ \ + int ok = 1; \ + OSSL_PARAM* p; \ + WOLFPROV_ENTER(WP_LOG_COMP_DIGEST, #name "_get_ctx_params"); \ + if (ctx == NULL) { \ + ok = 0; \ + } \ + p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN); \ + if (ok && (p != NULL) && (!OSSL_PARAM_set_size_t(p, ctx->outLen))) { \ + ok = 0; \ + } \ + p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); \ + if (ok && (p != NULL) && (!OSSL_PARAM_set_size_t(p, ctx->outLen))) { \ + ok = 0; \ + } \ + WOLFPROV_LEAVE(WP_LOG_COMP_DIGEST, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);\ + return ok; \ +} /** * Implement the XOF functions for an algorithm. * Also define the dispatch table for the functions. */ #define IMPLEMENT_XOF(alg, name, WC_CTX, CTX, blkSize, dgstSize, flags, \ - init, upd, fin, copy, free) \ + init, upd, fin, copy, free, absorb, squeeze) \ +IMPLEMENT_XOF_NEWCTX(alg, name, CTX, dgstSize) \ IMPLEMENT_XOF_INIT(alg, name, CTX, init) \ -IMPLEMENT_DIGEST_UPDATE(name, WC_CTX, upd) \ +IMPLEMENT_XOF_UPDATE(name, WC_CTX, CTX, upd) \ IMPLEMENT_XOF_FINAL(name, CTX, dgstSize, fin) \ +IMPLEMENT_XOF_SQUEEZE(name, CTX, blkSize, absorb, squeeze) \ IMPLEMENT_XOF_FREECTX(name, CTX, free) \ IMPLEMENT_XOF_DUPCTX(name, CTX, copy) \ -IMPLEMENT_DIGEST_GET_PARAM(name, blkSize, dgstSize, flags) \ +IMPLEMENT_DIGEST_GET_PARAM(name, blkSize, WP_XOF_SIZE(dgstSize), flags) \ /** Dispatch table for XOF algorithms. */ \ const OSSL_DISPATCH name##_functions[] = { \ - { OSSL_FUNC_DIGEST_NEWCTX, (DFUNC)wp_##alg##_newctx }, \ + { OSSL_FUNC_DIGEST_NEWCTX, (DFUNC)name##_newctx }, \ { OSSL_FUNC_DIGEST_INIT, (DFUNC)name##_init }, \ { OSSL_FUNC_DIGEST_UPDATE, (DFUNC)name##_update }, \ { OSSL_FUNC_DIGEST_FINAL, (DFUNC)name##_final }, \ @@ -748,8 +921,10 @@ const OSSL_DISPATCH name##_functions[] = { \ { OSSL_FUNC_DIGEST_GET_PARAMS, (DFUNC)name##_get_params }, \ { OSSL_FUNC_DIGEST_GETTABLE_PARAMS, (DFUNC)wp_digest_gettable_params }, \ { OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (DFUNC)wp_##alg##_set_ctx_params }, \ - { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \ - (DFUNC)wp_xof_settable_ctx_params }, \ + { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, (DFUNC)wp_xof_ctx_params }, \ + { OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (DFUNC)wp_##alg##_get_ctx_params }, \ + { OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, (DFUNC)wp_xof_ctx_params }, \ + WP_XOF_SQUEEZE_FUNC(name) \ { 0, NULL } \ }; @@ -760,46 +935,58 @@ const OSSL_DISPATCH name##_functions[] = { \ #ifdef WP_HAVE_SHAKE_256 /** - * Get the table of supported settable parameters for XOF. + * Get the table of supported settable and gettable parameters for XOF. * * @param [in] ctx Context object. Unused. * @param [in] provCtx Provider context. Unused. * @return Table of supported parameters. */ -static const OSSL_PARAM* wp_xof_settable_ctx_params(void* ctx, - WOLFPROV_CTX* provCtx) +static const OSSL_PARAM* wp_xof_ctx_params(void* ctx, WOLFPROV_CTX* provCtx) { - static const OSSL_PARAM wp_xof_supported_settable_ctx_params[] = { + static const OSSL_PARAM wp_xof_supported_ctx_params[] = { {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, + {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, OSSL_PARAM_END }; (void)ctx; (void)provCtx; - return wp_xof_supported_settable_ctx_params; + return wp_xof_supported_ctx_params; } -/** All SHAKE algorithms are eXtendable Output Functions. */ -#define WP_SHAKE_FLAGS WP_DIGEST_FLAG_XOF +/** SHAKE algorithms are XOFs without parameters in the ASN.1 alg id. */ +#define WP_SHAKE_FLAGS (WP_DIGEST_FLAG_XOF | WP_DIGEST_FLAG_ALGID_ABSENT) + +/** Largest SHAKE block size (SHAKE-128 rate). */ +#define WP_SHAKE_MAX_BLOCK_SIZE 168 /** * SHAKE context object. - * Need to keep the outpt length for finalization. + * Keeps the output length for finalization and the squeeze state. */ typedef struct wp_ShakeCtx { /** wolfSSL SHAKE object - must be first field. */ wc_Shake obj; + /** Last squeezed block - follows obj to be 8-byte aligned. + * Last bufLen bytes not yet output. */ + unsigned char buf[WP_SHAKE_MAX_BLOCK_SIZE]; + /** Number of squeezed bytes in buf not yet output. */ + size_t bufLen; /** Output length when finalization is called. */ size_t outLen; + /** Absorbing, squeezing or finalized. */ + int state; } wp_ShakeCtx; IMPLEMENT_DIGEST_NEWCTX(wp_shake, wp_ShakeCtx) IMPLEMENT_XOF_SET_CTX_PARAMS(wp_shake, wp_ShakeCtx) +IMPLEMENT_XOF_GET_CTX_PARAMS(wp_shake, wp_ShakeCtx) IMPLEMENT_XOF(shake, wp_shake_256, wc_Shake, wp_ShakeCtx, WC_SHA3_256_BLOCK_SIZE, WC_SHA3_256_DIGEST_SIZE, WP_SHAKE_FLAGS, wc_InitShake256, wc_Shake256_Update, wc_Shake256_Final, - wc_Shake256_Copy, wc_Shake256_Free) + wc_Shake256_Copy, wc_Shake256_Free, wc_Shake256_Absorb, + wc_Shake256_SqueezeBlocks) #endif From de5ecec2d46764fcddf8b13014d18f86aa8825a9 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Mon, 19 Oct 2026 14:18:55 -0700 Subject: [PATCH 2/3] digest: register SHAKE-128 wolfCrypt builds with WOLFSSL_SHAKE128 but only SHAKE-256 was exposed, so SHAKE-128 fetches (openssl dgst -shake128, Python hashlib) failed. Reuse the SHAKE-256 XOF code with the wc_Shake128 functions. --- README.md | 2 +- include/wolfprovider/alg_funcs.h | 2 ++ include/wolfprovider/settings.h | 4 ++++ src/wp_digests.c | 14 +++++++++++++- src/wp_wolfprov.c | 6 +++++- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3db632e3..943c11e9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Information on how to configure, build, and test wolfProvider can be found here: * SHA-1 * SHA-2: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256 * SHA-3: SHA3-224, SHA3-256, SHA3-384, SHA3-512 -* SHAKE-256 +* SHAKE-128, SHAKE-256 ### Symmetric Ciphers * AES (128, 192, 256-bit keys) diff --git a/include/wolfprovider/alg_funcs.h b/include/wolfprovider/alg_funcs.h index 771a1a76..1bc287cb 100644 --- a/include/wolfprovider/alg_funcs.h +++ b/include/wolfprovider/alg_funcs.h @@ -86,6 +86,7 @@ typedef void (*DFUNC)(void); #define WP_NAMES_SHA3_384 "SHA3-384:2.16.840.1.101.3.4.2.9" #define WP_NAMES_SHA3_512 "SHA3-512:2.16.840.1.101.3.4.2.10" +#define WP_NAMES_SHAKE_128 "SHAKE-128:SHAKE128:2.16.840.1.101.3.4.2.11" #define WP_NAMES_SHAKE_256 "SHAKE-256:SHAKE256:2.16.840.1.101.3.4.2.12" /* Cipher names. */ @@ -396,6 +397,7 @@ extern const OSSL_DISPATCH wp_sha3_256_functions[]; extern const OSSL_DISPATCH wp_sha3_384_functions[]; extern const OSSL_DISPATCH wp_sha3_512_functions[]; +extern const OSSL_DISPATCH wp_shake_128_functions[]; extern const OSSL_DISPATCH wp_shake_256_functions[]; /* Cipher implementations. */ diff --git a/include/wolfprovider/settings.h b/include/wolfprovider/settings.h index cdda021c..659a3d4d 100644 --- a/include/wolfprovider/settings.h +++ b/include/wolfprovider/settings.h @@ -92,6 +92,10 @@ #define WP_HAVE_SHA3_256 #define WP_HAVE_SHA3_384 #define WP_HAVE_SHA3_512 + #if (LIBWOLFSSL_VERSION_HEX >= 0x05005001) && defined(WOLFSSL_SHAKE128) && \ + !defined(WOLFSSL_NO_SHAKE128) + #define WP_HAVE_SHAKE_128 + #endif #if (LIBWOLFSSL_VERSION_HEX >= 0x05000000) && defined(WOLFSSL_SHAKE256) && \ !defined(WOLFSSL_NO_SHAKE256) #define WP_HAVE_SHAKE_256 diff --git a/src/wp_digests.c b/src/wp_digests.c index 8d37c067..9b6e7cbb 100644 --- a/src/wp_digests.c +++ b/src/wp_digests.c @@ -932,7 +932,7 @@ const OSSL_DISPATCH name##_functions[] = { \ * SHAKE ******************************************************************************/ -#ifdef WP_HAVE_SHAKE_256 +#if defined(WP_HAVE_SHAKE_128) || defined(WP_HAVE_SHAKE_256) /** * Get the table of supported settable and gettable parameters for XOF. @@ -982,11 +982,23 @@ IMPLEMENT_DIGEST_NEWCTX(wp_shake, wp_ShakeCtx) IMPLEMENT_XOF_SET_CTX_PARAMS(wp_shake, wp_ShakeCtx) IMPLEMENT_XOF_GET_CTX_PARAMS(wp_shake, wp_ShakeCtx) +#ifdef WP_HAVE_SHAKE_128 +/* No wolfCrypt SHAKE-128 digest size constant: 128 / 8. */ +IMPLEMENT_XOF(shake, wp_shake_128, wc_Shake, wp_ShakeCtx, + WC_SHA3_128_BLOCK_SIZE, 16, + WP_SHAKE_FLAGS, + wc_InitShake128, wc_Shake128_Update, wc_Shake128_Final, + wc_Shake128_Copy, wc_Shake128_Free, wc_Shake128_Absorb, + wc_Shake128_SqueezeBlocks) +#endif + +#ifdef WP_HAVE_SHAKE_256 IMPLEMENT_XOF(shake, wp_shake_256, wc_Shake, wp_ShakeCtx, WC_SHA3_256_BLOCK_SIZE, WC_SHA3_256_DIGEST_SIZE, WP_SHAKE_FLAGS, wc_InitShake256, wc_Shake256_Update, wc_Shake256_Final, wc_Shake256_Copy, wc_Shake256_Free, wc_Shake256_Absorb, wc_Shake256_SqueezeBlocks) +#endif #endif diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c index 69446838..e90a813f 100644 --- a/src/wp_wolfprov.c +++ b/src/wp_wolfprov.c @@ -460,8 +460,12 @@ static const OSSL_ALGORITHM wolfprov_digests[] = { "" }, #endif -#ifdef WP_HAVE_SHAKE_256 /* SHAKE */ +#ifdef WP_HAVE_SHAKE_128 + { WP_NAMES_SHAKE_128, WOLFPROV_PROPERTIES, wp_shake_128_functions, + "" }, +#endif +#ifdef WP_HAVE_SHAKE_256 { WP_NAMES_SHAKE_256, WOLFPROV_PROPERTIES, wp_shake_256_functions, "" }, #endif From 9bf6dd00b54cb8e78d51a895b75cd796b1509c21 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Mon, 19 Oct 2026 14:18:55 -0700 Subject: [PATCH 3/3] test: SHAKE-128 and XOF parity with the default provider Mirror test_shake_256 for SHAKE-128 and compare default length final, squeeze across block boundaries and flags with OpenSSL for both SHAKEs. Enable the SHAKE128 evp_test vectors. --- scripts/evp_test/evpmd_sha.txt | 46 ++++----- test/test_digest.c | 175 ++++++++++++++++++++++++++++++++- test/unit.c | 3 + test/unit.h | 3 + 4 files changed, 203 insertions(+), 24 deletions(-) diff --git a/scripts/evp_test/evpmd_sha.txt b/scripts/evp_test/evpmd_sha.txt index 09973994..66ddf459 100644 --- a/scripts/evp_test/evpmd_sha.txt +++ b/scripts/evp_test/evpmd_sha.txt @@ -228,22 +228,22 @@ Digest = SHA3-512 Input = 991c4e7402c7da689dd5525af76fcc58fe9cc1451308c0c4600363586ccc83c9ec10a8c9ddaec3d7cfbd206484d09634b9780108440bf27a5fa4a428446b3214fa17084b6eb197c5c59a4e8df1cfc521826c3b1cbf6f4212f6bfb9bc106dfb5568395643de58bffa2774c31e67f5c1e7017f57caadbb1a56cc5b8a5cf9584552e17e7af9542ba13e9c54695e0dc8f24eddb93d5a3678e10c8a80ff4f27b677d40bef5cb5f9b3a659cc4127970cd2c11ebf22d514812dfefdd73600dfc10efba38e93e5bff47736126043e50f8b9b941e4ec3083fb762dbf15c86 Output = cd0f2a48e9aa8cc700d3f64efb013f3600ebdbb524930c682d21025eab990eb6d7c52e611f884031fafd9360e5225ab7e4ec24cbe97f3af6dbe4a86a4f068ba7 -#Digest = SHAKE128 -#Input = "" -#Output = 7F9C2BA4E88F827D616045507605853ED73B8093F6EFBC88EB1A6EACFA66EF263CB1EEA988004B93103CFB0AEEFD2A686E01FA4A58E8A3639CA8A1E3F9AE57E235B8CC873C23DC62B8D260169AFA2F75AB916A58D974918835D25E6A435085B2BADFD6DFAAC359A5EFBB7BCC4B59D538DF9A04302E10C8BC1CBF1A0B3A5120EA17CDA7CFAD765F5623474D368CCCA8AF0007CD9F5E4C849F167A580B14AABDEFAEE7EEF47CB0FCA9767BE1FDA69419DFB927E9DF07348B196691ABAEB580B32DEF58538B8D23F87732EA63B02B4FA0F4873360E2841928CD60DD4CEE8CC0D4C922A96188D032675C8AC850933C7AFF1533B94C834ADBB69C6115BAD4692D8619F90B0CDF8A7B9C264029AC185B70B83F2801F2F4B3F70C593EA3AEEB613A7F1B1DE33FD75081F592305F2E4526EDC09631B10958F464D889F31BA010250FDA7F1368EC2967FC84EF2AE9AFF268E0B1700AFFC6820B523A3D917135F2DFF2EE06BFE72B3124721D4A26C04E53A75E30E73A7A9C4A95D91C55D495E9F51DD0B5E9D83C6D5E8CE803AA62B8D654DB53D09B8DCFF273CDFEB573FAD8BCD45578BEC2E770D01EFDE86E721A3F7C6CCE275DABE6E2143F1AF18DA7EFDDC4C7B70B5E345DB93CC936BEA323491CCB38A388F546A9FF00DD4E1300B9B2153D2041D205B443E41B45A653F2A5C4492C1ADD544512DDA2529833462B71A41A45BE97290B6F -# -#Digest = SHAKE128 -#Input = A3 -#Count = 200 -#Output = 131AB8D2B594946B9C81333F9BB6E0CE75C3B93104FA3469D3917457385DA037CF232EF7164A6D1EB448C8908186AD852D3F85A5CF28DA1AB6FE3438171978467F1C05D58C7EF38C284C41F6C2221A76F12AB1C04082660250802294FB87180213FDEF5B0ECB7DF50CA1F8555BE14D32E10F6EDCDE892C09424B29F597AFC270C904556BFCB47A7D40778D390923642B3CBD0579E60908D5A000C1D08B98EF933F806445BF87F8B009BA9E94F7266122ED7AC24E5E266C42A82FA1BBEFB7B8DB0066E16A85E0493F07DF4809AEC084A593748AC3DDE5A6D7AAE1E8B6E5352B2D71EFBB47D4CAEED5E6D633805D2D323E6FD81B4684B93A2677D45E7421C2C6AEA259B855A698FD7D13477A1FE53E5A4A6197DBEC5CE95F505B520BCD9570C4A8265A7E01F89C0C002C59BFEC6CD4A5C109258953EE5EE70CD577EE217AF21FA70178F0946C9BF6CA8751793479F6B537737E40B6ED28511D8A2D7E73EB75F8DAAC912FF906E0AB955B083BAC45A8E5E9B744C8506F37E9B4E749A184B30F43EB188D855F1B70D71FF3E50C537AC1B0F8974F0FE1A6AD295BA42F6AEC74D123A7ABEDDE6E2C0711CAB36BE5ACB1A5A11A4B1DB08BA6982EFCCD716929A7741CFC63AA4435E0B69A9063E880795C3DC5EF3272E11C497A91ACF699FEFEE206227A44C9FB359FD56AC0A9A75A743CFF6862F17D7259AB075216C0699511643B6439 -# -#Digest = SHAKE128 -#Input = a6fe00064257aa318b621c5eb311d32bb8004c2fa1a969d205d71762cc5d2e633907992629d1b69d9557ff6d5e8deb454ab00f6e497c89a4fea09e257a6fa2074bd818ceb5981b3e3faefd6e720f2d1edd9c5e4a5c51e5009abf636ed5bca53fe159c8287014a1bd904f5c8a7501625f79ac81eb618f478ce21cae6664acffb30572f059e1ad0fc2912264e8f1ca52af26c8bf78e09d75f3dd9fc734afa8770abe0bd78c90cc2ff448105fb16dd2c5b7edd8611a62e537db9331f5023e16d6ec150cc6e706d7c7fcbfff930c7281831fd5c4aff86ece57ed0db882f59a5fe403105d0592ca38a081fed84922873f538ee774f13b8cc09bd0521db4374aec69f4bae6dcb66455822c0b84c91a3474ffac2ad06f0a4423cd2c6a49d4f0d6242d6a1890937b5d9835a5f0ea5b1d01884d22a6c1718e1f60b3ab5e232947c76ef70b344171083c688093b5f1475377e3069863 -#Output = 3109d9472ca436e805c6b3db2251a9bc -# -#Digest = SHAKE128 -#Input = 49d81708d86cd59dea0ac2c1017a9712d6dffb754dde0b57a9023a39fc5f5b6be276fc176f59f6826610428fac3a0e85fcf71011db061b8fcf2bf085ccd45670effb6dc46f4e3f2ed08e981c5935187fc95b86cf46da675096b1cf9591a67842d6301116be93d8288e4d6b70f1b1db8aa5d203b774a21825665b8170351ee86801da91154570eaf80a1564945af7822df8232fd04ea65593a7f2ab1e9e84cf6ad6c494c9ec2d9d27aaad2b8f7e4f33f12a17b422bc2d4724c13ff8a8b62054d1bfb5c33b9c11183cd8df67694300165ca37637b5a781155f1c070d156339a0242374c6723b6584bffb71c02b935455f8cb086392f5e8e8cc2015956d8f19daeb6aca4476b27108387a2ce0dc5591154d0b94ddc090abe8f4363036b821062baffb7fe550ea7dcd30bfd86c84710081e1c9e450475e123c5ec41f98ff0149bbf6405b5207cad1fb2f313d0f2bcee9be3f6ebe623049640d9234ab644a172ab14ba02633a339b5b9bb38226fda5694f7ec63ebbb8238eb8219ec9c429f4bf0353383a72f2d21702f5e3c513499f04852710f33044512edc47a56bad90885e5713851a7efac694b869fa590076e844ff757d95de581c1b3fa3dd8ccd28cad4f8ae173ee1b28f98ee606dca89063fbef0f262b33053f2c854debdc9cd433ab77abb64f445aa9b981761c4761767f3b71c2646c7b0d873baae50bc9f0 -#Output = c609be05458f7ab33e7b6b54bc6e8999 +Digest = SHAKE128 +Input = "" +Output = 7F9C2BA4E88F827D616045507605853ED73B8093F6EFBC88EB1A6EACFA66EF263CB1EEA988004B93103CFB0AEEFD2A686E01FA4A58E8A3639CA8A1E3F9AE57E235B8CC873C23DC62B8D260169AFA2F75AB916A58D974918835D25E6A435085B2BADFD6DFAAC359A5EFBB7BCC4B59D538DF9A04302E10C8BC1CBF1A0B3A5120EA17CDA7CFAD765F5623474D368CCCA8AF0007CD9F5E4C849F167A580B14AABDEFAEE7EEF47CB0FCA9767BE1FDA69419DFB927E9DF07348B196691ABAEB580B32DEF58538B8D23F87732EA63B02B4FA0F4873360E2841928CD60DD4CEE8CC0D4C922A96188D032675C8AC850933C7AFF1533B94C834ADBB69C6115BAD4692D8619F90B0CDF8A7B9C264029AC185B70B83F2801F2F4B3F70C593EA3AEEB613A7F1B1DE33FD75081F592305F2E4526EDC09631B10958F464D889F31BA010250FDA7F1368EC2967FC84EF2AE9AFF268E0B1700AFFC6820B523A3D917135F2DFF2EE06BFE72B3124721D4A26C04E53A75E30E73A7A9C4A95D91C55D495E9F51DD0B5E9D83C6D5E8CE803AA62B8D654DB53D09B8DCFF273CDFEB573FAD8BCD45578BEC2E770D01EFDE86E721A3F7C6CCE275DABE6E2143F1AF18DA7EFDDC4C7B70B5E345DB93CC936BEA323491CCB38A388F546A9FF00DD4E1300B9B2153D2041D205B443E41B45A653F2A5C4492C1ADD544512DDA2529833462B71A41A45BE97290B6F + +Digest = SHAKE128 +Input = A3 +Count = 200 +Output = 131AB8D2B594946B9C81333F9BB6E0CE75C3B93104FA3469D3917457385DA037CF232EF7164A6D1EB448C8908186AD852D3F85A5CF28DA1AB6FE3438171978467F1C05D58C7EF38C284C41F6C2221A76F12AB1C04082660250802294FB87180213FDEF5B0ECB7DF50CA1F8555BE14D32E10F6EDCDE892C09424B29F597AFC270C904556BFCB47A7D40778D390923642B3CBD0579E60908D5A000C1D08B98EF933F806445BF87F8B009BA9E94F7266122ED7AC24E5E266C42A82FA1BBEFB7B8DB0066E16A85E0493F07DF4809AEC084A593748AC3DDE5A6D7AAE1E8B6E5352B2D71EFBB47D4CAEED5E6D633805D2D323E6FD81B4684B93A2677D45E7421C2C6AEA259B855A698FD7D13477A1FE53E5A4A6197DBEC5CE95F505B520BCD9570C4A8265A7E01F89C0C002C59BFEC6CD4A5C109258953EE5EE70CD577EE217AF21FA70178F0946C9BF6CA8751793479F6B537737E40B6ED28511D8A2D7E73EB75F8DAAC912FF906E0AB955B083BAC45A8E5E9B744C8506F37E9B4E749A184B30F43EB188D855F1B70D71FF3E50C537AC1B0F8974F0FE1A6AD295BA42F6AEC74D123A7ABEDDE6E2C0711CAB36BE5ACB1A5A11A4B1DB08BA6982EFCCD716929A7741CFC63AA4435E0B69A9063E880795C3DC5EF3272E11C497A91ACF699FEFEE206227A44C9FB359FD56AC0A9A75A743CFF6862F17D7259AB075216C0699511643B6439 + +Digest = SHAKE128 +Input = a6fe00064257aa318b621c5eb311d32bb8004c2fa1a969d205d71762cc5d2e633907992629d1b69d9557ff6d5e8deb454ab00f6e497c89a4fea09e257a6fa2074bd818ceb5981b3e3faefd6e720f2d1edd9c5e4a5c51e5009abf636ed5bca53fe159c8287014a1bd904f5c8a7501625f79ac81eb618f478ce21cae6664acffb30572f059e1ad0fc2912264e8f1ca52af26c8bf78e09d75f3dd9fc734afa8770abe0bd78c90cc2ff448105fb16dd2c5b7edd8611a62e537db9331f5023e16d6ec150cc6e706d7c7fcbfff930c7281831fd5c4aff86ece57ed0db882f59a5fe403105d0592ca38a081fed84922873f538ee774f13b8cc09bd0521db4374aec69f4bae6dcb66455822c0b84c91a3474ffac2ad06f0a4423cd2c6a49d4f0d6242d6a1890937b5d9835a5f0ea5b1d01884d22a6c1718e1f60b3ab5e232947c76ef70b344171083c688093b5f1475377e3069863 +Output = 3109d9472ca436e805c6b3db2251a9bc + +Digest = SHAKE128 +Input = 49d81708d86cd59dea0ac2c1017a9712d6dffb754dde0b57a9023a39fc5f5b6be276fc176f59f6826610428fac3a0e85fcf71011db061b8fcf2bf085ccd45670effb6dc46f4e3f2ed08e981c5935187fc95b86cf46da675096b1cf9591a67842d6301116be93d8288e4d6b70f1b1db8aa5d203b774a21825665b8170351ee86801da91154570eaf80a1564945af7822df8232fd04ea65593a7f2ab1e9e84cf6ad6c494c9ec2d9d27aaad2b8f7e4f33f12a17b422bc2d4724c13ff8a8b62054d1bfb5c33b9c11183cd8df67694300165ca37637b5a781155f1c070d156339a0242374c6723b6584bffb71c02b935455f8cb086392f5e8e8cc2015956d8f19daeb6aca4476b27108387a2ce0dc5591154d0b94ddc090abe8f4363036b821062baffb7fe550ea7dcd30bfd86c84710081e1c9e450475e123c5ec41f98ff0149bbf6405b5207cad1fb2f313d0f2bcee9be3f6ebe623049640d9234ab644a172ab14ba02633a339b5b9bb38226fda5694f7ec63ebbb8238eb8219ec9c429f4bf0353383a72f2d21702f5e3c513499f04852710f33044512edc47a56bad90885e5713851a7efac694b869fa590076e844ff757d95de581c1b3fa3dd8ccd28cad4f8ae173ee1b28f98ee606dca89063fbef0f262b33053f2c854debdc9cd433ab77abb64f445aa9b981761c4761767f3b71c2646c7b0d873baae50bc9f0 +Output = c609be05458f7ab33e7b6b54bc6e8999 Digest = SHAKE256 Input = "" @@ -265,13 +265,13 @@ Output = 21a48efd949c3f785179a0e340756a23f77d29a7625229a71a05731c7fbd5aa9 # Following tests are pairs of *last* "VariableOut" vectors from # http://csrc.nist.gov/groups/STM/cavp/secure-hashing.html#test-vectors -#Digest = SHAKE128 -#Input = c60a221c975e14bf835827c1103a2906 -#Output = 0db7f7196eee8dd6994a16ded19cb09f05f89ccd2464333df2c017c6ca041fa0d54a4832a74ce86ce9b41d8e523e66ce6ef9df7c20aa70e0ac00f54eb072a472ef46cf2a933df0d5f9fafab6388a206f6bd1df50b0836500c758c557c8ac965733fdaaa59f5ed661a1bda61e2952886a60f9568157e3d72e49b6e061fc08f3f1caf159e8eff77ea5221565d2 -# -#Digest = SHAKE128 -#Input = 0a13ad2c7a239b4ba73ea6592ae84ea9 -#Output = 5feaf99c15f48851943ff9baa6e5055d8377f0dd347aa4dbece51ad3a6d9ce0c01aee9fe2260b80a4673a909b532adcdd1e421c32d6460535b5fe392a58d2634979a5a104d6c470aa3306c400b061db91c463b2848297bca2bc26d1864ba49d7ff949ebca50fbf79a5e63716dc82b600bd52ca7437ed774d169f6bf02e46487956fba2230f34cd2a0485484d +Digest = SHAKE128 +Input = c60a221c975e14bf835827c1103a2906 +Output = 0db7f7196eee8dd6994a16ded19cb09f05f89ccd2464333df2c017c6ca041fa0d54a4832a74ce86ce9b41d8e523e66ce6ef9df7c20aa70e0ac00f54eb072a472ef46cf2a933df0d5f9fafab6388a206f6bd1df50b0836500c758c557c8ac965733fdaaa59f5ed661a1bda61e2952886a60f9568157e3d72e49b6e061fc08f3f1caf159e8eff77ea5221565d2 + +Digest = SHAKE128 +Input = 0a13ad2c7a239b4ba73ea6592ae84ea9 +Output = 5feaf99c15f48851943ff9baa6e5055d8377f0dd347aa4dbece51ad3a6d9ce0c01aee9fe2260b80a4673a909b532adcdd1e421c32d6460535b5fe392a58d2634979a5a104d6c470aa3306c400b061db91c463b2848297bca2bc26d1864ba49d7ff949ebca50fbf79a5e63716dc82b600bd52ca7437ed774d169f6bf02e46487956fba2230f34cd2a0485484d Digest = SHAKE256 Input = 6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b diff --git a/test/test_digest.c b/test/test_digest.c index cc9e3930..5004ffa4 100644 --- a/test/test_digest.c +++ b/test/test_digest.c @@ -203,7 +203,7 @@ int test_sha3_512(void *data) /******************************************************************************/ -#ifdef WP_HAVE_SHAKE_256 +#if defined(WP_HAVE_SHAKE_128) || defined(WP_HAVE_SHAKE_256) static int test_xof_op(const EVP_MD *md, unsigned char *msg, size_t len, unsigned char *prev, unsigned int *prevLen) { @@ -251,6 +251,166 @@ static int test_xof_op(const EVP_MD *md, unsigned char *msg, size_t len, return err; } +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L) && \ + (LIBWOLFSSL_VERSION_HEX >= 0x05005001) +/* Squeeze in chunks across block boundaries, reinitializing and copying the + * context on the way. No final after squeeze and no squeeze after final. */ +static int test_xof_squeeze(EVP_MD *md, int wp, const unsigned char *in, + size_t inLen, unsigned char *out, size_t *len) +{ + static const size_t chunks[] = { 0, 1, 135, 32, 168, 104, 400, 3 }; + unsigned char tmp[200]; + EVP_MD_CTX *ctx; + EVP_MD_CTX *dup = NULL; + size_t i; + int r; + int err; + + err = (ctx = EVP_MD_CTX_new()) == NULL; + for (r = 0; (err == 0) && (r < 2); r++) { + *len = 0; + err = (EVP_DigestInit_ex(ctx, md, NULL) != 1) || + (EVP_DigestUpdate(ctx, in, inLen / 2) != 1) || + (EVP_DigestUpdate(ctx, in + inLen / 2, inLen - inLen / 2) != 1); + for (i = 0; (err == 0) && (i < sizeof(chunks) / sizeof(*chunks)); + i++) { + err = EVP_DigestSqueeze(ctx, out + *len, chunks[i]) != 1; + *len += chunks[i]; + } + } + /* wolfProvider refuses absorbing once output started. */ + if ((err == 0) && wp && (EVP_DigestUpdate(ctx, out, 1) == 1)) { + err = 1; + } + if (err == 0) { + err = ((dup = EVP_MD_CTX_dup(ctx)) == NULL) || + (EVP_DigestSqueeze(ctx, out + *len, sizeof(tmp)) != 1) || + (EVP_DigestSqueeze(dup, tmp, sizeof(tmp)) != 1) || + (memcmp(out + *len, tmp, sizeof(tmp)) != 0); + *len += sizeof(tmp); + } + if ((err == 0) && (EVP_DigestFinalXOF(ctx, tmp, 1) == 1)) { + err = 1; + } + if ((err == 0) && ((EVP_DigestInit_ex(dup, md, NULL) != 1) || + (EVP_DigestFinalXOF(dup, tmp, 1) != 1) || + (EVP_DigestSqueeze(dup, tmp, 1) == 1))) { + err = 1; + } + + EVP_MD_CTX_free(dup); + EVP_MD_CTX_free(ctx); + return err; +} +#endif + +/* Sizes, default length final and squeeze must match OpenSSL. */ +static int test_xof_parity(EVP_MD *omd, EVP_MD *wmd) +{ + static const unsigned char msg[] = "Test pattern"; + unsigned char out[2][1100]; + unsigned int len[2]; + int rc[2]; + EVP_MD *md[2]; + EVP_MD_CTX *ctx = NULL; + size_t i; + int err; + + md[0] = omd; + md[1] = wmd; + /* Parameters absent (RFC 8702), as OpenSSL 3.0.17+. */ + err = (EVP_MD_get_block_size(omd) != EVP_MD_get_block_size(wmd)) || + (EVP_MD_get_size(omd) != EVP_MD_get_size(wmd)) || + ((EVP_MD_get_flags(omd) & EVP_MD_FLAG_XOF) == 0) || + ((EVP_MD_get_flags(wmd) & EVP_MD_FLAG_XOF) == 0) || + ((EVP_MD_get_flags(wmd) & EVP_MD_FLAG_DIGALGID_ABSENT) == 0); + if (err) { + PRINT_ERR_MSG("XOF sizes or flags don't match"); + } + if (err == 0) { + err = (ctx = EVP_MD_CTX_new()) == NULL; + } + for (i = 0; (err == 0) && (i < 2); i++) { + len[i] = 0; + rc[i] = EVP_DigestInit_ex(ctx, md[i], NULL) && + EVP_DigestUpdate(ctx, msg, sizeof(msg)) && + EVP_DigestFinal_ex(ctx, out[i], &len[i]); + } + if ((err == 0) && ((rc[0] != rc[1]) || (len[0] != len[1]) || + (memcmp(out[0], out[1], len[0]) != 0))) { + PRINT_ERR_MSG("Default length XOF output doesn't match"); + err = 1; + } +#if OPENSSL_VERSION_NUMBER >= 0x30400000L + if (err == 0) { + size_t xofLen = 64; + size_t getLen; + OSSL_PARAM params[2]; + OSSL_PARAM getParams[2]; + + /* Size is an alias of XOF length; read back as XOF length. */ + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, + &xofLen); + params[1] = OSSL_PARAM_construct_end(); + getParams[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, + &getLen); + getParams[1] = OSSL_PARAM_construct_end(); + for (i = 0; (err == 0) && (i < 2); i++) { + len[i] = 0; + getLen = 0; + err = (EVP_DigestInit_ex2(ctx, md[i], params) != 1) || + (EVP_MD_CTX_get_params(ctx, getParams) != 1) || + (getLen != xofLen) || + (EVP_DigestUpdate(ctx, msg, sizeof(msg)) != 1) || + (EVP_DigestFinal_ex(ctx, out[i], &len[i]) != 1) || + (len[i] != xofLen); + } + if (err || (memcmp(out[0], out[1], xofLen) != 0)) { + PRINT_ERR_MSG("XOF length with final doesn't match"); + err = 1; + } + } +#endif + /* No absorbing or output after final until init (EVP or provider). */ + for (i = 0; (err == 0) && (i < 2); i++) { + err = (EVP_DigestInit_ex(ctx, wmd, NULL) != 1) || + (EVP_DigestUpdate(ctx, msg, sizeof(msg)) != 1) || + (EVP_DigestFinalXOF(ctx, out[i], 32) != 1) || + (EVP_DigestUpdate(ctx, msg, sizeof(msg)) == 1) || + (EVP_DigestFinalXOF(ctx, out[i], 32) == 1); + } + if ((err == 0) && (memcmp(out[0], out[1], 32) != 0)) { + err = 1; + } +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L) && \ + (LIBWOLFSSL_VERSION_HEX >= 0x05005001) + { + static const size_t inLens[] = { 0, 135, 136, 137, 168, 169, 400 }; + unsigned char in[400]; + size_t j; + size_t sLen[2] = { 0, 0 }; + + for (i = 0; i < sizeof(in); i++) { + in[i] = (unsigned char)i; + } + for (j = 0; (err == 0) && (j < sizeof(inLens) / sizeof(*inLens)); + j++) { + for (i = 0; (err == 0) && (i < 2); i++) { + err = test_xof_squeeze(md[i], i == 1, in, inLens[j], out[i], + &sLen[i]); + } + if ((err == 0) && (memcmp(out[0], out[1], sLen[0]) != 0)) { + PRINT_ERR_MSG("Squeezed XOF output doesn't match"); + err = 1; + } + } + } +#endif + EVP_MD_CTX_free(ctx); + + return err; +} + static int test_create_xof(const char *name, void *data) { int err = 0; @@ -284,6 +444,9 @@ static int test_create_xof(const char *name, void *data) PRINT_MSG("Digest With wolfprovider"); err = test_xof_op(wmd, longMsg, sizeof(longMsg), digest, &dLen); } + if (err == 0) { + err = test_xof_parity(omd, wmd); + } EVP_MD_free(wmd); EVP_MD_free(omd); @@ -292,6 +455,13 @@ static int test_create_xof(const char *name, void *data) } #endif +#ifdef WP_HAVE_SHAKE_128 +int test_shake_128(void *data) +{ + return test_create_xof("SHAKE128", data); +} +#endif + #ifdef WP_HAVE_SHAKE_256 int test_shake_256(void *data) { @@ -417,6 +587,9 @@ int test_digest_dupctx(void *data) #ifdef WP_HAVE_SHA3_512 { "SHA3-512", 0 }, #endif +#ifdef WP_HAVE_SHAKE_128 + { "SHAKE-128", 1 }, +#endif #ifdef WP_HAVE_SHAKE_256 { "SHAKE-256", 1 }, #endif diff --git a/test/unit.c b/test/unit.c index be7f72a2..794a3e46 100644 --- a/test/unit.c +++ b/test/unit.c @@ -215,6 +215,9 @@ TEST_CASE test_case[] = { #ifdef WP_HAVE_SHA3_512 TEST_DECL(test_sha3_512, NULL), #endif +#ifdef WP_HAVE_SHAKE_128 + TEST_DECL(test_shake_128, NULL), +#endif #ifdef WP_HAVE_SHAKE_256 TEST_DECL(test_shake_256, NULL), #endif diff --git a/test/unit.h b/test/unit.h index 35bc245b..c981e143 100644 --- a/test/unit.h +++ b/test/unit.h @@ -163,6 +163,9 @@ int test_sha3_224(void *data); int test_sha3_256(void *data); int test_sha3_384(void *data); int test_sha3_512(void *data); +#ifdef WP_HAVE_SHAKE_128 +int test_shake_128(void *data); +#endif #ifdef WP_HAVE_SHAKE_256 int test_shake_256(void *data); #endif