When MBEDTLS_HARDWARE_GCM is enabled, we ALT all the GCM functions that are
declared in mbedtls/gcm.h with our H/W port functions, due to which even
if non-AES ciphers such as ARIA, CAMELLIA, BLOWFISH, etc. are selected
for a GCM operation, we perform an AES-GCM operation, thus resulting into
an incorrect calculation.
Thus in such cases we need to fallback to the software definitions of
GCM.
Currently, it is not directly possible to pull in software definitions of GCM
related functions directly due to gcm_alt.h, but this commit renames the
functions by appending `_soft` to their names, thus making them look different
functions in all and thus they are made available to pull in during compilation.
The change is configrable using the config MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK.
As this config is enabled by default, building the mbedtls crypto library
(libmbedcrypto.a) with this change increases its size by ~2.5KB.
- ESP32C2 has a hardware ECC accelerator that supports NIST P-192 and NIST P-256 curves,
which can increase the performance of the point multiplication and point
verification operation.
- Provision is also added to fallback to software implementation in
case the curve is not from the supported curves
- Override ecp_mul_restartable_internal with accelerator
- Many ECC operations use the internal API ecp_mul_restartable_internal
instead of the public API mbedtls_ecp_mul for point multiplication.
This will improve the performance of all those parent operations as
well
(cherry picked from commit 0ecb27b9d88059e8980c8ae6e111283f5f2859f8)
For exponential mod (API mbedtls_mpi_exp_mod) operation, some ESP target
chips needs to have ability for both hardware and software implementation.
Hardware implementation provided performance advantage but it can only
support upto 3072 bit operations (e.g., ESP32-C3) and hence we fallback
to software implementation in such cases (e.g., 4096 bit operations).
Earlier this was handled using linker "--wrap" flag but that does not
work in all scenarios as API `mbedtls_mpi_exp_mod` is being used in
same tranlation (compilation unit).
This approach was found to be next best option with minimal changes in
mbedTLS library.
(cherry picked from commit ab3a845107377c6cdf148f86015cad94434a1f2e)
Fix a race condition in `mbedtls_aes_ni_has_support()` with some compilers.
A compiler could hoist the assignment `done = 1` above the assignment to `c`,
in which case if two threads call `mbedtls_aes_ni_has_support()` at almost
the same time, they could be interleaved as follows:
Initially: done = 0, c = 0
thread A thread B
if (!done)
done = 1; # hoisted
if (!done)
return c & what; # wrong!
c = cpuid();
return c & what
This would lead to thread B using software AES even though AESNI was
available. This is a very minor performance bug. But also, given a very
powerful adversary who can block thread A indefinitely (which may be
possible when attacking an SGX enclave), thread B could use software AES for
a long time, opening the way to a timing side channel attack.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Correct base64 input (excluding ignored characters such as spaces) consists
of exactly 4*k, 4*k-1 or 4*k-2 digits, followed by 0, 1 or 2 equal signs
respectively.
Previously, any number of trailing equal signs up to 2 was accepted, but if
there fewer than 4*k digits-or-equals, the last partial block was counted in
`*olen` in buffer-too-small mode, but was not output despite returning 0.
Now `mbedtls_base64_decode()` insists on correct padding. This is
backward-compatible since the only plausible useful inputs that used to be
accepted were inputs with 4*k-1 or 4*k-2 digits and no trailing equal signs,
and those led to invalid (truncated) output. Furthermore the function now
always reports the exact output size in buffer-too-small mode.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This is mostly unrelated to other commits in this PR, except for the
fact that one of the added X.509 tests revealed that with UBSan.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
When passed a zero-length val, the function was free-ing the buffer as
the documentation suggests:
* \param val_len The minimum length of the data buffer needed.
* If this is 0, do not allocate a buffer for the associated
* data.
* If the OID was already present, enlarge, shrink or free
* the existing buffer to fit \p val_len.
However it kept the previous length, leaving the val structure in the
corresponding item in the output list in an inconsistent state:
p == NULL but len != 0
As a result, functions that would try using this item in the list
(including the same function!) afterwards would trip an dereference the
NULL pointer.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
In functions that bypass the API functions and call an internal MAC setup
function directly, make sure to initialize the driver-specific part of the
context. This is a union, and initializing the union to `{0}` only
guarantees that the first member of the union is initialized, not
necessarily the member used by the driver. Most compilers do initialize the
whole union to all-bits-zero, but some don't. With compilers that don't, the
lack of initialization caused failures of the affected operations. This
affected one-shot MAC operations using the built-in implementation.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
In functions that bypass the API functions and call the MAC driver wrapper
`psa_driver_wrapper_mac_sign_setup()` directly, make
sure to initialize the driver-specific part of the context. This is a union,
and initializing the union to `{0}` only guarantees that the first member of
the union is initialized, not necessarily the member used by the driver.
Most compilers do initialize the whole union to all-bits-zero, but some
don't. With compilers that don't, the lack of initialization caused failures
of the affected operations. This affected several key derivation operations.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
In API functions that set up a multipart or interruptible operation, make
sure to initialize the driver-specific part of the context. This is a union,
and initializing the union to `{0}` only guarantees that the first member of
the union is initialized, not necessarily the member used by the driver.
Most compilers do initialize the whole union to all-bits-zero, but some
don't. With compilers that don't, the lack of initialization caused failures
of built-in MAC, interruptible-sign and interruptible-verify. It could also
cause failures for other operations with third-party drivers: we promise
that drivers' setup entry points receive a zero-initialized operation
structure, but this promise was not kept.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
The documentation doesn't say you can't call these functions more than
once on the same context, and if you do it shouldn't result in a memory
leak. Historically, the call to mbedtls_asn1_free_named_data_list() in
mbedtls_x509_string_to_names() (that was removed in the previous commit)
was ensuring that. Let's restore it where it makes sense. (These are the
only 3 places calling mbedtls_x509_string_to_names() in the library.)
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Now programs/x509/cert_write san="DN:CN=#0000;DN:CN=#0000" is no longer
crashing with use-after-free, instead it's now failing cleanly:
failed
! mbedtls_x509_string_to_names returned -0x2800 - X509 - Input invalid
That's better of course but still not great, will be fixed by future
commits.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This structure is initialized during the compilation and there is no
reason it changes.
Making it const allows the compiler to put it in .rodata section instead
of .data one.
Signed-off-by: Xavier Chapron <chapron.xavier@gmail.com>
Previously, the length of the label was limited to the maximal length
that would be used in the TLS 1.3 key schedule. With the keying material
exporter, labels of up to 249 bytes may be used.
Signed-off-by: Max Fillinger <maximilian.fillinger@foxcrypto.com>