mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 19:10:50 +02:00
Merge pull request #10450 from Frauschi/slhdsa_pre_hash
HashSLH-DSA APIs take the pre-hashed digest, not the raw message
This commit is contained in:
@@ -12737,41 +12737,102 @@ void bench_slhdsa(int param)
|
||||
);
|
||||
bench_stats_asym_finish(name, len, "vrfy-msg", 0, count, start, ret);
|
||||
|
||||
/* Pre-hash interface: hash message, then sign the hash. */
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
sigLen = WC_SLHDSA_MAX_SIG_LEN;
|
||||
ret = wc_SlhDsaKey_SignHashDeterministic(key, ctx, 0, msg,
|
||||
(word32)sizeof(msg), WC_HASH_TYPE_SHA256, sig, &sigLen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
count++;
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
PRIVATE_KEY_LOCK();
|
||||
bench_stats_asym_finish(name, len, "sign-pre", 0, count, start, ret);
|
||||
#ifndef NO_SHA256
|
||||
/* Pre-hash interface: hash message ONCE outside the timed loop (the
|
||||
* bench measures sign/verify, not the application-side hash), then sign
|
||||
* and verify the digest. SHA-256 path: only built when SHA-256 is
|
||||
* available; HashSLH-DSA still works at runtime with any hashType the
|
||||
* build supports, but the bench needs a compile-time choice. */
|
||||
{
|
||||
byte digest[WC_SHA256_DIGEST_SIZE];
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, msg,
|
||||
(word32)sizeof(msg), WC_HASH_TYPE_SHA256, sig, sigLen);
|
||||
ret = wc_Sha256Hash(msg, (word32)sizeof(msg), digest);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
count++;
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
} while (bench_stats_check(start)
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
sigLen = WC_SLHDSA_MAX_SIG_LEN;
|
||||
ret = wc_SlhDsaKey_SignHashDeterministic(key, ctx, 0, digest,
|
||||
(word32)sizeof(digest), WC_HASH_TYPE_SHA256, sig, &sigLen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
count++;
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
bench_stats_asym_finish(name, len, "vrfy-pre", 0, count, start, ret);
|
||||
);
|
||||
PRIVATE_KEY_LOCK();
|
||||
bench_stats_asym_finish(name, len, "sign-pre", 0, count, start, ret);
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, digest,
|
||||
(word32)sizeof(digest), WC_HASH_TYPE_SHA256, sig, sigLen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
count++;
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
bench_stats_asym_finish(name, len, "vrfy-pre", 0, count, start, ret);
|
||||
}
|
||||
#elif defined(WOLFSSL_SHAKE256)
|
||||
/* SHAKE-only build (NO_SHA256): use SHAKE256 prehash bench instead. */
|
||||
{
|
||||
byte digest[WC_SHA3_512_DIGEST_SIZE];
|
||||
|
||||
ret = wc_Shake256Hash(msg, (word32)sizeof(msg), digest,
|
||||
WC_SHA3_512_DIGEST_SIZE);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
sigLen = WC_SLHDSA_MAX_SIG_LEN;
|
||||
ret = wc_SlhDsaKey_SignHashDeterministic(key, ctx, 0, digest,
|
||||
(word32)sizeof(digest), WC_HASH_TYPE_SHAKE256, sig, &sigLen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
count++;
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
PRIVATE_KEY_LOCK();
|
||||
bench_stats_asym_finish(name, len, "sign-pre", 0, count, start, ret);
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, digest,
|
||||
(word32)sizeof(digest), WC_HASH_TYPE_SHAKE256, sig, sigLen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
count++;
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
bench_stats_asym_finish(name, len, "vrfy-pre", 0, count, start, ret);
|
||||
}
|
||||
#endif /* NO_SHA256 / WOLFSSL_SHAKE256 */
|
||||
|
||||
exit:
|
||||
#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
|
||||
|
||||
+181
-108
@@ -7266,9 +7266,11 @@ int wc_SlhDsaKey_Sign(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sign using internal interface -- M' provided directly (deterministic).
|
||||
/* Sign using the FIPS 205 internal interface (Algorithm 19) -- M' provided
|
||||
* directly by the caller, deterministic variant (opt_rand = PK.seed).
|
||||
*
|
||||
* opt_rand = PK.seed for the deterministic variant.
|
||||
* Used for HashSLH-DSA implementations that build M' externally and for ACVP
|
||||
* signatureInterface=internal test vectors.
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] mprime M' message (already in internal format).
|
||||
@@ -7276,16 +7278,29 @@ int wc_SlhDsaKey_Sign(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
* @param [out] sig Buffer to hold signature.
|
||||
* @param [in, out] sigSz On in, buffer length. On out, signature length.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, mprime, sig or sigSz is
|
||||
* NULL.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length.
|
||||
* @return MISSING_KEY when private key not set.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
int wc_SlhDsaKey_SignMsgDeterministic(SlhDsaKey* key, const byte* mprime,
|
||||
word32 mprimeSz, byte* sig, word32* sigSz)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if ((key == NULL) || (key->params == NULL)) {
|
||||
if ((key == NULL) || (key->params == NULL) || (mprime == NULL) ||
|
||||
(sig == NULL) || (sigSz == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
else {
|
||||
else if (*sigSz < key->params->sigLen) {
|
||||
ret = BAD_LENGTH_E;
|
||||
}
|
||||
else if ((key->flags & WC_SLHDSA_FLAG_PRIVATE) == 0) {
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_sign_internal_msg(key, mprime, mprimeSz, sig, sigSz,
|
||||
key->sk + 2 * key->params->n);
|
||||
}
|
||||
@@ -7293,7 +7308,11 @@ int wc_SlhDsaKey_SignMsgDeterministic(SlhDsaKey* key, const byte* mprime,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sign using internal interface -- M' provided directly (with explicit random).
|
||||
/* Sign using the FIPS 205 internal interface (Algorithm 19) -- M' provided
|
||||
* directly by the caller, with explicit randomness.
|
||||
*
|
||||
* Used for HashSLH-DSA implementations that build M' externally and for ACVP
|
||||
* signatureInterface=internal test vectors.
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] mprime M' message (already in internal format).
|
||||
@@ -7302,12 +7321,34 @@ int wc_SlhDsaKey_SignMsgDeterministic(SlhDsaKey* key, const byte* mprime,
|
||||
* @param [in, out] sigSz On in, buffer length. On out, signature length.
|
||||
* @param [in] addRnd opt_rand value.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, mprime, sig, sigSz or
|
||||
* addRnd is NULL.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length.
|
||||
* @return MISSING_KEY when private key not set.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
int wc_SlhDsaKey_SignMsgWithRandom(SlhDsaKey* key, const byte* mprime,
|
||||
word32 mprimeSz, byte* sig, word32* sigSz, const byte* addRnd)
|
||||
{
|
||||
return slhdsakey_sign_internal_msg(key, mprime, mprimeSz, sig, sigSz,
|
||||
addRnd);
|
||||
int ret = 0;
|
||||
|
||||
if ((key == NULL) || (key->params == NULL) || (mprime == NULL) ||
|
||||
(sig == NULL) || (sigSz == NULL) || (addRnd == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
else if (*sigSz < key->params->sigLen) {
|
||||
ret = BAD_LENGTH_E;
|
||||
}
|
||||
else if ((key->flags & WC_SLHDSA_FLAG_PRIVATE) == 0) {
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_sign_internal_msg(key, mprime, mprimeSz, sig, sigSz,
|
||||
addRnd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */
|
||||
@@ -7538,6 +7579,16 @@ int wc_SlhDsaKey_VerifyMsg(SlhDsaKey* key, const byte* mprime,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* All HashSLH-DSA hash OIDs are DER-encoded as tag(0x06) + length(0x09) + 9
|
||||
* bytes, so any approved hash OID is exactly 11 bytes. The PRF_msg / H_msg
|
||||
* input for the SHA-2 path is the concatenation OID || PHM, bounded by
|
||||
* SLHDSA_OID_MAX_LEN + WC_MAX_DIGEST_SIZE. WC_MAX_DIGEST_SIZE is the project-
|
||||
* wide max digest size (>= 64 today) and absorbs any future hash with a
|
||||
* larger digest as long as slhdsakey_validate_prehash continues to enforce
|
||||
* hashSz <= WC_MAX_DIGEST_SIZE. */
|
||||
#define SLHDSA_OID_MAX_LEN 11
|
||||
#define SLHDSA_PHMSG_MAX_LEN (SLHDSA_OID_MAX_LEN + WC_MAX_DIGEST_SIZE)
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
/* OID for SHA-224 for hash signing/verification. */
|
||||
static const byte slhdsakey_oid_sha224[] = {
|
||||
@@ -7613,70 +7664,73 @@ static const byte slhdsakey_oid_sha3_512[] = {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Pre-hash the message with the hash specified.
|
||||
/* Validate the caller-supplied pre-hashed digest length and look up the
|
||||
* corresponding OID for the chosen hash algorithm.
|
||||
*
|
||||
* @param [in] msg Message to hash.
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @param [in] hashType Hash algorithm.
|
||||
* @param [out] ph Prehash buffer.
|
||||
* @param [out] phLen Length of prehash data.
|
||||
* The HashSLH-DSA family takes the digest as input rather than the full
|
||||
* message. This mirrors the wc_dilithium_*_ctx_hash interface and matches the
|
||||
* convention used by NIST ACVP signatureInterface=external / preHash test
|
||||
* vectors and other libraries (OpenSSL HASH-ML-DSA, leancrypto SLH-DSA,
|
||||
* mldsa-native pre_hash_internal). The expected digest length is fixed by
|
||||
* FIPS 205 Section 10.2.2 and equals wc_HashGetDigestSize(hashType) for the
|
||||
* fixed-output hashes; for SHAKE128/256 the standard fixes the XOF output to
|
||||
* 256/512 bits respectively. Callers feed the caller-supplied digest buffer
|
||||
* directly into the M' construction -- there is no copy.
|
||||
*
|
||||
* @param [in] hashSz Length of the caller-supplied digest in bytes.
|
||||
* @param [in] hashType Hash algorithm identifier (selects OID and length).
|
||||
* @param [out] oid OID data for hash algorithm.
|
||||
* @param [out] oidLen Length of OID data for hash algorithm.
|
||||
* @return 0 on success.
|
||||
* @return BAD_LENGTH_E when hashSz does not equal the expected digest size.
|
||||
* @return NOT_COMPILED_IN when hash algorithm not supported.
|
||||
*/
|
||||
static int slhdsakey_prehash_msg(const byte* msg, word32 msgSz,
|
||||
enum wc_HashType hashType, byte* ph, byte* phLen, const byte** oid,
|
||||
byte* oidLen)
|
||||
static int slhdsakey_validate_prehash(word32 hashSz,
|
||||
enum wc_HashType hashType, const byte** oid, byte* oidLen)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
word32 expectedLen = 0;
|
||||
|
||||
switch ((int)hashType) {
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case WC_HASH_TYPE_SHA224:
|
||||
*oid = slhdsakey_oid_sha224;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha224);
|
||||
*phLen = WC_SHA224_DIGEST_SIZE;
|
||||
ret = wc_Sha224Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA224_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
*oid = slhdsakey_oid_sha256;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha256);
|
||||
*phLen = WC_SHA256_DIGEST_SIZE;
|
||||
ret = wc_Sha256Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_HASH_TYPE_SHA384:
|
||||
*oid = slhdsakey_oid_sha384;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha384);
|
||||
*phLen = WC_SHA384_DIGEST_SIZE;
|
||||
ret = wc_Sha384Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_HASH_TYPE_SHA512:
|
||||
*oid = slhdsakey_oid_sha512;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha512);
|
||||
*phLen = WC_SHA512_DIGEST_SIZE;
|
||||
ret = wc_Sha512Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA512_DIGEST_SIZE;
|
||||
break;
|
||||
#ifndef WOLFSSL_NOSHA512_224
|
||||
case WC_HASH_TYPE_SHA512_224:
|
||||
*oid = slhdsakey_oid_sha512_224;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha512_224);
|
||||
*phLen = WC_SHA512_224_DIGEST_SIZE;
|
||||
ret = wc_Sha512_224Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA512_224_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA512_256
|
||||
case WC_HASH_TYPE_SHA512_256:
|
||||
*oid = slhdsakey_oid_sha512_256;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha512_256);
|
||||
*phLen = WC_SHA512_256_DIGEST_SIZE;
|
||||
ret = wc_Sha512_256Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA512_256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -7684,16 +7738,16 @@ static int slhdsakey_prehash_msg(const byte* msg, word32 msgSz,
|
||||
case WC_HASH_TYPE_SHAKE128:
|
||||
*oid = slhdsakey_oid_shake128;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_shake128);
|
||||
*phLen = WC_SHA3_256_DIGEST_SIZE;
|
||||
ret = wc_Shake128Hash(msg, msgSz, ph, WC_SHA3_256_DIGEST_SIZE);
|
||||
/* FIPS 205 Section 10.2.2 fixes SHAKE128 PHM length at 256 bits. */
|
||||
expectedLen = WC_SHA3_256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHAKE256
|
||||
case WC_HASH_TYPE_SHAKE256:
|
||||
*oid = slhdsakey_oid_shake256;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_shake256);
|
||||
*phLen = WC_SHA3_512_DIGEST_SIZE;
|
||||
ret = wc_Shake256Hash(msg, msgSz, ph, WC_SHA3_512_DIGEST_SIZE);
|
||||
/* FIPS 205 Section 10.2.2 fixes SHAKE256 PHM length at 512 bits. */
|
||||
expectedLen = WC_SHA3_512_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA3
|
||||
@@ -7701,32 +7755,28 @@ static int slhdsakey_prehash_msg(const byte* msg, word32 msgSz,
|
||||
case WC_HASH_TYPE_SHA3_224:
|
||||
*oid = slhdsakey_oid_sha3_224;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha3_224);
|
||||
*phLen = WC_SHA3_224_DIGEST_SIZE;
|
||||
ret = wc_Sha3_224Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA3_224_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA3_256
|
||||
case WC_HASH_TYPE_SHA3_256:
|
||||
*oid = slhdsakey_oid_sha3_256;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha3_256);
|
||||
*phLen = WC_SHA3_256_DIGEST_SIZE;
|
||||
ret = wc_Sha3_256Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA3_256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA3_384
|
||||
case WC_HASH_TYPE_SHA3_384:
|
||||
*oid = slhdsakey_oid_sha3_384;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha3_384);
|
||||
*phLen = WC_SHA3_384_DIGEST_SIZE;
|
||||
ret = wc_Sha3_384Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA3_384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA3_512
|
||||
case WC_HASH_TYPE_SHA3_512:
|
||||
*oid = slhdsakey_oid_sha3_512;
|
||||
*oidLen = (byte)sizeof(slhdsakey_oid_sha3_512);
|
||||
*phLen = WC_SHA3_512_DIGEST_SIZE;
|
||||
ret = wc_Sha3_512Hash(msg, msgSz, ph);
|
||||
expectedLen = WC_SHA3_512_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -7735,6 +7785,10 @@ static int slhdsakey_prehash_msg(const byte* msg, word32 msgSz,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ret == 0) && (hashSz != expectedLen)) {
|
||||
ret = BAD_LENGTH_E;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7790,37 +7844,40 @@ static int slhdsakey_prehash_msg(const byte* msg, word32 msgSz,
|
||||
*
|
||||
* Note: ctx length is of type byte which means it can never be more than 255.
|
||||
*
|
||||
* The caller MUST pre-hash the application message with hashType before
|
||||
* calling and pass the digest as hash. hashSz must equal the digest size of
|
||||
* hashType (32 for SHAKE128, 64 for SHAKE256 per FIPS 205 Section 10.2.2).
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] ctx Context of signing.
|
||||
* @param [in] ctxSz Length of context in bytes.
|
||||
* @param [in] msg Message to sign.
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @param [in] hashType Hash algorithm to use in pre-hash.
|
||||
* @param [in] hash Pre-hashed message digest to sign.
|
||||
* @param [in] hashSz Length of digest in bytes.
|
||||
* @param [in] hashType Hash algorithm used for pre-hash (selects OID).
|
||||
* @param [out] sig Buffer to hold signature.
|
||||
* @param [in, out] sigSz On in, length of signature buffer.
|
||||
* On out, length of signature data.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, msg, sig, sigSz or addRnd
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, hash, sig, sigSz or addRnd
|
||||
* is NULL.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL but ctx length is greater than 0.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length, or
|
||||
* when hashSz does not equal the digest size for hashType.
|
||||
* @return NOT_COMPILED in when hash algorithm is not supported.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
static int slhdsakey_signhash_external(SlhDsaKey* key, const byte* ctx,
|
||||
byte ctxSz, const byte* msg, word32 msgSz, enum wc_HashType hashType,
|
||||
byte ctxSz, const byte* hash, word32 hashSz, enum wc_HashType hashType,
|
||||
byte* sig, word32* sigSz, byte* addRnd)
|
||||
{
|
||||
int ret = 0;
|
||||
byte ph[WC_MAX_DIGEST_SIZE];
|
||||
byte phLen = 0;
|
||||
const byte* oid = NULL;
|
||||
byte oidLen = 0;
|
||||
|
||||
/* Validate parameters. */
|
||||
if ((key == NULL) || (key->params == NULL) ||
|
||||
((ctx == NULL) && (ctxSz > 0)) || (msg == NULL) || (sig == NULL) ||
|
||||
((ctx == NULL) && (ctxSz > 0)) || (hash == NULL) || (sig == NULL) ||
|
||||
(sigSz == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
@@ -7834,10 +7891,9 @@ static int slhdsakey_signhash_external(SlhDsaKey* key, const byte* ctx,
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Alg 23, Steps 8-23: Pre-hash message with hash algorithm specified.
|
||||
*/
|
||||
ret = slhdsakey_prehash_msg(msg, msgSz, hashType, ph, &phLen, &oid,
|
||||
&oidLen);
|
||||
/* Alg 23, Steps 8-23: Validate caller-supplied pre-hashed digest length
|
||||
* and select OID for the chosen hash algorithm. */
|
||||
ret = slhdsakey_validate_prehash(hashSz, hashType, &oid, &oidLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
byte n = key->params->n;
|
||||
@@ -7850,12 +7906,12 @@ static int slhdsakey_signhash_external(SlhDsaKey* key, const byte* ctx,
|
||||
|
||||
#ifdef WOLFSSL_SLHDSA_SHA2
|
||||
if (SLHDSA_IS_SHA2(key->params->param)) {
|
||||
/* SHA2: Build oid||ph as message for PRF_msg/H_msg. */
|
||||
byte phMsg[80]; /* Max: 11 byte OID + 64 byte hash */
|
||||
word32 phMsgLen = (word32)oidLen + phLen;
|
||||
/* SHA2: Build oid||hash as message for PRF_msg/H_msg. */
|
||||
byte phMsg[SLHDSA_PHMSG_MAX_LEN];
|
||||
word32 phMsgLen = (word32)oidLen + hashSz;
|
||||
|
||||
XMEMCPY(phMsg, oid, oidLen);
|
||||
XMEMCPY(phMsg + oidLen, ph, phLen);
|
||||
XMEMCPY(phMsg + oidLen, hash, hashSz);
|
||||
|
||||
ret = slhdsakey_prf_msg_sha2(key, key->sk + n, addRnd, hdr, ctx,
|
||||
ctxSz, phMsg, phMsgLen, n, sig);
|
||||
@@ -7885,7 +7941,7 @@ static int slhdsakey_signhash_external(SlhDsaKey* key, const byte* ctx,
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, oid, oidLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, ph, phLen);
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, hash, hashSz);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_hash_final(&key->hash.shk.shake, sig, n);
|
||||
@@ -7910,7 +7966,7 @@ static int slhdsakey_signhash_external(SlhDsaKey* key, const byte* ctx,
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, oid, oidLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, ph, phLen);
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, hash, hashSz);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_hash_final(&key->hash.shk.shake, md,
|
||||
@@ -7931,29 +7987,33 @@ static int slhdsakey_signhash_external(SlhDsaKey* key, const byte* ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Generate a deterministic pre-hash SLH-DSA signature.
|
||||
/* Generate a deterministic HashSLH-DSA signature.
|
||||
*
|
||||
* addrnd is the public key seed.
|
||||
* addrnd is the public key seed. The caller MUST pre-hash the application
|
||||
* message with hashType before calling and pass the digest as hash; hashSz
|
||||
* must equal the digest size of hashType (32 for SHAKE128, 64 for SHAKE256
|
||||
* per FIPS 205 Section 10.2.2).
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] ctx Context of signing.
|
||||
* @param [in] ctxSz Length of context in bytes.
|
||||
* @param [in] msg Message to sign.
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @param [in] hashType Hash algorithm to use in pre-hash.
|
||||
* @param [in] hash Pre-hashed message digest to sign.
|
||||
* @param [in] hashSz Length of digest in bytes.
|
||||
* @param [in] hashType Hash algorithm used for pre-hash (selects OID).
|
||||
* @param [out] sig Buffer to hold signature.
|
||||
* @param [in, out] sigSz On in, length of signature buffer.
|
||||
* On out, length of signature data.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, msg, sig or sigSz is NULL.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, hash, sig or sigSz is NULL.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL but ctx length is greater than 0.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length, or
|
||||
* when hashSz does not equal the digest size for hashType.
|
||||
* @return MISSING_KEY when private key not set.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
int wc_SlhDsaKey_SignHashDeterministic(SlhDsaKey* key, const byte* ctx,
|
||||
byte ctxSz, const byte* msg, word32 msgSz, enum wc_HashType hashType,
|
||||
byte ctxSz, const byte* hash, word32 hashSz, enum wc_HashType hashType,
|
||||
byte* sig, word32* sigSz)
|
||||
{
|
||||
int ret;
|
||||
@@ -7967,68 +8027,79 @@ int wc_SlhDsaKey_SignHashDeterministic(SlhDsaKey* key, const byte* ctx,
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
else {
|
||||
/* Pre-hash sign. */
|
||||
ret = slhdsakey_signhash_external(key, ctx, ctxSz, msg, msgSz, hashType,
|
||||
sig, sigSz, key->sk + 2 * key->params->n);
|
||||
/* HashSLH-DSA sign with caller-supplied digest. */
|
||||
ret = slhdsakey_signhash_external(key, ctx, ctxSz, hash, hashSz,
|
||||
hashType, sig, sigSz, key->sk + 2 * key->params->n);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Generate a pre-hash SLH-DSA signature.
|
||||
/* Generate a HashSLH-DSA signature with explicit randomness.
|
||||
*
|
||||
* The caller MUST pre-hash the application message with hashType before
|
||||
* calling and pass the digest as hash; hashSz must equal the digest size of
|
||||
* hashType (32 for SHAKE128, 64 for SHAKE256 per FIPS 205 Section 10.2.2).
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] ctx Context of signing.
|
||||
* @param [in] ctxSz Length of context in bytes.
|
||||
* @param [in] msg Message to sign.
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @param [in] hashType Hash algorithm to use in pre-hash.
|
||||
* @param [in] hash Pre-hashed message digest to sign.
|
||||
* @param [in] hashSz Length of digest in bytes.
|
||||
* @param [in] hashType Hash algorithm used for pre-hash (selects OID).
|
||||
* @param [out] sig Buffer to hold signature.
|
||||
* @param [in, out] sigSz On in, length of signature buffer.
|
||||
* On out, length of signature data.
|
||||
* @param [in] addRnd Additional random for signature.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, msg, sig, sigSz or addrnd
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, hash, sig, sigSz or addrnd
|
||||
* is NULL.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL but ctx length is greater than 0.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length.
|
||||
* @return BAD_LENGTH_E when sigSz is less than required signature length, or
|
||||
* when hashSz does not equal the digest size for hashType.
|
||||
* @return MISSING_KEY when private key not set.
|
||||
* @return NOT_COMPILED in when hash algorithm is not supported.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
int wc_SlhDsaKey_SignHashWithRandom(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
const byte* msg, word32 msgSz, enum wc_HashType hashType, byte* sig,
|
||||
const byte* hash, word32 hashSz, enum wc_HashType hashType, byte* sig,
|
||||
word32* sigSz, byte* addRnd)
|
||||
{
|
||||
/* Pre-hash sign */
|
||||
return slhdsakey_signhash_external(key, ctx, ctxSz, msg, msgSz, hashType,
|
||||
/* HashSLH-DSA sign with caller-supplied digest. */
|
||||
return slhdsakey_signhash_external(key, ctx, ctxSz, hash, hashSz, hashType,
|
||||
sig, sigSz, addRnd);
|
||||
}
|
||||
|
||||
/* Generate a pre-hash SLH-DSA signature with a random number generator.
|
||||
/* Generate a HashSLH-DSA signature using an RNG for added randomness.
|
||||
*
|
||||
* The caller MUST pre-hash the application message with hashType before
|
||||
* calling and pass the digest as hash; hashSz must equal the digest size of
|
||||
* hashType (32 for SHAKE128, 64 for SHAKE256 per FIPS 205 Section 10.2.2).
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] ctx Context of signing.
|
||||
* @param [in] ctxSz Length of context in bytes.
|
||||
* @param [in] msg Message to sign.
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @param [in] hashType Hash algorithm to use in pre-hash.
|
||||
* @param [in] hash Pre-hashed message digest to sign.
|
||||
* @param [in] hashSz Length of digest in bytes.
|
||||
* @param [in] hashType Hash algorithm used for pre-hash (selects OID).
|
||||
* @param [out] sig Buffer to hold signature.
|
||||
* @param [in, out] sigSz On in, length of signature buffer.
|
||||
* On out, length of signature data.
|
||||
* @param [in] rng Random number generator.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, msg, sig, sigSz or rng is
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, hash, sig, sigSz or rng is
|
||||
* NULL.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL but ctx length is greater than 0.
|
||||
* @return BAD_LENGTH_E when hashSz does not equal the digest size for
|
||||
* hashType.
|
||||
* @return MISSING_KEY when private key not set.
|
||||
* @return NOT_COMPILED in when hash algorithm is not supported.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
int wc_SlhDsaKey_SignHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
const byte* msg, word32 msgSz, enum wc_HashType hashType, byte* sig,
|
||||
const byte* hash, word32 hashSz, enum wc_HashType hashType, byte* sig,
|
||||
word32* sigSz, WC_RNG* rng)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -8036,7 +8107,7 @@ int wc_SlhDsaKey_SignHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
|
||||
/* Validate parameters before generating random. */
|
||||
if ((key == NULL) || (key->params == NULL) ||
|
||||
((ctx == NULL) && (ctxSz > 0)) || (msg == NULL) || (sig == NULL) ||
|
||||
((ctx == NULL) && (ctxSz > 0)) || (hash == NULL) || (sig == NULL) ||
|
||||
(sigSz == NULL) || (rng == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
@@ -8053,8 +8124,8 @@ int wc_SlhDsaKey_SignHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
ret = wc_RNG_GenerateBlock(rng, addRnd, key->params->n);
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Pre-hash sign. */
|
||||
ret = wc_SlhDsaKey_SignHashWithRandom(key, ctx, ctxSz, msg, msgSz,
|
||||
/* HashSLH-DSA sign with caller-supplied digest. */
|
||||
ret = wc_SlhDsaKey_SignHashWithRandom(key, ctx, ctxSz, hash, hashSz,
|
||||
hashType, sig, sigSz, addRnd);
|
||||
}
|
||||
|
||||
@@ -8106,36 +8177,39 @@ int wc_SlhDsaKey_SignHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
* 20: M' <- toByte(1, 1) || toByte(|ctx|, 1) || ctx || OID || PHM
|
||||
* 21: return slh_verify_internal(M', SIG, PK)
|
||||
*
|
||||
* The caller MUST pre-hash the application message with hashType before
|
||||
* calling and pass the digest as hash; hashSz must equal the digest size of
|
||||
* hashType (32 for SHAKE128, 64 for SHAKE256 per FIPS 205 Section 10.2.2).
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] ctx Context of signing.
|
||||
* @param [in] ctxSz Length of context in bytes.
|
||||
* @param [in] msg Message to sign.
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @param [in] hashType Hash algorithm to use in pre-hash.
|
||||
* @param [in] hash Pre-hashed message digest to verify against.
|
||||
* @param [in] hashSz Length of digest in bytes.
|
||||
* @param [in] hashType Hash algorithm used for pre-hash (selects OID).
|
||||
* @param [in] sig Signature data.
|
||||
* @param [in] sigSz Length of signature in bytes.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, msg or sig is NULL.
|
||||
* @return BAD_FUNC_ARG when key, key's parameters, hash or sig is NULL.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL but ctx length is greater than 0.
|
||||
* @return BAD_LENGTH_E when signature size does not match parameters.
|
||||
* @return BAD_LENGTH_E when signature size does not match parameters, or
|
||||
* when hashSz does not equal the digest size for hashType.
|
||||
* @return MISSING_KEY when public key not set.
|
||||
* @return NOT_COMPILED in when hash algorithm is not supported.
|
||||
* @return MEMORY_E on dynamic memory allocation failure.
|
||||
* @return SHAKE-256 error return code on digest failure.
|
||||
*/
|
||||
int wc_SlhDsaKey_VerifyHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
const byte* msg, word32 msgSz, enum wc_HashType hashType, const byte* sig,
|
||||
const byte* hash, word32 hashSz, enum wc_HashType hashType, const byte* sig,
|
||||
word32 sigSz)
|
||||
{
|
||||
int ret = 0;
|
||||
byte ph[WC_MAX_DIGEST_SIZE];
|
||||
byte phLen = 0;
|
||||
const byte* oid = NULL;
|
||||
byte oidLen = 0;
|
||||
|
||||
/* Validate parameters. */
|
||||
if ((key == NULL) || (key->params == NULL) ||
|
||||
((ctx == NULL) && (ctxSz > 0)) || (msg == NULL) || (sig == NULL)) {
|
||||
((ctx == NULL) && (ctxSz > 0)) || (hash == NULL) || (sig == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
/* Alg 20, Step 1: Check signature length is the expect length. */
|
||||
@@ -8148,10 +8222,9 @@ int wc_SlhDsaKey_VerifyHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Alg 24, Steps 4-19: Pre-hash message with hash algorithm specified.
|
||||
*/
|
||||
ret = slhdsakey_prehash_msg(msg, msgSz, hashType, ph, &phLen, &oid,
|
||||
&oidLen);
|
||||
/* Alg 24, Steps 4-19: Validate caller-supplied pre-hashed digest length
|
||||
* and select OID for the chosen hash algorithm. */
|
||||
ret = slhdsakey_validate_prehash(hashSz, hashType, &oid, &oidLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
byte n = key->params->n;
|
||||
@@ -8164,12 +8237,12 @@ int wc_SlhDsaKey_VerifyHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
|
||||
#ifdef WOLFSSL_SLHDSA_SHA2
|
||||
if (SLHDSA_IS_SHA2(key->params->param)) {
|
||||
/* SHA2: Build oid||ph as message for H_msg. */
|
||||
byte phMsg[80]; /* Max: 11 byte OID + 64 byte hash */
|
||||
word32 phMsgLen = (word32)oidLen + phLen;
|
||||
/* SHA2: Build oid||hash as message for H_msg. */
|
||||
byte phMsg[SLHDSA_PHMSG_MAX_LEN];
|
||||
word32 phMsgLen = (word32)oidLen + hashSz;
|
||||
|
||||
XMEMCPY(phMsg, oid, oidLen);
|
||||
XMEMCPY(phMsg + oidLen, ph, phLen);
|
||||
XMEMCPY(phMsg + oidLen, hash, hashSz);
|
||||
|
||||
ret = slhdsakey_h_msg_sha2(key, sig, hdr, ctx, ctxSz, phMsg,
|
||||
phMsgLen, md, (word32)key->params->dl1 + key->params->dl2 +
|
||||
@@ -8195,7 +8268,7 @@ int wc_SlhDsaKey_VerifyHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, oid, oidLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, ph, phLen);
|
||||
ret = slhdsakey_hash_update(&key->hash.shk.shake, hash, hashSz);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = slhdsakey_hash_final(&key->hash.shk.shake, md,
|
||||
|
||||
+41
-14
@@ -54542,6 +54542,7 @@ static wc_test_ret_t slhdsa_test_param(enum SlhDsaParam param)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
|
||||
/* HashSLH-DSA takes the caller's pre-hashed digest as input. */
|
||||
{
|
||||
#ifdef WOLFSSL_SLHDSA_SHA2
|
||||
enum wc_HashType phType = SLHDSA_IS_SHA2(param) ?
|
||||
@@ -54549,15 +54550,33 @@ static wc_test_ret_t slhdsa_test_param(enum SlhDsaParam param)
|
||||
#else
|
||||
enum wc_HashType phType = WC_HASH_TYPE_SHAKE256;
|
||||
#endif
|
||||
byte digest[WC_SHA3_512_DIGEST_SIZE];
|
||||
word32 digestLen;
|
||||
|
||||
#ifdef WOLFSSL_SLHDSA_SHA2
|
||||
if (phType == WC_HASH_TYPE_SHA256) {
|
||||
ret = wc_Sha256Hash(msg, (word32)sizeof(msg), digest);
|
||||
digestLen = WC_SHA256_DIGEST_SIZE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = wc_Shake256Hash(msg, (word32)sizeof(msg), digest,
|
||||
WC_SHA3_512_DIGEST_SIZE);
|
||||
digestLen = WC_SHA3_512_DIGEST_SIZE;
|
||||
}
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
sigLen = WC_SLHDSA_MAX_SIG_LEN;
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_SlhDsaKey_SignHash(key, ctx, 0, msg, (word32)sizeof(msg),
|
||||
ret = wc_SlhDsaKey_SignHash(key, ctx, 0, digest, digestLen,
|
||||
phType, sig, &sigLen, &rng);
|
||||
PRIVATE_KEY_LOCK();
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, msg, (word32)sizeof(msg),
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, digest, digestLen,
|
||||
phType, sig, sigLen);
|
||||
}
|
||||
if (ret != 0) {
|
||||
@@ -54566,18 +54585,26 @@ static wc_test_ret_t slhdsa_test_param(enum SlhDsaParam param)
|
||||
|
||||
/* Additional pre-hash test: SHA-384 exercises a different OID path */
|
||||
#ifdef WOLFSSL_SHA384
|
||||
sigLen = WC_SLHDSA_MAX_SIG_LEN;
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_SlhDsaKey_SignHash(key, ctx, 0, msg, (word32)sizeof(msg),
|
||||
WC_HASH_TYPE_SHA384, sig, &sigLen, &rng);
|
||||
PRIVATE_KEY_LOCK();
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, msg, (word32)sizeof(msg),
|
||||
WC_HASH_TYPE_SHA384, sig, sigLen);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
{
|
||||
byte digest384[WC_SHA384_DIGEST_SIZE];
|
||||
|
||||
ret = wc_Sha384Hash(msg, (word32)sizeof(msg), digest384);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
sigLen = WC_SLHDSA_MAX_SIG_LEN;
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_SlhDsaKey_SignHash(key, ctx, 0, digest384, sizeof(digest384),
|
||||
WC_HASH_TYPE_SHA384, sig, &sigLen, &rng);
|
||||
PRIVATE_KEY_LOCK();
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
ret = wc_SlhDsaKey_VerifyHash(key_vfy, ctx, 0, digest384,
|
||||
sizeof(digest384), WC_HASH_TYPE_SHA384, sig, sigLen);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user