mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 10:40:52 +02:00
Size cert signature buffers from the key and check sig type vs key
MAX_ENCODED_SIG_SZ grows to ~50KB once SLH-DSA is enabled, yet it was used to size PKCS#1/signature scratch and output buffers across the library, wasting stack and heap even for classic RSA/ECC operations. - Add MAX_ENCODED_CLASSIC_SIG_SZ for RSA/DSA/ECC DigestInfo buffers that can never hold a PQC signature. - Size the certificate/CSR signing output buffer from the signing key at runtime instead of the worst-case macro. - Add overridable WOLFSSL_MAX_SIG_SZ for the WOLFSSL_NO_MALLOC buffer. - Reject a signature type that does not match the signing key.
This commit is contained in:
+23
-11
@@ -33825,12 +33825,14 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
|
||||
}
|
||||
#endif
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
/* DigestInfo encoding for RSA, never a PQC
|
||||
* signature -- size to the classic tier. */
|
||||
WC_DECLARE_VAR(encodedSig, byte,
|
||||
MAX_ENCODED_SIG_SZ, 0);
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ, 0);
|
||||
word32 encSigSz;
|
||||
|
||||
WC_ALLOC_VAR_EX(encodedSig, byte,
|
||||
MAX_ENCODED_SIG_SZ, ssl->heap,
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ, ssl->heap,
|
||||
DYNAMIC_TYPE_SIGNATURE,
|
||||
ERROR_OUT(MEMORY_E,exit_dske));
|
||||
|
||||
@@ -33840,7 +33842,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
|
||||
TypeHash(ssl->options.peerHashAlgo));
|
||||
if (encSigSz != args->sigSz || !args->output ||
|
||||
XMEMCMP(args->output, encodedSig,
|
||||
min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) {
|
||||
min(encSigSz,
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ))
|
||||
!= 0) {
|
||||
ret = VERIFY_SIGN_ERROR;
|
||||
}
|
||||
WC_FREE_VAR_EX(encodedSig, ssl->heap,
|
||||
@@ -35141,9 +35145,14 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
args->verify = &args->output[RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ];
|
||||
args->extraSz = 0; /* tls 1.2 hash/sig */
|
||||
|
||||
/* build encoded signature buffer */
|
||||
ssl->buffers.sig.length = MAX_ENCODED_SIG_SZ;
|
||||
ssl->buffers.sig.buffer = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
|
||||
/* Build encoded signature buffer. This is TLS 1.2 and earlier
|
||||
* (TLS 1.3 uses SendTls13CertificateVerify), so the signature is
|
||||
* always classic (RSA/ECC/EdDSA), never PQC -- size to the classic
|
||||
* tier rather than the (potentially huge) PQC worst case. This
|
||||
* comfortably holds an ECC/EdDSA signature written directly, or the
|
||||
* PKCS#1 DigestInfo that is the input to RsaSign. */
|
||||
ssl->buffers.sig.length = MAX_ENCODED_CLASSIC_SIG_SZ;
|
||||
ssl->buffers.sig.buffer = (byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_SIGNATURE);
|
||||
if (ssl->buffers.sig.buffer == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_scv);
|
||||
@@ -36354,8 +36363,9 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
||||
static int ReEncodeSig(WOLFSSL* ssl)
|
||||
{ /* For TLS 1.2 re-encode signature */
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, ssl->heap,
|
||||
DYNAMIC_TYPE_DIGEST);
|
||||
/* DigestInfo encoding for RSA, never a PQC signature. */
|
||||
byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_DIGEST);
|
||||
if (encodedSig == NULL)
|
||||
return MEMORY_E;
|
||||
ssl->buffers.digest.length =
|
||||
@@ -39489,10 +39499,12 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* DigestInfo encoding for RSA */
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
byte encodedSig[MAX_ENCODED_SIG_SZ];
|
||||
byte encodedSig[MAX_ENCODED_CLASSIC_SIG_SZ];
|
||||
#else
|
||||
byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
|
||||
byte* encodedSig =
|
||||
(byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_SIGNATURE);
|
||||
if (encodedSig == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_dcv);
|
||||
@@ -39507,7 +39519,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
||||
|
||||
if (args->sendSz != args->sigSz || !args->output ||
|
||||
XMEMCMP(args->output, encodedSig,
|
||||
min(args->sigSz, MAX_ENCODED_SIG_SZ)) != 0) {
|
||||
min(args->sigSz, MAX_ENCODED_CLASSIC_SIG_SZ)) != 0) {
|
||||
ret = VERIFY_CERT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -3117,7 +3117,7 @@ int wolfSSL_RSA_sign_mgf(int hashAlg, const unsigned char* hash,
|
||||
#else
|
||||
WC_RNG _tmpRng[1];
|
||||
WC_RNG* tmpRng = _tmpRng;
|
||||
byte encodedSig[MAX_ENCODED_SIG_SZ];
|
||||
byte encodedSig[MAX_ENCODED_CLASSIC_SIG_SZ];
|
||||
#endif
|
||||
unsigned int encSz = 0;
|
||||
|
||||
@@ -3158,7 +3158,7 @@ int wolfSSL_RSA_sign_mgf(int hashAlg, const unsigned char* hash,
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (ret == 1) {
|
||||
/* Allocate encoded signature buffer if doing PKCS#1 padding. */
|
||||
encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
|
||||
encodedSig = (byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ, NULL,
|
||||
DYNAMIC_TYPE_SIGNATURE);
|
||||
if (encodedSig == NULL) {
|
||||
ret = 0;
|
||||
@@ -3314,10 +3314,10 @@ int wolfSSL_RSA_verify_mgf(int hashAlg, const unsigned char* hash,
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
unsigned char* encodedSig = NULL;
|
||||
#else
|
||||
unsigned char encodedSig[MAX_ENCODED_SIG_SZ];
|
||||
unsigned char encodedSig[MAX_ENCODED_CLASSIC_SIG_SZ];
|
||||
#endif
|
||||
unsigned char* sigDec = NULL;
|
||||
unsigned int len = MAX_ENCODED_SIG_SZ;
|
||||
unsigned int len = MAX_ENCODED_CLASSIC_SIG_SZ;
|
||||
int verLen = 0;
|
||||
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1)) && !defined(HAVE_SELFTEST)
|
||||
enum wc_HashType hType = WC_HASH_TYPE_NONE;
|
||||
|
||||
+19
@@ -23304,6 +23304,11 @@ static int test_wc_SignCert_cb(void)
|
||||
/* Invalid keyType for ECC signature */
|
||||
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
|
||||
FOURK_BUF, ED25519_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
|
||||
/* sigType/key family mismatch: an RSA signature OID against an ECC
|
||||
* key must be rejected with ALGO_ID_E before any signing happens. */
|
||||
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, CTC_SHA256wRSA, der,
|
||||
FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng),
|
||||
WC_NO_ERR_TRACE(ALGO_ID_E));
|
||||
#endif
|
||||
|
||||
ret = wc_ecc_free(&key);
|
||||
@@ -23390,6 +23395,11 @@ static int test_wc_SignCert_cb(void)
|
||||
/* Invalid keyType */
|
||||
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
|
||||
FOURK_BUF, ED448_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
|
||||
/* sigType/key family mismatch: an ECDSA signature OID against an RSA
|
||||
* key must be rejected with ALGO_ID_E before any signing happens. */
|
||||
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, CTC_SHA256wECDSA, der,
|
||||
FOURK_BUF, RSA_TYPE, mockSignCb, &signCtx, &rng),
|
||||
WC_NO_ERR_TRACE(ALGO_ID_E));
|
||||
#endif
|
||||
|
||||
ret = wc_FreeRsaKey(&key);
|
||||
@@ -24329,6 +24339,15 @@ static int test_wc_MakeCRL_max_crlnum(void)
|
||||
ExpectIntGT(crlSz, 0);
|
||||
}
|
||||
|
||||
/* --- Negative: a sigType whose family does not match the signing key
|
||||
* must be rejected before any signature is produced. The RSA key here
|
||||
* paired with an ECDSA OID must return ALGO_ID_E. --- */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
ExpectIntEQ(wc_SignCRL_ex(tbsBuf, tbsSz, CTC_SHA256wECDSA,
|
||||
crlBuf, (word32)bufSz, &rsaKey, NULL, &rng),
|
||||
WC_NO_ERR_TRACE(ALGO_ID_E));
|
||||
}
|
||||
|
||||
/* --- Decode the CRL and verify CRL number --- */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
ExpectNotNull(decodedCrl = d2i_X509_CRL(NULL, crlBuf, crlSz));
|
||||
|
||||
+368
-73
@@ -17030,7 +17030,9 @@ int ConfirmSignature(SignatureCtx* sigCtx,
|
||||
ERROR_OUT(MEMORY_E, exit_cs);
|
||||
}
|
||||
#endif
|
||||
if (sigSz > MAX_ENCODED_SIG_SZ) {
|
||||
/* RSA signature copied into sigCpy, which under
|
||||
* WOLFSSL_NO_MALLOC is sized to MAX_ENCODED_CLASSIC_SIG_SZ. */
|
||||
if (sigSz > MAX_ENCODED_CLASSIC_SIG_SZ) {
|
||||
WOLFSSL_MSG("Verify Signature is too big");
|
||||
ERROR_OUT(BUFFER_E, exit_cs);
|
||||
}
|
||||
@@ -17058,7 +17060,7 @@ int ConfirmSignature(SignatureCtx* sigCtx,
|
||||
WOLFSSL_MSG("Verify Signature is too small");
|
||||
ERROR_OUT(BUFFER_E, exit_cs);
|
||||
}
|
||||
else if (sigSz > MAX_ENCODED_SIG_SZ) {
|
||||
else if (sigSz > MAX_ENCODED_CLASSIC_SIG_SZ) {
|
||||
WOLFSSL_MSG("Verify Signature is too big");
|
||||
ERROR_OUT(BUFFER_E, exit_cs);
|
||||
}
|
||||
@@ -17747,13 +17749,15 @@ int ConfirmSignature(SignatureCtx* sigCtx,
|
||||
if (sigCtx->CertAtt.verifyByTSIP_SCE == 1) break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
|
||||
byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
|
||||
/* Holds a PKCS#1 DigestInfo encoding for RSA verification,
|
||||
* never a PQC signature -- size to the classic tier. */
|
||||
byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ,
|
||||
sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (encodedSig == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_cs);
|
||||
}
|
||||
#else
|
||||
byte encodedSig[MAX_ENCODED_SIG_SZ];
|
||||
byte encodedSig[MAX_ENCODED_CLASSIC_SIG_SZ];
|
||||
#endif
|
||||
|
||||
verifySz = ret;
|
||||
@@ -28380,6 +28384,270 @@ static int InternalSignCb(const byte* in, word32 inLen,
|
||||
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ */
|
||||
|
||||
|
||||
/* Return the buffer size needed to hold the raw signature that
|
||||
* MakeSignature() will produce for the provided key, or a negative error code
|
||||
* if it cannot be determined. The per-algorithm branches mirror the dispatch
|
||||
* in MakeSignature() so the two stay in agreement; exactly one key pointer is
|
||||
* expected to be non-NULL.
|
||||
*
|
||||
* Sizing the signature buffer from the key (rather than the worst-case
|
||||
* MAX_ENCODED_SIG_SZ) avoids allocating tens of KB for classic keys in builds
|
||||
* that merely enable a PQC algorithm, and is required for LMS/XMSS whose
|
||||
* parameter-dependent signatures can exceed MAX_ENCODED_SIG_SZ. */
|
||||
static int GetSignatureBufferSz(RsaKey* rsaKey, ecc_key* eccKey,
|
||||
ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
|
||||
wc_MlDsaKey* mldsaKey, SlhDsaKey* slhDsaKey, LmsKey* lmsKey,
|
||||
XmssKey* xmssKey)
|
||||
{
|
||||
int sigSz = ALGO_ID_E;
|
||||
|
||||
(void)rsaKey; (void)eccKey; (void)ed25519Key; (void)ed448Key;
|
||||
(void)falconKey; (void)mldsaKey; (void)slhDsaKey; (void)lmsKey;
|
||||
(void)xmssKey;
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (rsaKey != NULL)
|
||||
sigSz = wc_RsaEncryptSize(rsaKey);
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (eccKey != NULL)
|
||||
sigSz = wc_ecc_sig_size(eccKey);
|
||||
#endif
|
||||
#if defined(HAVE_ED25519)
|
||||
if (ed25519Key != NULL)
|
||||
sigSz = wc_ed25519_sig_size(ed25519Key);
|
||||
#endif
|
||||
#if defined(HAVE_ED448)
|
||||
if (ed448Key != NULL)
|
||||
sigSz = wc_ed448_sig_size(ed448Key);
|
||||
#endif
|
||||
#if defined(HAVE_FALCON)
|
||||
if (falconKey != NULL)
|
||||
sigSz = wc_falcon_sig_size(falconKey);
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_MLDSA)
|
||||
if (mldsaKey != NULL) {
|
||||
int len = 0;
|
||||
int rc = wc_MlDsaKey_GetSigLen(mldsaKey, &len);
|
||||
sigSz = (rc == 0) ? len : rc;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_SLHDSA)
|
||||
if (slhDsaKey != NULL)
|
||||
sigSz = wc_SlhDsaKey_SigSize(slhDsaKey);
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
if (lmsKey != NULL) {
|
||||
word32 len = 0;
|
||||
int rc = wc_LmsKey_GetSigLen(lmsKey, &len);
|
||||
sigSz = (rc == 0) ? (int)len : rc;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)
|
||||
if (xmssKey != NULL) {
|
||||
word32 len = 0;
|
||||
int rc = wc_XmssKey_GetSigLen(xmssKey, &len);
|
||||
sigSz = (rc == 0) ? (int)len : rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sigSz still ALGO_ID_E means no (compiled-in) key matched; a getter
|
||||
* returning 0 means the matched key was not usable. */
|
||||
if (sigSz == 0)
|
||||
sigSz = BAD_FUNC_ARG;
|
||||
return sigSz;
|
||||
}
|
||||
|
||||
#ifndef NO_RSA
|
||||
/* True if sType is an RSA signature-algorithm OID (any hash, incl. PSS). */
|
||||
static int IsRsaSigType(int sType)
|
||||
{
|
||||
switch (sType) {
|
||||
case CTC_MD2wRSA:
|
||||
case CTC_MD5wRSA:
|
||||
case CTC_SHAwRSA:
|
||||
case CTC_SHA224wRSA:
|
||||
case CTC_SHA256wRSA:
|
||||
case CTC_SHA384wRSA:
|
||||
case CTC_SHA512wRSA:
|
||||
case CTC_SHA3_224wRSA:
|
||||
case CTC_SHA3_256wRSA:
|
||||
case CTC_SHA3_384wRSA:
|
||||
case CTC_SHA3_512wRSA:
|
||||
case CTC_RSASSAPSS:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* !NO_RSA */
|
||||
#ifdef HAVE_ECC
|
||||
/* True if sType is an ECDSA (or SM2) signature-algorithm OID (any hash). */
|
||||
static int IsEccSigType(int sType)
|
||||
{
|
||||
switch (sType) {
|
||||
case CTC_SHAwECDSA:
|
||||
case CTC_SHA224wECDSA:
|
||||
case CTC_SHA256wECDSA:
|
||||
case CTC_SHA384wECDSA:
|
||||
case CTC_SHA512wECDSA:
|
||||
case CTC_SHA3_224wECDSA:
|
||||
case CTC_SHA3_256wECDSA:
|
||||
case CTC_SHA3_384wECDSA:
|
||||
case CTC_SHA3_512wECDSA:
|
||||
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
|
||||
case CTC_SM3wSM2:
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
/* Return the heap hint of whichever signing key is set, or NULL if none does
|
||||
* (falcon_key has no heap member). Centralizes the lookup shared by the
|
||||
* certificate/CSR signing entry points. */
|
||||
static void* GetSigningKeyHeap(RsaKey* rsaKey, ecc_key* eccKey,
|
||||
ed25519_key* ed25519Key, ed448_key* ed448Key, wc_MlDsaKey* mldsaKey,
|
||||
SlhDsaKey* slhDsaKey, LmsKey* lmsKey, XmssKey* xmssKey)
|
||||
{
|
||||
(void)rsaKey; (void)eccKey; (void)ed25519Key; (void)ed448Key;
|
||||
(void)mldsaKey; (void)slhDsaKey; (void)lmsKey; (void)xmssKey;
|
||||
#ifndef NO_RSA
|
||||
if (rsaKey != NULL)
|
||||
return rsaKey->heap;
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (eccKey != NULL)
|
||||
return eccKey->heap;
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
if (ed25519Key != NULL)
|
||||
return ed25519Key->heap;
|
||||
#endif
|
||||
#ifdef HAVE_ED448
|
||||
if (ed448Key != NULL)
|
||||
return ed448Key->heap;
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_MLDSA
|
||||
if (mldsaKey != NULL)
|
||||
return mldsaKey->heap;
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_SLHDSA
|
||||
if (slhDsaKey != NULL)
|
||||
return slhDsaKey->heap;
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
if (lmsKey != NULL)
|
||||
return lmsKey->heap;
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)
|
||||
if (xmssKey != NULL)
|
||||
return xmssKey->heap;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Verify that the requested signature type -- which becomes the certificate's
|
||||
* signatureAlgorithm OID -- is consistent with the signing key. The signature
|
||||
* is produced by dispatching on the key while the OID is written from sType,
|
||||
* so a mismatch would emit a certificate whose advertised algorithm
|
||||
* contradicts the key that signed it (e.g. leaving the wc_InitCert default of
|
||||
* CTC_SHA256wRSA on a non-RSA key). For RSA/ECC the hash is free to vary, so
|
||||
* the whole signature-algorithm family is accepted; the remaining algorithms
|
||||
* have a single (level/parameter-determined) OID. Returns 0 if consistent or
|
||||
* if there is no key to check, ALGO_ID_E on a mismatch. */
|
||||
static int CheckSigTypeForKey(int sType, RsaKey* rsaKey, ecc_key* eccKey,
|
||||
ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
|
||||
wc_MlDsaKey* mldsaKey, SlhDsaKey* slhDsaKey, LmsKey* lmsKey,
|
||||
XmssKey* xmssKey)
|
||||
{
|
||||
(void)sType;
|
||||
(void)rsaKey; (void)eccKey; (void)ed25519Key; (void)ed448Key;
|
||||
(void)falconKey; (void)mldsaKey; (void)slhDsaKey; (void)lmsKey;
|
||||
(void)xmssKey;
|
||||
|
||||
#ifdef WOLFSSL_DUAL_ALG_CERTS
|
||||
/* sigType 0 indicates preTBS encoding: no signatureAlgorithm to validate. */
|
||||
if (sType == 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (rsaKey != NULL)
|
||||
return IsRsaSigType(sType) ? 0 : ALGO_ID_E;
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (eccKey != NULL)
|
||||
return IsEccSigType(sType) ? 0 : ALGO_ID_E;
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
if (ed25519Key != NULL)
|
||||
return (sType == CTC_ED25519) ? 0 : ALGO_ID_E;
|
||||
#endif
|
||||
#ifdef HAVE_ED448
|
||||
if (ed448Key != NULL)
|
||||
return (sType == CTC_ED448) ? 0 : ALGO_ID_E;
|
||||
#endif
|
||||
#ifdef HAVE_FALCON
|
||||
if (falconKey != NULL) {
|
||||
if (falconKey->level == 1)
|
||||
return (sType == CTC_FALCON_LEVEL1) ? 0 : ALGO_ID_E;
|
||||
if (falconKey->level == 5)
|
||||
return (sType == CTC_FALCON_LEVEL5) ? 0 : ALGO_ID_E;
|
||||
return ALGO_ID_E;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_MLDSA
|
||||
if (mldsaKey != NULL) {
|
||||
if (mldsaKey->params == NULL)
|
||||
return ALGO_ID_E;
|
||||
#ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
|
||||
if (mldsaKey->params->level == WC_ML_DSA_44_DRAFT)
|
||||
return (sType == CTC_DILITHIUM_LEVEL2) ? 0 : ALGO_ID_E;
|
||||
if (mldsaKey->params->level == WC_ML_DSA_65_DRAFT)
|
||||
return (sType == CTC_DILITHIUM_LEVEL3) ? 0 : ALGO_ID_E;
|
||||
if (mldsaKey->params->level == WC_ML_DSA_87_DRAFT)
|
||||
return (sType == CTC_DILITHIUM_LEVEL5) ? 0 : ALGO_ID_E;
|
||||
#endif
|
||||
if (mldsaKey->level == WC_ML_DSA_44)
|
||||
return (sType == CTC_ML_DSA_44) ? 0 : ALGO_ID_E;
|
||||
if (mldsaKey->level == WC_ML_DSA_65)
|
||||
return (sType == CTC_ML_DSA_65) ? 0 : ALGO_ID_E;
|
||||
if (mldsaKey->level == WC_ML_DSA_87)
|
||||
return (sType == CTC_ML_DSA_87) ? 0 : ALGO_ID_E;
|
||||
return ALGO_ID_E;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_SLHDSA
|
||||
if (slhDsaKey != NULL) {
|
||||
/* SLH-DSA uses one OID per parameter set for both the key and the
|
||||
* signature, so the key OID sum equals the CTC signature value. */
|
||||
int oid;
|
||||
if (slhDsaKey->params == NULL)
|
||||
return ALGO_ID_E;
|
||||
oid = wc_SlhDsaParamToOid(slhDsaKey->params->param);
|
||||
if (oid < 0)
|
||||
return ALGO_ID_E;
|
||||
return (sType == oid) ? 0 : ALGO_ID_E;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
if (lmsKey != NULL)
|
||||
return (sType == CTC_HSS_LMS) ? 0 : ALGO_ID_E;
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)
|
||||
if (xmssKey != NULL) {
|
||||
if (xmssKey->is_xmssmt)
|
||||
return (sType == CTC_XMSSMT) ? 0 : ALGO_ID_E;
|
||||
return (sType == CTC_XMSS) ? 0 : ALGO_ID_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make signature from buffer (sz), write to sig (sigSz)
|
||||
* This function now uses MakeSignatureCb internally for RSA and ECC,
|
||||
* eliminating code duplication. Ed25519, Ed448, and post-quantum algorithms
|
||||
@@ -29658,29 +29926,25 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
|
||||
LmsKey* lmsKey, XmssKey* xmssKey, WC_RNG* rng)
|
||||
{
|
||||
int sigSz = 0;
|
||||
int ret;
|
||||
void* heap = NULL;
|
||||
/* The signature buffer must hold the largest signature any supported key
|
||||
* type can produce. LMS/XMSS signatures are parameter-dependent and can
|
||||
* exceed MAX_ENCODED_SIG_SZ, so size them from the key at runtime. */
|
||||
word32 maxSigSz = MAX_ENCODED_SIG_SZ;
|
||||
/* The signature buffer is sized from the key at runtime. */
|
||||
int maxSigSz;
|
||||
CertSignCtx certSignCtx_lcl;
|
||||
CertSignCtx* certSignCtx = &certSignCtx_lcl;
|
||||
|
||||
(void)lmsKey;
|
||||
(void)xmssKey;
|
||||
|
||||
XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
|
||||
|
||||
if (requestSz < 0)
|
||||
return requestSz;
|
||||
|
||||
/* locate ctx */
|
||||
/* Async crypto reuses the signing key's embedded CertSignCtx; only RSA and
|
||||
* ECC keys carry one. */
|
||||
if (rsaKey) {
|
||||
#ifndef NO_RSA
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
certSignCtx = &rsaKey->certSignCtx;
|
||||
#endif
|
||||
heap = rsaKey->heap;
|
||||
#else
|
||||
return NOT_COMPILED_IN;
|
||||
#endif /* NO_RSA */
|
||||
@@ -29690,67 +29954,49 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
certSignCtx = &eccKey->certSignCtx;
|
||||
#endif
|
||||
heap = eccKey->heap;
|
||||
#else
|
||||
return NOT_COMPILED_IN;
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
else if (lmsKey) {
|
||||
word32 lmsSigSz = 0;
|
||||
/* The signature algorithm OID is written from sType. Reject a
|
||||
* mismatch so we never emit a cert whose signatureAlgorithm
|
||||
* contradicts its HSS/LMS public key. */
|
||||
if (sType != CTC_HSS_LMS) {
|
||||
WOLFSSL_MSG("LMS key requires CTC_HSS_LMS signature type");
|
||||
return ALGO_ID_E;
|
||||
}
|
||||
heap = lmsKey->heap;
|
||||
if (wc_LmsKey_GetSigLen(lmsKey, &lmsSigSz) != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
if (lmsSigSz > maxSigSz)
|
||||
maxSigSz = lmsSigSz;
|
||||
heap = GetSigningKeyHeap(rsaKey, eccKey, ed25519Key, ed448Key, mldsaKey,
|
||||
slhDsaKey, lmsKey, xmssKey);
|
||||
|
||||
/* The signatureAlgorithm OID is written from sType while the signature is
|
||||
* produced from the key, so reject a mismatch rather than emit a cert
|
||||
* whose advertised algorithm contradicts the signing key. */
|
||||
ret = CheckSigTypeForKey(sType, rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
falconKey, mldsaKey, slhDsaKey, lmsKey, xmssKey);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Signature type does not match signing key");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)
|
||||
else if (xmssKey) {
|
||||
word32 xmssSigSz = 0;
|
||||
/* sType must match the tree variant (XMSS vs XMSS^MT) so the
|
||||
* signatureAlgorithm OID agrees with the XMSS public key OID that
|
||||
* MakeAnyCert derived from key->is_xmssmt. */
|
||||
if (xmssKey->is_xmssmt ? (sType != CTC_XMSSMT)
|
||||
: (sType != CTC_XMSS)) {
|
||||
WOLFSSL_MSG("XMSS signature type does not match key variant");
|
||||
return ALGO_ID_E;
|
||||
}
|
||||
heap = xmssKey->heap;
|
||||
if (wc_XmssKey_GetSigLen(xmssKey, &xmssSigSz) != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
if (xmssSigSz > maxSigSz)
|
||||
maxSigSz = xmssSigSz;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Size the signature buffer from the key in use. */
|
||||
maxSigSz = GetSignatureBufferSz(rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
falconKey, mldsaKey, slhDsaKey, lmsKey, xmssKey);
|
||||
if (maxSigSz <= 0)
|
||||
return (maxSigSz < 0) ? maxSigSz : ALGO_ID_E;
|
||||
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
if (certSignCtx->sig == NULL) {
|
||||
certSignCtx->sig = (byte*)XMALLOC(maxSigSz, heap,
|
||||
certSignCtx->sig = (byte*)XMALLOC((word32)maxSigSz, heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certSignCtx->sig == NULL)
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
/* Without dynamic memory the signature buffer is a fixed
|
||||
* MAX_ENCODED_SIG_SZ array in CertSignCtx. LMS/XMSS signatures are
|
||||
* WOLFSSL_MAX_SIG_SZ array in CertSignCtx. LMS/XMSS signatures are
|
||||
* parameter-dependent and can be larger, so reject rather than overflow
|
||||
* the fixed buffer. */
|
||||
if (maxSigSz > MAX_ENCODED_SIG_SZ) {
|
||||
WOLFSSL_MSG("LMS/XMSS signature larger than fixed CertSignCtx buffer");
|
||||
if ((word32)maxSigSz > WOLFSSL_MAX_SIG_SZ) {
|
||||
WOLFSSL_MSG("Signature larger than fixed CertSignCtx buffer");
|
||||
return BUFFER_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
sigSz = MakeSignature(certSignCtx, buf, (word32)requestSz, certSignCtx->sig,
|
||||
maxSigSz, rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
(word32)maxSigSz, rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
falconKey, mldsaKey, slhDsaKey, lmsKey, xmssKey, rng, (word32)sType,
|
||||
heap);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
@@ -29805,6 +30051,7 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf,
|
||||
SlhDsaKey* slhDsaKey = NULL;
|
||||
int ret = 0;
|
||||
int headerSz;
|
||||
int maxSigSz;
|
||||
void* heap = NULL;
|
||||
CertSignCtx certSignCtx_lcl;
|
||||
CertSignCtx* certSignCtx = &certSignCtx_lcl;
|
||||
@@ -29865,13 +30112,13 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf,
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* locate ctx */
|
||||
/* Async crypto reuses the signing key's embedded CertSignCtx; only RSA and
|
||||
* ECC keys carry one. */
|
||||
if (rsaKey) {
|
||||
#ifndef NO_RSA
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
certSignCtx = &rsaKey->certSignCtx;
|
||||
#endif
|
||||
heap = rsaKey->heap;
|
||||
#else
|
||||
return NOT_COMPILED_IN;
|
||||
#endif /* NO_RSA */
|
||||
@@ -29881,23 +30128,45 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf,
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
certSignCtx = &eccKey->certSignCtx;
|
||||
#endif
|
||||
heap = eccKey->heap;
|
||||
#else
|
||||
return NOT_COMPILED_IN;
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
heap = GetSigningKeyHeap(rsaKey, eccKey, ed25519Key, ed448Key, mldsaKey,
|
||||
slhDsaKey, NULL, NULL);
|
||||
|
||||
/* The signatureAlgorithm OID is written from sType while the signature is
|
||||
* produced from the key, so reject a mismatch rather than emit a cert
|
||||
* whose advertised algorithm contradicts the signing key. */
|
||||
ret = CheckSigTypeForKey(sType, rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
falconKey, mldsaKey, slhDsaKey, NULL, NULL);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Signature type does not match signing key");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Size the signature buffer from the key in use. */
|
||||
maxSigSz = GetSignatureBufferSz(rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
falconKey, mldsaKey, slhDsaKey, NULL, NULL);
|
||||
if (maxSigSz <= 0)
|
||||
return (maxSigSz < 0) ? maxSigSz : ALGO_ID_E;
|
||||
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
if (certSignCtx->sig == NULL) {
|
||||
certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
|
||||
certSignCtx->sig = (byte*)XMALLOC((word32)maxSigSz, heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certSignCtx->sig == NULL)
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
if ((word32)maxSigSz > WOLFSSL_MAX_SIG_SZ) {
|
||||
WOLFSSL_MSG("Signature larger than fixed CertSignCtx buffer");
|
||||
return BUFFER_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = MakeSignature(certSignCtx, buf, (word32)bufSz, certSignCtx->sig,
|
||||
MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
(word32)maxSigSz, rsaKey, eccKey, ed25519Key, ed448Key,
|
||||
falconKey, mldsaKey, slhDsaKey, NULL, NULL, rng, (word32)sType, heap);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
@@ -30050,6 +30319,7 @@ int wc_SignCert_cb(int requestSz, int sType, byte* buf, word32 buffSz,
|
||||
WC_RNG* rng)
|
||||
{
|
||||
int sigSz = 0;
|
||||
word32 sigCap = MAX_ENCODED_CLASSIC_SIG_SZ;
|
||||
CertSignCtx certSignCtx_lcl;
|
||||
CertSignCtx* certSignCtx = &certSignCtx_lcl;
|
||||
|
||||
@@ -30076,22 +30346,40 @@ int wc_SignCert_cb(int requestSz, int sType, byte* buf, word32 buffSz,
|
||||
return NOT_COMPILED_IN;
|
||||
#endif
|
||||
|
||||
/* The callback produces the signature for keyType while the cert's
|
||||
* signatureAlgorithm OID is written from sType, so reject a family
|
||||
* mismatch (e.g. an ECDSA OID with an RSA key). */
|
||||
#ifndef NO_RSA
|
||||
if (keyType == RSA_TYPE && !IsRsaSigType(sType))
|
||||
return ALGO_ID_E;
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (keyType == ECC_TYPE && !IsEccSigType(sType))
|
||||
return ALGO_ID_E;
|
||||
#endif
|
||||
|
||||
XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
|
||||
|
||||
if (requestSz < 0) {
|
||||
return requestSz;
|
||||
}
|
||||
|
||||
/* keyType is restricted to RSA_TYPE/ECC_TYPE above, so the signature is
|
||||
* a classic (non-PQC) one and fits MAX_ENCODED_CLASSIC_SIG_SZ. */
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
|
||||
certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certSignCtx->sig == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
/* Don't claim more capacity than the fixed sig buffer really has. */
|
||||
if (sigCap > (word32)sizeof(certSignCtx->sig))
|
||||
sigCap = (word32)sizeof(certSignCtx->sig);
|
||||
#endif
|
||||
|
||||
sigSz = MakeSignatureCb(certSignCtx, buf, (word32)requestSz,
|
||||
certSignCtx->sig, MAX_ENCODED_SIG_SZ, sType, keyType,
|
||||
certSignCtx->sig, sigCap, sType, keyType,
|
||||
signCb, signCtx, rng, NULL);
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
@@ -36611,6 +36899,7 @@ int wc_SignCRL_ex(const byte* tbsBuf, int tbsSz, int sType,
|
||||
{
|
||||
int ret;
|
||||
int sigSz;
|
||||
word32 sigCap = MAX_ENCODED_CLASSIC_SIG_SZ;
|
||||
CertSignCtx certSignCtx_lcl;
|
||||
CertSignCtx* certSignCtx = &certSignCtx_lcl;
|
||||
void* heap = NULL;
|
||||
@@ -36622,38 +36911,44 @@ int wc_SignCRL_ex(const byte* tbsBuf, int tbsSz, int sType,
|
||||
if (rsaKey != NULL && eccKey != NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* The CRL's signatureAlgorithm OID is written from sType while the
|
||||
* signature is produced from the key, so reject a mismatch. */
|
||||
ret = CheckSigTypeForKey(sType, rsaKey, eccKey, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Signature type does not match signing key");
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (rsaKey != NULL) {
|
||||
heap = rsaKey->heap;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (eccKey != NULL) {
|
||||
heap = eccKey->heap;
|
||||
}
|
||||
#endif
|
||||
heap = GetSigningKeyHeap(rsaKey, eccKey, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
/* Copy TBS to output buffer first */
|
||||
if ((word32)tbsSz > bufSz)
|
||||
return BUFFER_E;
|
||||
XMEMCPY(buf, tbsBuf, (size_t)tbsSz);
|
||||
|
||||
/* Only RSA/ECC keys are accepted above, so the signature is a classic
|
||||
* (non-PQC) one and fits MAX_ENCODED_CLASSIC_SIG_SZ. */
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
|
||||
certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_CLASSIC_SIG_SZ, heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certSignCtx->sig == NULL)
|
||||
return MEMORY_E;
|
||||
/* Initialize first byte to avoid static analysis warnings about using
|
||||
* uninitialized memory if MakeSignature fails before writing sig. */
|
||||
certSignCtx->sig[0] = 0;
|
||||
#else
|
||||
/* Don't claim more capacity than the fixed sig buffer really has. */
|
||||
if (sigCap > (word32)sizeof(certSignCtx->sig))
|
||||
sigCap = (word32)sizeof(certSignCtx->sig);
|
||||
#endif
|
||||
|
||||
/* Create signature */
|
||||
sigSz = MakeSignature(certSignCtx, buf, (word32)tbsSz, certSignCtx->sig,
|
||||
MAX_ENCODED_SIG_SZ, rsaKey, eccKey, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, rng, (word32)sType, heap);
|
||||
sigCap, rsaKey, eccKey, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, rng, (word32)sType, heap);
|
||||
if (sigSz < 0) {
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
@@ -46,8 +46,10 @@
|
||||
#ifndef MAX_DER_DIGEST_ASN_SZ
|
||||
#define MAX_DER_DIGEST_ASN_SZ 36
|
||||
#endif
|
||||
#ifndef MAX_ENCODED_SIG_SZ
|
||||
#define MAX_ENCODED_SIG_SZ 1024 /* Supports 8192 bit keys */
|
||||
/* Fallback when asn.h (which defines MAX_ENCODED_CLASSIC_SIG_SZ) is not
|
||||
* available. Sized to hold an RSA-modulus signature. */
|
||||
#ifndef MAX_ENCODED_CLASSIC_SIG_SZ
|
||||
#define MAX_ENCODED_CLASSIC_SIG_SZ 1024 /* Supports 8192 bit keys */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -289,7 +291,7 @@ int wc_SignatureVerifyHash(
|
||||
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
|
||||
byte *plain_data;
|
||||
#else
|
||||
ALIGN64 byte plain_data[MAX_ENCODED_SIG_SZ];
|
||||
ALIGN64 byte plain_data[MAX_ENCODED_CLASSIC_SIG_SZ];
|
||||
#endif
|
||||
|
||||
/* Make sure the plain text output is at least key size */
|
||||
|
||||
@@ -1541,7 +1541,9 @@ struct SignatureCtx {
|
||||
#endif
|
||||
#if !defined(NO_RSA) || !defined(NO_DSA)
|
||||
#ifdef WOLFSSL_NO_MALLOC
|
||||
byte sigCpy[MAX_ENCODED_SIG_SZ];
|
||||
/* Holds a copy of the RSA/DSA signature being verified, which is at most
|
||||
* an RSA-modulus-sized value -- never a (much larger) PQC signature. */
|
||||
byte sigCpy[MAX_ENCODED_CLASSIC_SIG_SZ];
|
||||
#else
|
||||
byte* sigCpy;
|
||||
#endif
|
||||
|
||||
+37
-17
@@ -2375,29 +2375,39 @@ enum Max_ASN {
|
||||
DSA_INTS = 5, /* DSA ints in private key */
|
||||
MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */
|
||||
MAX_IV_SIZE = 64, /* MAX PKCS Iv length */
|
||||
/* Max classic sig (RSA/DSA/ECC); separate from MAX_ENCODED_SIG_SZ so
|
||||
* PKCS#1/verify buffers stay small when PQC is enabled for verify-only. */
|
||||
#if !defined(NO_RSA)
|
||||
#if defined(USE_FAST_MATH) && defined(FP_MAX_BITS)
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = FP_MAX_BITS / 16,
|
||||
#elif (defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)) && \
|
||||
defined(SP_INT_BITS)
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = WC_BITS_TO_BYTES(SP_INT_BITS),
|
||||
#elif defined(WOLFSSL_HAPROXY)
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = 1024, /* Supports 8192 bit keys */
|
||||
#else
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = 512, /* Supports 4096 bit keys */
|
||||
#endif
|
||||
#elif defined(HAVE_ECC)
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = 140,
|
||||
#elif defined(HAVE_ED448)
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = 114, /* Ed448 signature is 114 bytes */
|
||||
#else
|
||||
MAX_ENCODED_CLASSIC_SIG_SZ = 64, /* Ed25519 signature is 64 bytes */
|
||||
#endif
|
||||
|
||||
/* Largest signature any enabled algorithm can produce. Used to size the
|
||||
* actual signature-output buffers. PQC signatures are large, so prefer
|
||||
* runtime sizing (see GetSignatureBufferSz in asn.c) where the key is
|
||||
* available. */
|
||||
#ifdef WOLFSSL_HAVE_SLHDSA
|
||||
/* Largest raw SLH-DSA signature (SHAKE-256f) is 49856 bytes; round up
|
||||
* to leave headroom for ASN.1 wrapping (BIT STRING tag + length). */
|
||||
MAX_ENCODED_SIG_SZ = 51200,
|
||||
#elif defined(HAVE_FALCON) || defined(WOLFSSL_HAVE_MLDSA)
|
||||
MAX_ENCODED_SIG_SZ = 5120,
|
||||
#elif !defined(NO_RSA)
|
||||
#if defined(USE_FAST_MATH) && defined(FP_MAX_BITS)
|
||||
MAX_ENCODED_SIG_SZ = FP_MAX_BITS / 16,
|
||||
#elif (defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)) && \
|
||||
defined(SP_INT_BITS)
|
||||
MAX_ENCODED_SIG_SZ = WC_BITS_TO_BYTES(SP_INT_BITS),
|
||||
#elif defined(WOLFSSL_HAPROXY)
|
||||
MAX_ENCODED_SIG_SZ = 1024, /* Supports 8192 bit keys */
|
||||
#else
|
||||
MAX_ENCODED_SIG_SZ = 512, /* Supports 4096 bit keys */
|
||||
#endif
|
||||
#elif defined(HAVE_ECC)
|
||||
MAX_ENCODED_SIG_SZ = 140,
|
||||
#elif defined(HAVE_CURVE448)
|
||||
MAX_ENCODED_SIG_SZ = 114,
|
||||
#else
|
||||
MAX_ENCODED_SIG_SZ = 64,
|
||||
MAX_ENCODED_SIG_SZ = MAX_ENCODED_CLASSIC_SIG_SZ,
|
||||
#endif
|
||||
MAX_ALGO_SZ = 20,
|
||||
MAX_LENGTH_SZ = WOLFSSL_ASN_MAX_LENGTH_SZ, /* Max length size for DER encoding */
|
||||
@@ -2457,6 +2467,16 @@ enum Max_ASN {
|
||||
|
||||
#define MAX_SIG_SZ MAX_ENCODED_SIG_SZ
|
||||
|
||||
/* Size of the fixed signature buffer embedded in CertSignCtx under
|
||||
* WOLFSSL_NO_MALLOC, and the reject threshold used by the cert/CSR signing
|
||||
* paths when dynamic memory is unavailable. Defaults to the largest signature
|
||||
* any enabled algorithm can produce. Override (e.g. via user_settings.h) to
|
||||
* fit a specific LMS/XMSS parameter set, or to shrink builds that only sign
|
||||
* with classic/compact algorithms. */
|
||||
#ifndef WOLFSSL_MAX_SIG_SZ
|
||||
#define WOLFSSL_MAX_SIG_SZ MAX_ENCODED_SIG_SZ
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_CERT_GEN) || defined(HAVE_OCSP_RESPONDER)
|
||||
/* Used in asn.c MakeSignature for ECC and RSA non-blocking/async */
|
||||
enum CertSignState {
|
||||
@@ -2468,7 +2488,7 @@ enum Max_ASN {
|
||||
|
||||
typedef struct CertSignCtx {
|
||||
#ifdef WOLFSSL_NO_MALLOC
|
||||
byte sig[MAX_ENCODED_SIG_SZ];
|
||||
byte sig[WOLFSSL_MAX_SIG_SZ];
|
||||
byte digest[WC_MAX_DIGEST_SIZE];
|
||||
#ifndef NO_RSA
|
||||
byte encSig[MAX_DER_DIGEST_SZ];
|
||||
|
||||
Reference in New Issue
Block a user