Jelajahi Sumber

fixes for issues introduced in #5384:

added numerous missing _SMALL_STACK code paths (PK objects on the stack);

in settings.h, enable WOLFSSL_SMALL_STACK_STATIC by default when WOLFSSL_SMALL_STACK is defined (NO_WOLFSSL_SMALL_STACK_STATIC to override);

fixes for unsafe strcat()s in tests/quic.c;

fix for unsafe macro WOLFSSL_IS_QUIC();

fix to exclude quic from enable-all when enable-linuxkm (quic needs opensslextra, and opensslextra currently only works in-kernel in cryptonly builds);

fix for signed/unsigned clash in wolfSSL_quic_receive().
Daniel Pouzzner 1 tahun lalu
induk
melakukan
f771181e1a
13 mengubah file dengan 537 tambahan dan 226 penghapusan
  1. 1 1
      configure.ac
  2. 34 19
      src/internal.c
  3. 79 44
      src/ocsp.c
  4. 44 15
      src/pk.c
  5. 23 7
      src/quic.c
  6. 92 34
      src/ssl.c
  7. 115 50
      src/x509.c
  8. 8 8
      tests/quic.c
  9. 23 10
      wolfcrypt/src/ecc.c
  10. 66 4
      wolfcrypt/src/sakke.c
  11. 46 33
      wolfcrypt/test/test.c
  12. 1 1
      wolfssl/internal.h
  13. 5 0
      wolfssl/wolfcrypt/settings.h

+ 1 - 1
configure.ac

@@ -664,7 +664,6 @@ then
         test "$enable_tls13" = "" && enable_tls13=yes
         test "$enable_rsapss" = "" && enable_rsapss=yes
     fi
-    test "$enable_quic" = "" && enable_quic=yes
 
     # this set is also enabled by enable-all-crypto:
     test "$enable_atomicuser" = "" && enable_atomicuser=yes
@@ -744,6 +743,7 @@ then
     if test "$ENABLED_LINUXKM_DEFAULTS" != "yes"
     then
         test "$enable_compkey" = "" && enable_compkey=yes
+        test "$enable_quic" = "" && enable_quic=yes
         AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL_IO -DHAVE_IO_TIMEOUT"
     fi
 

+ 34 - 19
src/internal.c

@@ -25903,33 +25903,48 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
 
         #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
             {
+                WOLFSSL_X509_NAME* name = NULL;
                 /* Use a DecodedCert struct to get access to GetName to
                  * parse DN name */
-                DecodedCert cert;
-                WOLFSSL_X509_NAME* name;
+#ifdef WOLFSSL_SMALL_STACK
+                DecodedCert *cert = (DecodedCert *)XMALLOC(
+                    sizeof(*cert), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                if (cert == NULL)
+                    return MEMORY_ERROR;
+#else
+                DecodedCert cert[1];
+#endif
 
-                InitDecodedCert(&cert, input + *inOutIdx, dnSz, ssl->heap);
+                InitDecodedCert(cert, input + *inOutIdx, dnSz, ssl->heap);
 
-                if ((ret = GetName(&cert, SUBJECT, dnSz)) != 0) {
-                    FreeDecodedCert(&cert);
-                    return ret;
-                }
+                do {
+                    if ((ret = GetName(cert, SUBJECT, dnSz)) != 0) {
+                        break;
+                    }
 
-                if ((name = wolfSSL_X509_NAME_new()) == NULL) {
-                    FreeDecodedCert(&cert);
-                    return MEMORY_ERROR;
-                }
+                    if ((name = wolfSSL_X509_NAME_new()) == NULL) {
+                        ret = MEMORY_ERROR;
+                        break;
+                    }
 
-                CopyDecodedName(name, &cert, SUBJECT);
+                    CopyDecodedName(name, cert, SUBJECT);
 
-                if (wolfSSL_sk_X509_NAME_push(ssl->ca_names, name)
-                        == WOLFSSL_FAILURE) {
-                    FreeDecodedCert(&cert);
-                    wolfSSL_X509_NAME_free(name);
-                    return MEMORY_ERROR;
+                    if (wolfSSL_sk_X509_NAME_push(ssl->ca_names, name)
+                        == WOLFSSL_FAILURE)
+                    {
+                        ret = MEMORY_ERROR;
+                        break;
+                    }
+                } while (0);
+                FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(cert, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                if (ret != 0) {
+                    if (name != NULL)
+                        wolfSSL_X509_NAME_free(name);
+                    return ret;
                 }
-
-                FreeDecodedCert(&cert);
             }
         #endif
 

+ 79 - 44
src/ocsp.c

@@ -593,12 +593,19 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
     const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
     const WOLFSSL_X509 *issuer)
 {
-    WOLFSSL_OCSP_CERTID* certId;
-    CertStatus* certStatus;
-    DecodedCert cert;
-    WOLFSSL_CERT_MANAGER* cm;
-    int ret;
+    WOLFSSL_OCSP_CERTID* certId = NULL;
+    CertStatus* certStatus = NULL;
+    WOLFSSL_CERT_MANAGER* cm = NULL;
+    int ret = -1;
     DerBuffer* derCert = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL,
+                                               DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL)
+        return NULL;
+#else
+    DecodedCert cert[1];
+#endif
 
     (void)dgst;
 
@@ -606,7 +613,7 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
     if (cm == NULL
             || subject == NULL || subject->derCert == NULL
             || issuer  == NULL || issuer->derCert  == NULL)
-        return NULL;
+        goto out;
 
     ret = AllocDer(&derCert, issuer->derCert->length,
         issuer->derCert->type, NULL);
@@ -616,50 +623,60 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
                 issuer->derCert->length);
         ret = AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
         if (ret != WOLFSSL_SUCCESS) {
-            wolfSSL_CertManagerFree(cm);
-            return NULL;
+            goto out;
         }
     }
 
+    ret = -1;
+
     certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
                                            DYNAMIC_TYPE_OPENSSL);
+    if (certId == NULL)
+        goto out;
+
     certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
                                            DYNAMIC_TYPE_OPENSSL);
+    if (certStatus == NULL)
+        goto out;
 
-    if (certId == NULL || certStatus == NULL) {
-        if (certId)
-            XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
-        if (certStatus)
-            XFREE(certStatus, NULL, DYNAMIC_TYPE_OPENSSL);
+    XMEMSET(certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
+    XMEMSET(certStatus, 0, sizeof(CertStatus));
+
+    certId->status = certStatus;
+    certId->ownStatus = 1;
 
-        certId = NULL;
+    InitDecodedCert(cert, subject->derCert->buffer,
+                    subject->derCert->length, NULL);
+    if (ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
+        goto out;
+    }
+    else {
+        XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE);
+        XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE);
+        XMEMCPY(certId->status->serial, cert->serial, cert->serialSz);
+        certId->status->serialSz = cert->serialSz;
+        FreeDecodedCert(cert);
     }
 
-    if (certId != NULL) {
-        XMEMSET(certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
-        XMEMSET(certStatus, 0, sizeof(CertStatus));
+    ret = 0;
 
-        certId->status = certStatus;
-        certId->ownStatus = 1;
+out:
 
-        InitDecodedCert(&cert, subject->derCert->buffer,
-                        subject->derCert->length, NULL);
-        if (ParseCertRelative(&cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
-            XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
-            certId = NULL;
-        }
-        else {
-            XMEMCPY(certId->issuerHash, cert.issuerHash, OCSP_DIGEST_SIZE);
-            XMEMCPY(certId->issuerKeyHash, cert.issuerKeyHash, OCSP_DIGEST_SIZE);
-            XMEMCPY(certId->status->serial, cert.serial, cert.serialSz);
-            certId->status->serialSz = cert.serialSz;
-        }
-        FreeDecodedCert(&cert);
-    }
+    if (cm != NULL)
+        wolfSSL_CertManagerFree(cm);
 
-    wolfSSL_CertManagerFree(cm);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
-    return certId;
+    if (ret != 0) {
+        if (certId != NULL)
+            XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
+        if (certStatus)
+            XFREE(certStatus, NULL, DYNAMIC_TYPE_OPENSSL);
+        return NULL;
+    } else
+        return certId;
 }
 
 void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
@@ -672,23 +689,41 @@ void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
 int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
     WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
 {
-    DecodedCert cert;
-    int         ret = WOLFSSL_SUCCESS;
+    int         ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL,
+                                               DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL)
+        return WOLFSSL_FAILURE;
+#else
+    DecodedCert cert[1];
+#endif
 
     (void)certs;
 
-    if (flags & OCSP_NOVERIFY)
-        return WOLFSSL_SUCCESS;
+    if (flags & OCSP_NOVERIFY) {
+        ret = WOLFSSL_SUCCESS;
+        goto out;
+    }
 
 #ifdef OPENSSL_EXTRA
-    if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
-        return WOLFSSL_FAILURE;
+    if (bs->verifyError != OCSP_VERIFY_ERROR_NONE) {
+        ret = WOLFSSL_FAILURE;
+        goto out;
+    }
 #endif
 
-    InitDecodedCert(&cert, bs->cert, bs->certSz, NULL);
-    if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0)
+    ret = WOLFSSL_SUCCESS;
+    InitDecodedCert(cert, bs->cert, bs->certSz, NULL);
+    if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm) < 0)
         ret = WOLFSSL_FAILURE;
-    FreeDecodedCert(&cert);
+    FreeDecodedCert(cert);
+
+out:
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
     return ret;
 }

+ 44 - 15
src/pk.c

@@ -4106,8 +4106,17 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
 {
     int     ret = 1;
     int     err;
-    mp_int  tmp;
     mp_int* t = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int  *tmp = (mp_int *)XMALLOC(sizeof(*tmp), rsa->heap,
+                                     DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("out of memory");
+        return -1;
+    }
+#else
+    mp_int  tmp[1];
+#endif
 
     WOLFSSL_ENTER("wolfSSL_RsaGenAdd");
 
@@ -4120,17 +4129,17 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
 
     if (ret == 1) {
         /* Initialize temp MP integer. */
-        if (mp_init(&tmp) != MP_OKAY) {
+        if (mp_init(tmp) != MP_OKAY) {
             WOLFSSL_MSG("mp_init error");
             ret = -1;
         }
     }
 
     if (ret == 1) {
-        t = &tmp;
+        t = tmp;
 
         /* Sub 1 from p into temp. */
-        err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
+        err = mp_sub_d((mp_int*)rsa->p->internal, 1, tmp);
         if (err != MP_OKAY) {
             WOLFSSL_MSG("mp_sub_d error");
             ret = -1;
@@ -4138,7 +4147,7 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
     }
     if (ret == 1) {
         /* Calculate d mod (p - 1) into dmp1 MP integer of BN. */
-        err = mp_mod((mp_int*)rsa->d->internal, &tmp,
+        err = mp_mod((mp_int*)rsa->d->internal, tmp,
             (mp_int*)rsa->dmp1->internal);
         if (err != MP_OKAY) {
             WOLFSSL_MSG("mp_mod error");
@@ -4147,7 +4156,7 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
     }
     if (ret == 1) {
         /* Sub 1 from q into temp. */
-        err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
+        err = mp_sub_d((mp_int*)rsa->q->internal, 1, tmp);
         if (err != MP_OKAY) {
             WOLFSSL_MSG("mp_sub_d error");
             ret = -1;
@@ -4155,7 +4164,7 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
     }
     if (ret == 1) {
         /* Calculate d mod (q - 1) into dmq1 MP integer of BN. */
-        err = mp_mod((mp_int*)rsa->d->internal, &tmp,
+        err = mp_mod((mp_int*)rsa->d->internal, tmp,
             (mp_int*)rsa->dmq1->internal);
         if (err != MP_OKAY) {
             WOLFSSL_MSG("mp_mod error");
@@ -4165,6 +4174,10 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
 
     mp_clear(t);
 
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmp, rsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
     return ret;
 }
 
@@ -6789,7 +6802,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn)
  */
 WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
 {
-    const char prm[] = {
+    static const char prm[] = {
         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
         "C4C6628B80DC1CD129024E088A67CC74"
         "020BBEA63B139B22514A08798E3404DD"
@@ -9100,23 +9113,39 @@ int NIDToEccEnum(int n)
 
 int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group)
 {
-    int ret;
-    mp_int order;
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int *order = (mp_int *)XMALLOC(sizeof(*order), NULL,
+                                      DYNAMIC_TYPE_TMP_BUFFER);
+    if (order == NULL)
+        return 0;
+#else
+    mp_int order[1];
+#endif
 
     if (group == NULL || group->curve_idx < 0) {
         WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error");
-        return 0;
+        ret = -1;
     }
 
-    ret = mp_init(&order);
+    if (ret == 0)
+        ret = mp_init(order);
+
     if (ret == 0) {
-        ret = mp_read_radix(&order, ecc_sets[group->curve_idx].order,
+        ret = mp_read_radix(order, ecc_sets[group->curve_idx].order,
             MP_RADIX_HEX);
         if (ret == 0)
-            ret = mp_count_bits(&order);
-        mp_clear(&order);
+            ret = mp_count_bits(order);
+        mp_clear(order);
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(order, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret == -1)
+        ret = 0;
+
     return ret;
 }
 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */

+ 23 - 7
src/quic.c

@@ -692,7 +692,8 @@ cleanup:
 /* Called internally when SSL wants a certain amount of input. */
 int wolfSSL_quic_receive(WOLFSSL* ssl, byte* buf, word32 sz)
 {
-    word32 n, transferred = 0;
+    word32 n = 0;
+    int transferred = 0;
 
     WOLFSSL_ENTER("wolfSSL_quic_receive");
     while (sz > 0) {
@@ -975,14 +976,29 @@ const WOLFSSL_EVP_CIPHER* wolfSSL_quic_get_hp(WOLFSSL* ssl)
 
 size_t wolfSSL_quic_get_aead_tag_len(const WOLFSSL_EVP_CIPHER* aead_cipher)
 {
-    WOLFSSL_EVP_CIPHER_CTX ctx;
-
-    XMEMSET(&ctx, 0, sizeof(ctx));
-    if (wolfSSL_EVP_CipherInit(&ctx, aead_cipher, NULL, NULL, 0)
-        != WOLFSSL_SUCCESS) {
+    size_t ret;
+#ifdef WOLFSSL_SMALL_STACK
+    WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(
+        sizeof(*ctx), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (ctx == NULL)
         return 0;
+#else
+    WOLFSSL_EVP_CIPHER_CTX ctx[1];
+#endif
+
+    XMEMSET(ctx, 0, sizeof(*ctx));
+    if (wolfSSL_EVP_CipherInit(ctx, aead_cipher, NULL, NULL, 0)
+        == WOLFSSL_SUCCESS) {
+        ret = ctx->authTagSz;
+    } else {
+        ret = 0;
     }
-    return ctx.authTagSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUF);
+#endif
+
+    return ret;
 }
 
 int wolfSSL_quic_aead_is_gcm(const WOLFSSL_EVP_CIPHER* aead_cipher)

+ 92 - 34
src/ssl.c

@@ -32965,7 +32965,11 @@ static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
         int encTicketLen, int* encLen, void* ctx)
 {
     byte                    digest[WC_MAX_DIGEST_SIZE];
-    WOLFSSL_EVP_CIPHER_CTX  evpCtx;
+#ifdef WOLFSSL_SMALL_STACK
+    WOLFSSL_EVP_CIPHER_CTX  *evpCtx;
+#else
+    WOLFSSL_EVP_CIPHER_CTX  evpCtx[1];
+#endif
     WOLFSSL_HMAC_CTX        hmacCtx;
     unsigned int            mdSz = 0;
     int                     len = 0;
@@ -32981,14 +32985,26 @@ static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
         return WOLFSSL_TICKET_RET_FATAL;
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
+                                               DYNAMIC_TYPE_TMP_BUFFER);
+    if (evpCtx == NULL) {
+        WOLFSSL_MSG("out of memory");
+        return WOLFSSL_TICKET_RET_FATAL;
+    }
+#endif
+
     /* Initialize the cipher and HMAC. */
-    wolfSSL_EVP_CIPHER_CTX_init(&evpCtx);
+    wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
     if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
         WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
         return WOLFSSL_TICKET_RET_FATAL;
     }
     res = ssl->ctx->ticketEncWrapCb(ssl, keyName,
-            iv, &evpCtx, &hmacCtx, enc);
+            iv, evpCtx, &hmacCtx, enc);
     if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW) {
         WOLFSSL_MSG("Ticket callback error");
         ret = WOLFSSL_TICKET_RET_FATAL;
@@ -32998,11 +33014,11 @@ static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
     if (enc)
     {
         /* Encrypt in place. */
-        if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
+        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
                                       encTicket, encTicketLen))
             goto end;
         encTicketLen = len;
-        if (!wolfSSL_EVP_EncryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
+        if (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[encTicketLen], &len))
             goto end;
         /* Total length of encrypted data. */
         encTicketLen += len;
@@ -33030,11 +33046,11 @@ static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
             goto end;
 
         /* Decrypt the ticket data in place. */
-        if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
+        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
                                       encTicket, encTicketLen))
             goto end;
         encTicketLen = len;
-        if (!wolfSSL_EVP_DecryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
+        if (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[encTicketLen], &len))
             goto end;
         /* Total length of decrypted data. */
         *encLen = encTicketLen + len;
@@ -33048,6 +33064,9 @@ static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
 end:
 
     (void)wc_HmacFree(&hmacCtx.hmac);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
     return ret;
 }
@@ -35659,9 +35678,16 @@ static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
 {
     int ret = WOLFSSL_SUCCESS;
     int rc = 0;
-    mp_int w_mp;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int *w_mp = (mp_int *)XMALLOC(sizeof(*w_mp), NULL,
+                                     DYNAMIC_TYPE_TMP_BUFFER);
+    if (w_mp == NULL)
+        return WOLFSSL_FAILURE;
+#else
+    mp_int w_mp[1];
+#endif
 
-    XMEMSET(&w_mp, 0, sizeof(mp_int));
+    XMEMSET(w_mp, 0, sizeof(*w_mp));
 
     if (bn == NULL || bn->internal == NULL) {
         WOLFSSL_MSG("bn NULL error");
@@ -35684,21 +35710,21 @@ static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
             }
         }
         else {
-            if (mp_init(&w_mp) != MP_OKAY) {
+            if (mp_init(w_mp) != MP_OKAY) {
                 ret = WOLFSSL_FAILURE;
             }
             if (ret == WOLFSSL_SUCCESS) {
-                if (mp_set_int(&w_mp, w) != MP_OKAY) {
+                if (mp_set_int(w_mp, w) != MP_OKAY) {
                     ret = WOLFSSL_FAILURE;
                 }
             }
             if (ret == WOLFSSL_SUCCESS) {
                 if (sub == 1) {
-                    rc = mp_sub((mp_int *)bn->internal, &w_mp,
+                    rc = mp_sub((mp_int *)bn->internal, w_mp,
                                 (mp_int *)bn->internal);
                 }
                 else {
-                    rc = mp_add((mp_int *)bn->internal, &w_mp,
+                    rc = mp_add((mp_int *)bn->internal, w_mp,
                                 (mp_int *)bn->internal);
                 }
                 if (rc != MP_OKAY) {
@@ -35709,7 +35735,11 @@ static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
         }
     }
 
-    mp_free(&w_mp);
+    mp_free(w_mp);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
     return ret;
 }
@@ -40455,7 +40485,6 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
           WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert,
           WOLF_STACK_OF(WOLFSSL_X509)** ca)
 {
-    DecodedCert DeCert;
     void* heap = NULL;
     int ret;
     byte* certData = NULL;
@@ -40463,6 +40492,11 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
     byte* pk = NULL;
     word32 pkSz;
     WC_DerCertList* certList = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *DeCert;
+#else
+    DecodedCert DeCert[1];
+#endif
 
     WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
 
@@ -40491,6 +40525,15 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
         return WOLFSSL_FAILURE;
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    DeCert = (DecodedCert *)XMALLOC(sizeof(*DeCert), heap,
+                                    DYNAMIC_TYPE_TMP_BUFFER);
+    if (DeCert == NULL) {
+        WOLFSSL_MSG("out of memory");
+        return WOLFSSL_FAILURE;
+    }
+#endif
+
     /* Decode cert and place in X509 stack struct */
     if (certList != NULL) {
         WC_DerCertList* current = certList;
@@ -40512,7 +40555,8 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
                 current = next;
             }
-            return WOLFSSL_FAILURE;
+            ret = WOLFSSL_FAILURE;
+            goto out;
         }
         XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
 
@@ -40524,16 +40568,16 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
             x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
                 DYNAMIC_TYPE_X509);
             InitX509(x509, 1, heap);
-            InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
-            if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
+            InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
+            if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
                 WOLFSSL_MSG("Issue with parsing certificate");
-                FreeDecodedCert(&DeCert);
+                FreeDecodedCert(DeCert);
                 wolfSSL_X509_free(x509);
             }
             else {
-                if (CopyDecodedToX509(x509, &DeCert) != 0) {
+                if (CopyDecodedToX509(x509, DeCert) != 0) {
                     WOLFSSL_MSG("Failed to copy decoded cert");
-                    FreeDecodedCert(&DeCert);
+                    FreeDecodedCert(DeCert);
                     wolfSSL_X509_free(x509);
                     wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
                     if (pk != NULL) {
@@ -40550,9 +40594,10 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
                         current = next;
                     }
-                    return WOLFSSL_FAILURE;
+                    ret = WOLFSSL_FAILURE;
+                    goto out;
                 }
-                FreeDecodedCert(&DeCert);
+                FreeDecodedCert(DeCert);
 
                 if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
                     WOLFSSL_MSG("Failed to push x509 onto stack");
@@ -40573,7 +40618,8 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
                         current = next;
                     }
-                    return WOLFSSL_FAILURE;
+                    ret = WOLFSSL_FAILURE;
+                    goto out;
                 }
             }
             current = current->next;
@@ -40595,16 +40641,17 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
             }
             XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
-            return WOLFSSL_FAILURE;
+            ret = WOLFSSL_FAILURE;
+            goto out;
         }
         InitX509(*cert, 1, heap);
-        InitDecodedCert(&DeCert, certData, certDataSz, heap);
-        if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
+        InitDecodedCert(DeCert, certData, certDataSz, heap);
+        if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
             WOLFSSL_MSG("Issue with parsing certificate");
         }
-        if (CopyDecodedToX509(*cert, &DeCert) != 0) {
+        if (CopyDecodedToX509(*cert, DeCert) != 0) {
             WOLFSSL_MSG("Failed to copy decoded cert");
-            FreeDecodedCert(&DeCert);
+            FreeDecodedCert(DeCert);
             if (pk != NULL) {
                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
             }
@@ -40612,9 +40659,10 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
             }
             wolfSSL_X509_free(*cert); *cert = NULL;
-            return WOLFSSL_FAILURE;
+            ret = WOLFSSL_FAILURE;
+            goto out;
         }
-        FreeDecodedCert(&DeCert);
+        FreeDecodedCert(DeCert);
         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
     }
 
@@ -40629,7 +40677,8 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
             }
             XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
-            return WOLFSSL_FAILURE;
+            ret = WOLFSSL_FAILURE;
+            goto out;
         }
 
     #ifndef NO_RSA
@@ -40660,7 +40709,8 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
             }
             wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
             WOLFSSL_MSG("Bad PKCS12 key format");
-            return WOLFSSL_FAILURE;
+            ret = WOLFSSL_FAILURE;
+            goto out;
         }
 
         if (pkey != NULL && *pkey != NULL) {
@@ -40671,7 +40721,15 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
     (void)ret;
     (void)ca;
 
-    return WOLFSSL_SUCCESS;
+    ret = WOLFSSL_SUCCESS;
+
+out:
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(DeCert, heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
 }
 
 int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw,

+ 115 - 50
src/x509.c

@@ -115,14 +115,18 @@ unsigned int wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509* x509)
 /* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
 int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
 {
-    int extCount = 0;
+    int extCount = WOLFSSL_FAILURE;
     int length = 0;
     int outSz = 0;
     const byte* rawCert;
     int sz = 0;
     word32 idx = 0;
-    DecodedCert cert;
     const byte* input;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *cert;
+#else
+    DecodedCert cert[1];
+#endif
 
     WOLFSSL_ENTER("wolfSSL_X509_get_ext_count()");
     if (passedCert == NULL) {
@@ -135,26 +139,33 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
         WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
         return WOLFSSL_FAILURE;
     }
-    InitDecodedCert(&cert, rawCert, (word32)outSz, 0);
 
-    if (ParseCert(&cert,
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL) {
+        WOLFSSL_MSG("out of memory");
+        return WOLFSSL_FAILURE;
+    }
+#endif
+
+    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
+
+    if (ParseCert(cert,
 #ifdef WOLFSSL_CERT_REQ
             passedCert->isCSR ? CERTREQ_TYPE :
 #endif
                     CA_TYPE,
             NO_VERIFY, NULL) < 0) {
         WOLFSSL_MSG("\tCertificate parsing failed");
-        FreeDecodedCert(&cert);
-        return WOLFSSL_FAILURE;
+        goto out;
     }
 
-    input = cert.extensions;
-    sz = cert.extensionsSz;
+    input = cert->extensions;
+    sz = cert->extensionsSz;
 
     if (input == NULL || sz == 0) {
         WOLFSSL_MSG("\tsz or input NULL error");
-        FreeDecodedCert(&cert);
-        return WOLFSSL_FAILURE;
+        goto out;
     }
 
 #ifdef WOLFSSL_CERT_REQ
@@ -163,33 +174,37 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
     {
         if (input[idx++] != ASN_EXTENSIONS) {
             WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
-            FreeDecodedCert(&cert);
-            return WOLFSSL_FAILURE;
+            goto out;
         }
 
         if (GetLength(input, &idx, &length, sz) < 0) {
             WOLFSSL_MSG("\tfail: invalid length");
-            FreeDecodedCert(&cert);
-            return WOLFSSL_FAILURE;
+            goto out;
         }
     }
 
     if (GetSequence(input, &idx, &length, sz) < 0) {
         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
-        FreeDecodedCert(&cert);
-        return WOLFSSL_FAILURE;
+        goto out;
     }
 
+    extCount = 0;
     while (idx < (word32)sz) {
         if (GetSequence(input, &idx, &length, sz) < 0) {
             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
-            FreeDecodedCert(&cert);
+            FreeDecodedCert(cert);
             return WOLFSSL_FAILURE;
         }
         idx += length;
         extCount++;
     }
-    FreeDecodedCert(&cert);
+
+out:
+
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
     return extCount;
 }
 
@@ -1709,7 +1724,11 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
     const byte* rawCert;
     const byte* input;
     word32 oid, idx = 0, tmpIdx = 0, foundNID;
-    DecodedCert cert;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *cert;
+#else
+    DecodedCert cert[1];
+#endif
 
     WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
 
@@ -1731,26 +1750,33 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
         return WOLFSSL_FATAL_ERROR;
     }
 
-    InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert *)XMALLOC(sizeof(*cert), x509->heap,
+                                  DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL) {
+        WOLFSSL_MSG("\tout of memory");
+        return WOLFSSL_FATAL_ERROR;
+    }
+#endif
 
-    if (ParseCert(&cert,
+    InitDecodedCert( cert, rawCert, (word32)outSz, 0);
+
+    if (ParseCert(cert,
 #ifdef WOLFSSL_CERT_REQ
             x509->isCSR ? CERTREQ_TYPE :
 #endif
             CA_TYPE,
             NO_VERIFY, NULL) < 0) {
         WOLFSSL_MSG("\tCertificate parsing failed");
-        FreeDecodedCert(&cert);
-        return WOLFSSL_FATAL_ERROR;
+        goto out;
     }
 
-    input = cert.extensions;
-    sz = cert.extensionsSz;
+    input = cert->extensions;
+    sz = cert->extensionsSz;
 
     if (input == NULL || sz == 0) {
         WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
-        FreeDecodedCert(&cert);
-        return WOLFSSL_FATAL_ERROR;
+        goto out;
     }
 
 #ifdef WOLFSSL_CERT_REQ
@@ -1759,21 +1785,18 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
     {
         if (input[idx++] != ASN_EXTENSIONS) {
             WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
-            FreeDecodedCert(&cert);
-            return WOLFSSL_FATAL_ERROR;
+            goto out;
         }
 
         if (GetLength(input, &idx, &length, sz) < 0) {
             WOLFSSL_MSG("\tfail: invalid length");
-            FreeDecodedCert(&cert);
-            return WOLFSSL_FATAL_ERROR;
+            goto out;
         }
     }
 
     if (GetSequence(input, &idx, &length, sz) < 0) {
         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
-        FreeDecodedCert(&cert);
-        return WOLFSSL_FATAL_ERROR;
+        goto out;
     }
 
     while (idx < (word32)sz) {
@@ -1781,16 +1804,14 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
 
         if (GetSequence(input, &idx, &length, sz) < 0) {
             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
-            FreeDecodedCert(&cert);
-            return WOLFSSL_FATAL_ERROR;
+            goto out;
         }
 
         tmpIdx = idx;
         ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
         if (ret < 0) {
             WOLFSSL_MSG("\tfail: OBJECT ID");
-            FreeDecodedCert(&cert);
-            return WOLFSSL_FATAL_ERROR;
+            goto out;
         }
         idx = tmpIdx;
         foundNID = (word32)oid2nid(oid, oidCertExtType);
@@ -1809,7 +1830,12 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
         extCount++;
     } /* while(idx < sz) */
 
-    FreeDecodedCert(&cert);
+out:
+
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
     return found ? extCount : WOLFSSL_FATAL_ERROR;
 }
@@ -11807,7 +11833,11 @@ int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
                     unsigned int flags, char **peername)
 {
     int         ret;
-    DecodedCert dCert;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *dCert;
+#else
+    DecodedCert dCert[1];
+#endif
 
     WOLFSSL_ENTER("wolfSSL_X509_check_host");
 
@@ -11829,15 +11859,30 @@ int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
         return WOLFSSL_FAILURE;
     }
 
-    InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
-    ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
+#ifdef WOLFSSL_SMALL_STACK
+    dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (dCert == NULL) {
+        WOLFSSL_MSG("\tout of memory");
+        return WOLFSSL_FATAL_ERROR;
+    }
+#endif
+
+    InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
+    ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL);
     if (ret != 0) {
-        FreeDecodedCert(&dCert);
-        return WOLFSSL_FAILURE;
+        goto out;
     }
 
-    ret = CheckHostName(&dCert, (char *)chk, chklen);
-    FreeDecodedCert(&dCert);
+    ret = CheckHostName(dCert, (char *)chk, chklen);
+
+out:
+
+    FreeDecodedCert(dCert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(dCert, x->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
     if (ret != 0)
         return WOLFSSL_FAILURE;
     return WOLFSSL_SUCCESS;
@@ -11848,7 +11893,11 @@ int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
         unsigned int flags)
 {
     int ret = WOLFSSL_FAILURE;
-    DecodedCert dCert;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert *dCert = NULL;
+#else
+    DecodedCert dCert[1];
+#endif
 
     WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
 
@@ -11862,14 +11911,25 @@ int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
         ret = WOLFSSL_SUCCESS;
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    if (ret == WOLFSSL_SUCCESS) {
+        dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
+                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (dCert == NULL) {
+            WOLFSSL_MSG("\tout of memory");
+            ret = WOLFSSL_FAILURE;
+        }
+    }
+#endif
+
     if (ret == WOLFSSL_SUCCESS) {
-        InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
-        ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
+        InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
+        ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL);
         if (ret != 0) {
             ret = WOLFSSL_FAILURE;
         }
         else {
-            ret = CheckIPAddr(&dCert, ipasc);
+            ret = CheckIPAddr(dCert, ipasc);
             if (ret != 0) {
                 ret = WOLFSSL_FAILURE;
             }
@@ -11877,9 +11937,14 @@ int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
                 ret = WOLFSSL_SUCCESS;
             }
         }
-        FreeDecodedCert(&dCert);
+        FreeDecodedCert(dCert);
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    if (dCert != NULL)
+        XFREE(dCert, x->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
     return ret;
 }
 #endif

+ 8 - 8
tests/quic.c

@@ -413,7 +413,7 @@ static int ctx_set_encryption_secrets(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL lev
 static int ctx_add_handshake_data(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL level,
                                   const uint8_t *data, size_t len);
 static int ctx_flush_flight(WOLFSSL *ssl);
-static int ctx_send_alert(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL level, uint8_t alert);
+static int ctx_send_alert(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL level, uint8_t err);
 #ifdef HAVE_SESSION_TICKET
 static int ctx_session_ticket_cb(WOLFSSL* ssl,
                                  const unsigned char* ticket, int ticketSz,
@@ -793,7 +793,7 @@ static void check_crypto_rec(const byte *data, size_t data_len, int verbose, int
     }
 }
 
-static void check_crypto_records(QuicTestContext *from, OutputBuffer *out, int indent, char *rec_log)
+static void check_crypto_records(QuicTestContext *from, OutputBuffer *out, int indent, char *rec_log, size_t rec_log_size)
 {
     const byte *data = out->data;
     size_t data_len = out->len;
@@ -843,8 +843,8 @@ static void check_crypto_records(QuicTestContext *from, OutputBuffer *out, int i
         }
 
         if (rec_log) {
-            if (*rec_log) strcat(rec_log, ":");
-            strcat(rec_log, rec_name);
+            if (*rec_log) XSTRLCAT(rec_log, ":", rec_log_size);
+            XSTRLCAT(rec_log, rec_name, rec_log_size);
         }
         if (from->verbose) printf("%*sCRYPTO[%s]: ", indent, " ", rec_name);
         check_rec(data, rec_len, from->verbose, indent);
@@ -854,7 +854,7 @@ static void check_crypto_records(QuicTestContext *from, OutputBuffer *out, int i
     }
 }
 
-static void QuicTestContext_forward(QuicTestContext *from, QuicTestContext *to, char *rec_log)
+static void QuicTestContext_forward(QuicTestContext *from, QuicTestContext *to, char *rec_log, size_t rec_log_size)
 {
     int ret;
     OutputBuffer *out, *old;
@@ -869,7 +869,7 @@ static void QuicTestContext_forward(QuicTestContext *from, QuicTestContext *to,
             if (from->verbose) dump_buffer("EarlyData", out->data, out->len, 4);
         }
         else {
-            check_crypto_records(from, out, 4, rec_log);
+            check_crypto_records(from, out, 4, rec_log, rec_log_size);
         }
         ret = wolfSSL_provide_quic_data(to->ssl, out->level, out->data, out->len);
         out->len = 0;
@@ -951,7 +951,7 @@ static int QuicConversation_step(QuicConversation *conv)
         conv->started = 1;
     }
     if (conv->server->output.len > 0) {
-        QuicTestContext_forward(conv->server, conv->client, conv->rec_log);
+        QuicTestContext_forward(conv->server, conv->client, conv->rec_log, sizeof conv->rec_log);
         n = wolfSSL_quic_read_write(conv->client->ssl);
         if (n != WOLFSSL_SUCCESS) {
             AssertIntEQ(wolfSSL_get_error(conv->client->ssl, 0), SSL_ERROR_WANT_READ);
@@ -959,7 +959,7 @@ static int QuicConversation_step(QuicConversation *conv)
         return 1;
     }
     else if (conv->client->output.len > 0) {
-        QuicTestContext_forward(conv->client, conv->server, conv->rec_log);
+        QuicTestContext_forward(conv->client, conv->server, conv->rec_log, sizeof conv->rec_log);
 #ifdef WOLFSSL_EARLY_DATA
         if (conv->accept_early_data) {
             int written;

+ 23 - 10
wolfcrypt/src/ecc.c

@@ -7111,7 +7111,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
 #endif
 {
 #ifdef WOLFSSL_SMALL_STACK_CACHE
-  ecc_key        key;
+  ecc_key        *key = NULL;
 #endif
 #ifdef WOLFSSL_SMALL_STACK
   ecc_point**    precomp = NULL;
@@ -7152,24 +7152,35 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
 #endif
 
 #ifdef WOLFSSL_SMALL_STACK
+  #ifdef WOLFSSL_SMALL_STACK_CACHE
+  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
+  if (key == NULL) {
+     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
+     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+     return GEN_MEM_ERR;
+  }
+  #endif
   precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
                                                        DYNAMIC_TYPE_ECC_BUFFER);
   if (precomp == NULL) {
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+  #ifdef WOLFSSL_SMALL_STACK_CACHE
+     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
+  #endif
      return GEN_MEM_ERR;
   }
 #endif
 #ifdef WOLFSSL_SMALL_STACK_CACHE
-  key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
-  key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
+  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 #ifdef ALT_ECC_SIZE
   key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
   key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
   key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 #endif
 
-  if (key.t1 == NULL || key.t2 == NULL
+  if (key->t1 == NULL || key->t2 == NULL
 #ifdef ALT_ECC_SIZE
      || key.x == NULL || key.y == NULL || key.z == NULL
 #endif
@@ -7179,14 +7190,15 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
 #endif
-      XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
-      XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
+      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
       XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
       XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
       XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
+      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
       return MEMORY_E;
   }
-  C->key = &key;
+  C->key = key;
 #endif /* WOLFSSL_SMALL_STACK_CACHE */
 
   /* init variables */
@@ -7230,7 +7242,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
             if (err != MP_OKAY)
                 break;
         #ifdef WOLFSSL_SMALL_STACK_CACHE
-            precomp[x]->key = &key;
+            precomp[x]->key = key;
         #endif
         }
     }
@@ -7399,8 +7411,9 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
   XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
   XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
 #endif
-  XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
-  XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
+  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
+  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
+  XFREE(key, heap, DYNAMIC_TYPE_ECC);
   C->key = NULL;
 #endif
 #ifdef WOLFSSL_SMALL_STACK

+ 66 - 4
wolfcrypt/src/sakke.c

@@ -1885,15 +1885,27 @@ static int sakke_accumulate_line_add_one(mp_proj* v, mp_int* prime, mp_digit mp,
 static int sakke_accumulate_line_dbl(mp_proj* v, ecc_point* p, ecc_point* q,
         mp_int* prime, mp_digit mp, mp_proj* r, mp_int** t)
 {
-    int err;
+    int err = 0;
     mp_int* t1 = t[0];
     mp_int* t2 = r->z;
     mp_int* z2 = t[1];
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* l = NULL;
+    mp_int* ty = NULL;
+    l = (mp_int *)XMALLOC(sizeof(*l), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (l == NULL)
+        err = 1;
+    ty = (mp_int *)XMALLOC(sizeof(*ty), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (ty == NULL)
+        err = 1;
+#else
     mp_int tmp[2];
     mp_int* l = &tmp[0];
     mp_int* ty = &tmp[1];
+#endif
 
-    err = mp_init(l);
+    if (err == 0)
+        err = mp_init(l);
     if (err == 0) {
         err = mp_init(ty);
     }
@@ -1985,8 +1997,19 @@ static int sakke_accumulate_line_dbl(mp_proj* v, ecc_point* p, ecc_point* q,
         err = sakke_submod(p->y, t2, prime, p->y);
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    if (ty != NULL) {
+        mp_free(ty);
+        XFREE(ty, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    if (l != NULL) {
+        mp_free(l);
+        XFREE(l, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#else
     mp_free(ty);
     mp_free(l);
+#endif
 
     return err;
 }
@@ -2018,16 +2041,36 @@ static int sakke_accumulate_line_dbl(mp_proj* v, ecc_point* p, ecc_point* q,
 static int sakke_accumulate_line_add_one(mp_proj* v, mp_int* prime, mp_digit mp,
         ecc_point* p, ecc_point* q, ecc_point* c, mp_proj* r, mp_int** t)
 {
-    int err;
+    int err = 0;
     mp_int* t1 = t[0];
     mp_int* t2 = t[1];
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int* h = NULL;
+    mp_int* ty = NULL;
+    mp_int* tz = NULL;
+    mp_int* t3 = NULL;
+    h = (mp_int *)XMALLOC(sizeof(*h), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (h == NULL)
+        err = 1;
+    ty = (mp_int *)XMALLOC(sizeof(*ty), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (ty == NULL)
+        err = 1;
+    tz = (mp_int *)XMALLOC(sizeof(*tz), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tz == NULL)
+        err = 1;
+    t3 = (mp_int *)XMALLOC(sizeof(*t3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (t3 == NULL)
+        err = 1;
+#else
     mp_int tmp[4];
     mp_int* h = &tmp[0];
     mp_int* ty = &tmp[1];
     mp_int* tz = &tmp[2];
     mp_int* t3 = &tmp[3];
+#endif
 
-    err = mp_init_multi(h, ty, tz, t3, NULL, NULL);
+    if (err == 0)
+        err = mp_init_multi(h, ty, tz, t3, NULL, NULL);
 
     /* r.x = (q.x + p.x) * c.y */
     if (err == 0) {
@@ -2135,10 +2178,29 @@ static int sakke_accumulate_line_add_one(mp_proj* v, mp_int* prime, mp_digit mp,
         err = sakke_addmod(t3, t2, prime, c->y);
     }
 
+#ifdef WOLFSSL_SMALL_STACK
+    if (t3 != NULL) {
+        mp_free(t3);
+        XFREE(t3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    if (tz != NULL) {
+        mp_free(tz);
+        XFREE(tz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    if (ty != NULL) {
+        mp_free(ty);
+        XFREE(ty, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    if (h != NULL) {
+        mp_free(h);
+        XFREE(h, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#else
     mp_free(t3);
     mp_free(tz);
     mp_free(ty);
     mp_free(h);
+#endif
 
     return err;
 }

+ 46 - 33
wolfcrypt/test/test.c

@@ -29532,82 +29532,95 @@ static int eccsi_enc_dec_pair_test(EccsiKey* priv, mp_int* ssk, ecc_point* pvt)
     int ret;
     byte data[32 * 3];
     word32 sz;
-    mp_int decSsk;
     ecc_point* decPvt = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    mp_int *decSsk = (mp_int *)XMALLOC(sizeof(*decSsk), HEAP_HINT,
+                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (decSsk == NULL)
+        return -10173;
+#else
+    mp_int decSsk[1];
+#endif
 
-    ret = mp_init(&decSsk);
+    ret = mp_init(decSsk);
     if (ret != 0)
-        return -10117;
+        ERROR_OUT(-10117, out);
 
     decPvt = wc_ecc_new_point();
     if (decPvt == NULL)
-        return -10118;
+        ERROR_OUT(-10118, out);
 
     ret = wc_EncodeEccsiPair(priv, ssk, pvt, NULL, &sz);
     if (ret != LENGTH_ONLY_E)
-        return -10119;
+        ERROR_OUT(-10119, out);
     if (sz != 32 * 3)
-        return -10120;
+        ERROR_OUT(-10120, out);
     ret = wc_EncodeEccsiPair(priv, ssk, pvt, data, &sz);
     if (ret != 0)
-        return -10121;
+        ERROR_OUT(-10121, out);
     if (sz != 32* 3)
-        return -10122;
-    ret = wc_DecodeEccsiPair(priv, data, sz, &decSsk, decPvt);
+        ERROR_OUT(-10122, out);
+    ret = wc_DecodeEccsiPair(priv, data, sz, decSsk, decPvt);
     if (ret != 0)
-        return -10123;
-    if (mp_cmp(ssk, &decSsk) != MP_EQ)
-        return -10124;
+        ERROR_OUT(-10123, out);
+    if (mp_cmp(ssk, decSsk) != MP_EQ)
+        ERROR_OUT(-10124, out);
     if (wc_ecc_cmp_point(pvt, decPvt) != MP_EQ)
-        return -10125;
+        ERROR_OUT(-10125, out);
 
     ret = wc_EncodeEccsiSsk(priv, ssk, NULL, &sz);
     if (ret != LENGTH_ONLY_E)
-        return -10119;
+        ERROR_OUT(-10119, out);
     if (sz != 32)
-        return -10120;
+        ERROR_OUT(-10120, out);
     ret = wc_EncodeEccsiSsk(priv, ssk, data, &sz);
     if (ret != 0)
-        return -10121;
+        ERROR_OUT(-10121, out);
     if (sz != 32)
-        return -10122;
-    ret = wc_DecodeEccsiSsk(priv, data, sz, &decSsk);
+        ERROR_OUT(-10122, out);
+    ret = wc_DecodeEccsiSsk(priv, data, sz, decSsk);
     if (ret != 0)
-        return -10123;
-    if (mp_cmp(ssk, &decSsk) != MP_EQ)
-        return -10124;
+        ERROR_OUT(-10123, out);
+    if (mp_cmp(ssk, decSsk) != MP_EQ)
+        ERROR_OUT(-10124, out);
 
     ret = wc_EncodeEccsiPvt(priv, pvt, NULL, &sz, 1);
     if (ret != LENGTH_ONLY_E)
-        return -10126;
+        ERROR_OUT(-10126, out);
     if (sz != 32 * 2)
-        return -10127;
+        ERROR_OUT(-10127, out);
     ret = wc_EncodeEccsiPvt(priv, pvt, data, &sz, 1);
     if (ret != 0)
-        return -10128;
+        ERROR_OUT(-10128, out);
     if (sz != 32 * 2)
-        return -10129;
+        ERROR_OUT(-10129, out);
     ret = wc_DecodeEccsiPvt(priv, data, sz, decPvt);
     if (ret != 0)
-        return -10130;
+        ERROR_OUT(-10130, out);
     if (wc_ecc_cmp_point(pvt, decPvt) != MP_EQ)
-        return -10131;
+        ERROR_OUT(-10131, out);
     sz = sizeof(data);
     ret = wc_EncodeEccsiPvt(priv, pvt, data, &sz, 0);
     if (ret != 0)
-        return -10128;
+        ERROR_OUT(-10128, out);
     if (sz != 32 * 2 + 1)
-        return -10129;
+        ERROR_OUT(-10129, out);
     ret = wc_DecodeEccsiPvt(priv, data, sz, decPvt);
     if (ret != 0)
-        return -10130;
+        ERROR_OUT(-10130, out);
     if (wc_ecc_cmp_point(pvt, decPvt) != MP_EQ)
-        return -10131;
+        ERROR_OUT(-10131, out);
 
     wc_ecc_del_point(decPvt);
-    mp_free(&decSsk);
 
-    return 0;
+out:
+
+    mp_free(decSsk);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decSsk, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
 }
 
 static int eccsi_imp_exp_key_test(EccsiKey* priv)

+ 1 - 1
wolfssl/internal.h

@@ -5632,7 +5632,7 @@ WOLFSSL_LOCAL int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf,
 #endif
 
 #ifdef WOLFSSL_QUIC
-#define WOLFSSL_IS_QUIC(s)  (s && s->quic.method != NULL)
+#define WOLFSSL_IS_QUIC(s)  (((s) != NULL) && ((s)->quic.method != NULL))
 WOLFSSL_LOCAL int wolfSSL_quic_receive(WOLFSSL* ssl, byte* buf, word32 sz);
 WOLFSSL_LOCAL int wolfSSL_quic_send(WOLFSSL* ssl);
 WOLFSSL_LOCAL void wolfSSL_quic_clear(WOLFSSL* ssl);

+ 5 - 0
wolfssl/wolfcrypt/settings.h

@@ -2607,6 +2607,11 @@ extern void uITRON4_free(void *p) ;
     #undef WOLFSSL_SMALL_STACK
 #endif
 
+#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_STATIC) && \
+    !defined(NO_WOLFSSL_SMALL_STACK_STATIC)
+#define WOLFSSL_SMALL_STACK_STATIC
+#endif
+
 #ifdef WOLFSSL_SMALL_STACK_STATIC
     #undef WOLFSSL_SMALL_STACK_STATIC
     #define WOLFSSL_SMALL_STACK_STATIC static