Morning Ralf, This does not appear to be an issue with your target platform and looks like an error propagation issue in the verify path. If you could report your findings at: https://github.com/Mbed-TLS/mbedtls/issues/new/choose, we can then look into it.
Many thanks
Ben
On Tue, 14 Apr 2026 at 17:01, Huber, Ralf ralf.huber@kiongroup.com wrote:
Hello Ben,
Thank you for your detailed support.
We can very likely define more constraints for the certificates to limit the number of attributes in the certificates, in addition to the 2 kB size limit. Without further constraints, the theoretical worst case heap consumption might be unacceptably high for us anyway, so we might as well specify more details about what the certificates may contain. We can then measure the heap consumption with some specially crafted certificates, as suggested by you. I guess we should add 1 or 2 kB extra at the end to be on the safe side.
During my tests, I found some unexpected behavior (unexpected for me at least):
When the heap is large enough to parse the certificates and CRL, but not large enough to perform the chain verification, I get return value 0 from mbedtls_x509_crl_parse_der() and 0 from mbedtls_x509_crt_parse_der_nocopy() and MBEDTLS_ERR_X509_CERT_VERIFY_FAILED from mbedtls_x509_crt_verify(). It took me a while until I realized that MBEDTLS_ERR_X509_CERT_VERIFY_FAILED could also mean that the heap is too small.
mbedtls_x509_crt_verify() doesn’t return MBEDTLS_ERR_X509_ALLOC_FAILED or MBEDTLS_ERR_X509_BUFFER_TOO_SMALL or any value indicating that it ran out of heap. Is this expected, or could it be that there is a more fundamental problem with running Mbed TLS on our target platform (Infineon Aurix TriCore)?
Best regards,
Ralf
*Von:* Ben Taylor ben.taylor@linaro.org *Gesendet:* Montag, 13. April 2026 09:24 *An:* Huber, Ralf ralf.huber@kiongroup.com *Cc:* mbed-tls@lists.trustedfirmware.org; Thome, Rainer < rainer.thome@kiongroup.com> *Betreff:* Re: [mbed-tls] Max. heap size for X509 certificate chain verification
*WARNING: This email originated outside of the company. DO NOT CLICK links or attachments or enter any information into forms unless you trust the sender and know the content is safe.*
Morning Ralf, Many thanks for your question and interest in using mbedtls. Here are some pointers that may help you resolve your issue.
`mbedtls_x509_crt_verify()` itself does not normally allocate heap memory in the X.509 layer. The heap you need is dominated by parsing and keeping the parsed certificates/CRL resident, not by the verify call itself. In particular, the verifier builds its working chain in a local `mbedtls_x509_crt_verify_chain` object, not with `calloc()` ([x509_crt.c](library/x509_crt.c#L3045), [x509_crt.h](include/mbedtls/x509_crt.h#L267)). The main exception is `MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK`, where the callback may return heap-backed trusted certs.
For certificates, `mbedtls_x509_crt_parse_der_nocopy()` really does avoid copying the raw DER buffer ([x509_crt.c](library/x509_crt.c#L1114), [x509_crt.c](library/x509_crt.c#L1364)). However, parsing still allocates metadata:
- one `mbedtls_x509_crt` object for every certificate after the first in a
linked list ([x509_crt.c](library/x509_crt.c#L1336))
- extra `mbedtls_x509_name` nodes for issuer/subject DN components beyond
the first ([x509.c](library/x509.c#L511))
- extra `mbedtls_asn1_sequence` nodes for SANs, EKUs, certificate
policies, and `authorityCertIssuer` if those extensions are present ([x509.c](library/x509.c#L1285), [x509_crt.c](library/x509_crt.c#L738), [asn1parse.c](tf-psa-crypto/utilities/asn1parse.c#L336))
For your ECDSA P-256 case, the public key is stored inline in `mbedtls_pk_context` (`pub_raw[...]`), so there is no additional heap object just for the parsed EC public key ([pk.h](tf-psa-crypto/include/mbedtls/pk.h#L106)).
For CRLs, your understanding is correct: `mbedtls_x509_crl_parse_der()` always copies the raw DER buffer, so a 2 kB CRL already needs at least that much allocator space just for `crl->raw` ([x509_crl.c](library/x509_crl.c#L321)). On top of that, each revoked-cert entry after the first gets its own `mbedtls_x509_crl_entry` allocation ([x509_crl.c](library/x509_crl.c#L265)), so CRL heap usage depends strongly on how many revoked entries fit into those 2 kB.
So to your specific questions:
- There is no simple closed-form “heap = f(number of certs, max DER
size)” guarantee in the current API. 2. The required heap is not fixed for a given number of certificates. It depends on certificate/CRL contents:
- number of DN attributes
- number of SAN entries
- number of EKU/policy entries
- presence of AKI issuer names
- number of CRL entries
- The worst cases are not the largest RSA keys in your case, but
structures with many small list elements packed into 2 kB. 4. Verification-time heap in the X.509 layer is essentially fixed; parse-time heap is the variable part.
Practically, the safest way to size this is:
- enable `MBEDTLS_MEMORY_DEBUG`
- use `mbedtls_memory_buffer_alloc_max_get()` after parsing plus
verification ([memory_buffer_alloc.h](tf-psa-crypto/include/mbedtls/memory_buffer_alloc.h#L90))
- test with deliberately “dense” inputs:
- certificates with many short DN attributes and many SAN/EKU/policy
entries
- a CRL with as many short revoked entries as can fit into 2 kB
One more detail: `memory_buffer_alloc` adds per-allocation metadata and alignment overhead, so summing requested sizes will underestimate the required buffer ([memory_buffer_alloc.c](tf-psa-crypto/platform/memory_buffer_alloc.c#L32), [memory_buffer_alloc.c](tf-psa-crypto/platform/memory_buffer_alloc.c#L253)).
For scale only: on a 64-bit build, `sizeof(mbedtls_x509_crt)` is 1296 bytes, `sizeof(mbedtls_x509_crl_entry)` is 104 bytes, `sizeof(mbedtls_x509_name)` is 64 bytes, and `sizeof(mbedtls_x509_sequence)` is 32 bytes. A 32-bit ECU build will be smaller, but this explains why 6 kB can already be tight even with `crt_parse_der_nocopy()`.
If you need a hard guarantee from the input specification alone, you would need tighter profile limits than “DER up to 2 kB”, for example also limiting the maximum number of DN attributes, SANs, EKUs, policies, and CRL entries. Without such limits, only an empirical worst-case measurement can give a reliable bound.
Let me know if you need any further help.
Regards
Ben
On Fri, 10 Apr 2026 at 11:50, Huber, Ralf via mbed-tls < mbed-tls@lists.trustedfirmware.org> wrote:
Dear Mbed TLS contributors,
I am working on an embedded project where we need to verify an X509 certificate chain with up to 4 certificates (root cert + 2 intermediates + client cert) and a CRL. The certificates contain public keys for ECDSA for the SECP_R1_256 curve. We are using mbedTLS 4.x.
There is no heap memory in this project. It is a vehicle control ECU and all RAM is normally statically allocated for safety reasons. However, the certificate verification is not safety critical. It is OK for us to use mbedtls_memory_buffer_alloc_init() as a heap replacement for mbedTLS. I will refer to this as the “heap” for the rest of this mail.
I would like to find out how large the heap needs to be for the chain verification. The system requirements state that it shall support certificates and CRL in DER format with a size of up to 2 kB each. There are 10 kB of static RAM buffer to store 4 certificates and the CRL.
The certificates are parsed with mbedtls_x509_crt_parse_der_nocopy(), so the certificate raw data is not duplicated on the heap.
The CRL is parsed with mbedtls_x509_crl_parse_der(), so I am expecting that the CRL raw data will be copied to the heap. Thus, it needs to be at least 2 kB. Unfortunately, there seems to be no “_nocopy()” function for CRLs.
8 kB heap was enough in my tests to verify a chain of 3 test certificates with sizes of ca. 0.5 kB each. 6 kB heap wasn’t enough to do this.
Is there a way to calculate or at least estimate the maximum required heap for the given maximum certificate and CRL sizes, such that a call of mbedtls_x509_crt_verify() for the chain will never fail due to insufficient memory?
Is the required heap size fixed for a given number of certificates, or does it depend on the content of the certificates? If it does depend on the content, is there some way to construct “worst case certificates” that result in maximum heap usage, so I could use them to measure the heap consumption?
Any help on this topic is kindly appreciated!
Best regards,
Ralf Huber KION Supply Chain Solutions
Linde Material Handling GmbH, Sitz der Gesellschaft: Aschaffenburg, Registergericht: Aschaffenburg HRB9963, Ust-IdNr. DE814809128, Geschäftsführung: Andreas Krinninger (Vorsitzender), Dr. Karoline Jung-Senssfelder, Ulrike Just, Dr. Frank Schepp, Vorsitzende des Aufsichtsrats: Valeria Gargiulo
-- mbed-tls mailing list -- mbed-tls@lists.trustedfirmware.org To unsubscribe send an email to mbed-tls-leave@lists.trustedfirmware.org
Linde Material Handling GmbH, Sitz der Gesellschaft: Aschaffenburg, Registergericht: Aschaffenburg HRB9963, Ust-IdNr. DE814809128, Geschäftsführung: Andreas Krinninger (Vorsitzender), Dr. Karoline Jung-Senssfelder, Ulrike Just, Dr. Frank Schepp, Vorsitzende des Aufsichtsrats: Valeria Gargiulo