Merge pull request #10025 from waleed-elmelegy-arm/mbedtls-3.6-fix-key-deriv-bad-state-error
Backport 3.6: Fix psa_key_derivation_input_integer() not detecting bad state
diff --git a/3rdparty/everest/include/everest/kremlin/c_endianness.h b/3rdparty/everest/include/everest/kremlin/c_endianness.h
index 5cfde5d..1b0d0eb 100644
--- a/3rdparty/everest/include/everest/kremlin/c_endianness.h
+++ b/3rdparty/everest/include/everest/kremlin/c_endianness.h
@@ -7,6 +7,8 @@
#include <string.h>
#include <inttypes.h>
+#include "kremlin/internal/callconv.h"
+
/******************************************************************************/
/* Implementing C.fst (part 2: endian-ness macros) */
/******************************************************************************/
diff --git a/3rdparty/everest/include/everest/kremlin/internal/callconv.h b/3rdparty/everest/include/everest/kremlin/internal/callconv.h
index bf631ff..8ff8ca5 100644
--- a/3rdparty/everest/include/everest/kremlin/internal/callconv.h
+++ b/3rdparty/everest/include/everest/kremlin/internal/callconv.h
@@ -27,8 +27,10 @@
/* Since KreMLin emits the inline keyword unconditionally, we follow the
* guidelines at https://gcc.gnu.org/onlinedocs/gcc/Inline.html and make this
* __inline__ to ensure the code compiles with -std=c90 and earlier. */
-#ifdef __GNUC__
+#if defined(__GNUC__)
# define inline __inline__
+#elif defined(_MSC_VER)
+# define inline __inline
#endif
/* GCC-specific attribute syntax; everyone else gets the standard C inline
diff --git a/3rdparty/everest/include/everest/vs2013/inttypes.h b/3rdparty/everest/include/everest/vs2013/inttypes.h
deleted file mode 100644
index 77003be..0000000
--- a/3rdparty/everest/include/everest/vs2013/inttypes.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Custom inttypes.h for VS2010 KreMLin requires these definitions,
- * but VS2010 doesn't provide them.
- *
- * Copyright 2016-2018 INRIA and Microsoft Corporation
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-
-#ifndef _INTTYPES_H_VS2010
-#define _INTTYPES_H_VS2010
-
-#include <stdint.h>
-
-#ifdef _MSC_VER
-#define inline __inline
-#endif
-
-/* VS2010 unsigned long == 8 bytes */
-
-#define PRIu64 "I64u"
-
-#endif
diff --git a/3rdparty/everest/include/everest/vs2013/stdbool.h b/3rdparty/everest/include/everest/vs2013/stdbool.h
deleted file mode 100644
index dcae6d8..0000000
--- a/3rdparty/everest/include/everest/vs2013/stdbool.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Custom stdbool.h for VS2010 KreMLin requires these definitions,
- * but VS2010 doesn't provide them.
- *
- * Copyright 2016-2018 INRIA and Microsoft Corporation
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-
-#ifndef _STDBOOL_H_VS2010
-#define _STDBOOL_H_VS2010
-
-typedef int bool;
-
-static bool true = 1;
-static bool false = 0;
-
-#endif
diff --git a/ChangeLog.d/9652.txt b/ChangeLog.d/9652.txt
new file mode 100644
index 0000000..98a8eae
--- /dev/null
+++ b/ChangeLog.d/9652.txt
@@ -0,0 +1,9 @@
+Features
+ * MD module can now perform PSA dispatching also when
+ `MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C`, even though this
+ configuration is not officially supported. This requires that a
+ PSA Crypto provider library which:
+ * supports the required `PSA_WANT_ALG_xxx` and
+ * implements `psa_can_do_hash()` on the client interface
+ is linked against Mbed TLS and that `psa_crypto_init()` is called before
+ performing any PSA call.
diff --git a/ChangeLog.d/fix-msvc-version-guard-format-zu.txt b/ChangeLog.d/fix-msvc-version-guard-format-zu.txt
new file mode 100644
index 0000000..2713f6c
--- /dev/null
+++ b/ChangeLog.d/fix-msvc-version-guard-format-zu.txt
@@ -0,0 +1,9 @@
+Bugfix
+ * Fix definition of MBEDTLS_PRINTF_SIZET to prevent runtime crashes that
+ occurred whenever SSL debugging was enabled on a copy of Mbed TLS built
+ with Visual Studio 2013 or MinGW.
+ Fixes #10017.
+ * Remove Everest Visual Studio 2010 compatibility headers, which could
+ shadow standard CRT headers inttypes.h and stdbool.h with incomplete
+ implementatios if placed on the include path, eg. when building Mbed TLS
+ with the .sln file shipped with the project.
diff --git a/ChangeLog.d/tls-hs-defrag-in.txt b/ChangeLog.d/tls-hs-defrag-in.txt
new file mode 100644
index 0000000..6bab02a
--- /dev/null
+++ b/ChangeLog.d/tls-hs-defrag-in.txt
@@ -0,0 +1,7 @@
+Bugfix
+ * Support re-assembly of fragmented handshake messages in TLS (both
+ 1.2 and 1.3). The lack of support was causing handshake failures with
+ some servers, especially with TLS 1.3 in practice. There are a few
+ limitations, notably a fragmented ClientHello is only supported when
+ TLS 1.3 support is enabled. See the documentation of
+ mbedtls_ssl_handshake() for details.
diff --git a/docs/architecture/psa-migration/md-cipher-dispatch.md b/docs/architecture/psa-migration/md-cipher-dispatch.md
index eda65a3..89b7b61 100644
--- a/docs/architecture/psa-migration/md-cipher-dispatch.md
+++ b/docs/architecture/psa-migration/md-cipher-dispatch.md
@@ -17,36 +17,44 @@
#### Backward compatibility user story
-As a developer of an application that uses Mbed TLS's interfaces (including legacy crypto),
-I want Mbed TLS to preserve backward compatibility,
+As a developer of an application that uses Mbed TLS's interfaces (including legacy crypto),
+I want Mbed TLS to preserve backward compatibility,
so that my code keeps working in new minor versions of Mbed TLS.
#### Interface design user story
-As a developer of library code that uses Mbed TLS to perform cryptographic operations,
-I want to know which functions to call and which feature macros to check,
+As a developer of library code that uses Mbed TLS to perform cryptographic operations,
+I want to know which functions to call and which feature macros to check,
so that my code works in all Mbed TLS configurations.
Note: this is the same problem we face in X.509 and TLS.
#### Hardware accelerator vendor user stories
-As a vendor of a platform with hardware acceleration for some crypto,
-I want to build Mbed TLS in a way that uses my hardware wherever relevant,
+As a vendor of a platform with hardware acceleration for some crypto,
+I want to build Mbed TLS in a way that uses my hardware wherever relevant,
so that my customers maximally benefit from my hardware.
-As a vendor of a platform with hardware acceleration for some crypto,
-I want to build Mbed TLS without software that replicates what my hardware does,
+As a vendor of a platform with hardware acceleration for some crypto,
+I want to build Mbed TLS without software that replicates what my hardware does,
to minimize the code size.
+#### Integrators of Mbed TLS alongside a PSA Crypto provider
+
+I have a platform where the PSA Crypto is already provided "externally" from
+Mbed TLS (ex: through TF-M in Zephyr) and I would like Mbed TLS to make use
+of it whenever possible in order to benefit from higher performances (if some
+hardware acceleration is supported in the provider) and/or higher isolation/security
+(if the PSA provider is running in a completetly separated/inaccessible context).
+
#### Maintainer user stories
-As a maintainer of Mbed TLS,
-I want to have clear rules for when to use which interface,
+As a maintainer of Mbed TLS,
+I want to have clear rules for when to use which interface,
to avoid bugs in “unusual” configurations.
-As a maintainer of Mbed TLS,
-I want to avoid duplicating code,
+As a maintainer of Mbed TLS,
+I want to avoid duplicating code,
because this is inefficient and error-prone.
### Use PSA more
@@ -55,8 +63,8 @@
The goal of this work is to arrange for more non-PSA interfaces to use PSA interfaces under the hood, without breaking code in the cases where this doesn't work. Using PSA interfaces has two benefits:
-* Where a PSA driver is available, it likely has better performance, and sometimes better security, than the built-in software implementation.
-* In many scenarios, where a PSA driver is available, this allows removing the software implementation altogether.
+* Where a PSA driver/provider is available, it likely has better performance, and sometimes better security, than the built-in software implementation.
+* In many scenarios, where a PSA driver/provider is available, this allows removing the software implementation altogether.
* We may be able to get rid of some redundancies, for example the duplication between the implementations of HMAC in `md.c` and in `psa_crypto_mac.c`, and HKDF in `hkdf.c` and `psa_crypto.c`.
### Correct dependencies
@@ -72,7 +80,6 @@
The following configuration options are described as experimental, and are likely to change at least marginally:
* `MBEDTLS_PSA_CRYPTO_CLIENT`: “This interface is experimental and may change or be removed without notice.” In practice we don't want to remove this, but we may constrain how it's used.
-* `MBEDTLS_PSA_CRYPTO_DRIVERS`: “This interface is experimental. We intend to maintain backward compatibility with application code that relies on drivers, but the driver interfaces may change without notice.” In practice, this may mean constraints not only on how to write drivers, but also on how to integrate drivers into code that is platform code more than application code.
* `MBEDTLS_PSA_CRYPTO_CONFIG`: “This feature is still experimental and is not ready for production since it is not completed.” We may want to change this, for example, to automatically enable more mechanisms (although this wouldn't be considered a backward compatibility break anyway, since we don't promise that you will not get a feature if you don't enable its `PSA_WANT_xxx`).
### Non-goals
@@ -190,7 +197,7 @@
Here are some reasons why calling `psa_xxx()` to perform a hash or cipher calculation might not be desirable in some circumstances, explaining why the application would arrange to call the legacy software implementation instead.
-* `MBEDTLS_PSA_CRYPTO_C` is disabled.
+* `MBEDTLS_PSA_CRYPTO_CLIENT` is disabled.
* There is a PSA driver which has not been initialized (this happens in `psa_crypto_init()`).
* For ciphers, the keystore is not initialized yet, and Mbed TLS uses a custom implementation of PSA ITS where the file system is not accessible yet (because something else needs to happen first, and the application takes care that it happens before it calls `psa_crypto_init()`). A possible workaround may be to dispatch to the internal functions that are called after the keystore lookup, rather than to the PSA API functions (but this is incompatible with `MBEDTLS_PSA_CRYPTO_CLIENT`).
* The requested mechanism is enabled in the legacy interface but not in the PSA interface. This was not really intended, but is possible, for example, if you enable `MBEDTLS_MD5_C` for PEM decoding with PBKDF1 but don't want `PSA_ALG_WANT_MD5` because it isn't supported for `PSA_ALG_RSA_PSS` and `PSA_ALG_DETERMINISTIC_ECDSA`.
@@ -208,7 +215,7 @@
#### Non-support guarantees: requirements
-Generally speaking, just because some feature is not enabled in `mbedtls_config.h` or `psa_config.h` doesn't guarantee that it won't be enabled in the build. We can enable additional features through `build_info.h`.
+Generally speaking, just because some feature is not enabled in `mbedtls_config.h` or `crypto_config.h` doesn't guarantee that it won't be enabled in the build. We can enable additional features through `build_info.h` and other header files included there (`*adjust*.h`).
If `PSA_WANT_xxx` is disabled, this should guarantee that attempting xxx through the PSA API will fail. This is generally guaranteed by the test suite `test_suite_psa_crypto_not_supported` with automatically enumerated test cases, so it would be inconvenient to carve out an exception.
@@ -331,14 +338,10 @@
This will go away naturally in 4.0 when this macros is not longer an option (because it's always on).
-#### Don't support for `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`
+#### Support for `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`
We generally don't really support builds with `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`. For example, both `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_SSL_PROTO_TLS1_3` require `MBEDTLS_PSA_CRYPTO_C`, while in principle they should only require `MBEDTLS_PSA_CRYPTO_CLIENT`.
-Considering this existing restriction which we do not plan to lift before 4.0, it is acceptable driver-only hashes and cipher support to have the same restriction in 3.x.
-
-It is however desirable for the design to keep support for `MBEDTLS_PSA_CRYPTO_CLIENT` in mind, in order to avoid making it more difficult to add in the future.
-
#### For cipher: prioritize constrained devices and modern TLS
The primary target is a configuration like TF-M's medium profile, plus TLS with only AEAD ciphersuites.
@@ -420,8 +423,9 @@
For each hash algorithm, `md.h` defines a macro `MBEDTLS_MD_CAN_xxx` whenever the corresponding hash is available through MD light. These macros are only defined when `MBEDTLS_MD_LIGHT` is enabled. Per “[Availability of hashes](#availability-of-hashes)”, `MBEDTLS_MD_CAN_xxx` is enabled if:
-* the corresponding `MBEDTLS_xxx_C` is defined; or
-* one of `MBEDTLS_PSA_CRYPTO_C` or `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, and the corresponding `PSA_WANT_ALG_xxx` is enabled.
+* the corresponding `MBEDTLS_xxx_C` is defined.
+* `MBEDTLS_PSA_CRYPTO_C` is enabled and the corresponding `PSA_WANT_ALG_xxx` and `MBEDTLS_PSA_ACCEL_ALG_xxx` are enabled. This enables driver acceleration support.
+* `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled the corresponding `PSA_WANT_ALG_xxx` is enabled. Then the Mbed TLS library must be linked against the PSA Crypto provider one which will eventually handle all PSA calls.
Note that some algorithms have different spellings in legacy and PSA. Since MD is a legacy interface, we'll use the legacy names. Thus, for example:
@@ -440,7 +444,7 @@
#### MD light internal support macros
-* If at least one hash has a PSA driver, define `MBEDTLS_MD_SOME_PSA`.
+* If at least one hash has a PSA driver or support in PSA Crypto provider, define `MBEDTLS_MD_SOME_PSA`.
* If at least one hash has a legacy implementation, defined `MBEDTLS_MD_SOME_LEGACY`.
#### Support for PSA in the MD context
@@ -488,15 +492,24 @@
#### Determination of PSA support at runtime
+Mbed TLS defines internal symbols `MBEDTLS_MD_xxx_VIA_PSA` which are used to check if the `xxx` hash algorithm is supported in PSA. They are enabled when:
+
+* `MBEDTLS_PSA_CRYPTO_C && MBEDTLS_PSA_ACCEL_ALG_xxx`, i.e. when the PSA Crypto core is built with Mbed TLS and the `xxx` is accelerated through a driver.
+* `MBEDTLS_PSA_CRYPTO_CLIENT && PSA_WANT_ALG_xxx`, i.e. there is a PSA Crypto provider/server which supports `xxx` hash algorithm.
+
+MD internally uses the following private function to determine if PSA can be used at runtime or not:
+
```
-int psa_can_do_hash(psa_algorithm_t hash_alg);
+static int md_can_use_psa(const mbedtls_md_info_t *info)
```
-The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA.
+Internally this function does the following:
-As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
+* First of all it converts the `mbedtls_md_info_t` to `psa_algorithm_t`. The result of this conversion is based on the `MBEDTLS_MD_xxx_VIA_PSA` symbols: if an algorithm does not have the corresponding `MBEDTLS_MD_xxx_VIA_PSA` enabled, then `md_can_use_psa` will return false.
-Usage note: for algorithms that are not enabled via PSA, calling `psa_can_do_hash` is generally safe: whether it returns 0 or 1, you can call a PSA hash function on the algorithm and it will return `PSA_ERROR_NOT_SUPPORTED`.
+* `int psa_can_do_hash(psa_algorithm_t hash_alg)` is then used to further checking if the PSA Crypto core has been initialized or not. If so then `md_can_use_psa` will finally succeed, otherwise it will fail.
+
+To be noted that in client/server builds (i.e. `MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C`) the implementer of the client interface is expected to provide psa_can_do_hash().
#### Support for PSA dispatch in hash operations
@@ -506,7 +519,7 @@
If given an algorithm as an `mbedtls_md_type_t type` (possibly being the `type` field of a `const mbedtls_md_info_t *`):
-* If there is a PSA accelerator for this hash and `psa_can_do_hash(alg)`, call the corresponding PSA function, and if applicable set the engine to `MBEDTLS_MD_ENGINE_PSA`. (Skip this is `MBEDTLS_MD_SOME_PSA` is not defined.)
+* If there is a PSA accelerator/provider for this hash and `md_can_use_psa` succeeds, call the corresponding PSA function, and if applicable set the engine to `MBEDTLS_MD_ENGINE_PSA`. (Skip this is `MBEDTLS_MD_SOME_PSA` is not defined.)
* Otherwise dispatch to the legacy module based on the type as currently done. (Skip this is `MBEDTLS_MD_SOME_LEGACY` is not defined.)
* If no dispatch is possible, return `MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE`.
@@ -522,7 +535,7 @@
> If an algorithm has a legacy implementation, it is also available through PSA.
-When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, this is already the case. When is enabled, we will now make it so as well. Change `include/mbedtls/config_psa.h` accordingly.
+When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, this is already the case. When is enabled, `include/config_adjust_psa_superset_legacy.h` will ensure that PSA configuration is always a superset of what's enabled in legacy.
### MD light optimizations
@@ -557,15 +570,6 @@
PSA has its own HMAC implementation. In builds with both `MBEDTLS_MD_C` and `PSA_WANT_ALG_HMAC` not fully provided by drivers, we should have a single implementation. Replace the one in `md.h` by calls to the PSA driver interface. This will also give mixed-domain modules access to HMAC accelerated directly by a PSA driver (eliminating the need to a HMAC interface in software if all supported hashes have an accelerator that includes HMAC support).
-### Improving support for `MBEDTLS_PSA_CRYPTO_CLIENT`
-
-So far, MD light only dispatches to PSA if an algorithm is available via `MBEDTLS_PSA_CRYPTO_C`, not if it's available via `MBEDTLS_PSA_CRYPTO_CLIENT`. This is acceptable because `MBEDTLS_USE_PSA_CRYPTO` requires `MBEDTLS_PSA_CRYPTO_C`, hence mixed-domain code never invokes PSA.
-
-The architecture can be extended to support `MBEDTLS_PSA_CRYPTO_CLIENT` with a little extra work. Here is an overview of the task breakdown, which should be fleshed up after we've done the first [migration](#migration-to-md-light):
-
-* Compile-time dependencies: instead of checking `defined(MBEDTLS_PSA_CRYPTO_C)`, check `defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)`.
-* Implementers of `MBEDTLS_PSA_CRYPTO_CLIENT` will need to provide `psa_can_do_hash()` (or a more general function `psa_can_do`) alongside `psa_crypto_init()`. Note that at this point, it will become a public interface, hence we won't be able to change it at a whim.
-
### Internal "block cipher" abstraction (previously known as "Cipher light")
#### Definition
diff --git a/framework b/framework
index 523a12d..cab0c5f 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 523a12d05b91301b020e2aa560d9774135e3a801
+Subproject commit cab0c5fe19d5747cb9603552b80ebe64b9c67fdd
diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h
index 3ba987e..331ac9b 100644
--- a/include/mbedtls/config_adjust_legacy_crypto.h
+++ b/include/mbedtls/config_adjust_legacy_crypto.h
@@ -48,6 +48,13 @@
#endif
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
+/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
+ * is defined as well to include all PSA code.
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+#define MBEDTLS_PSA_CRYPTO_CLIENT
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+
/* Auto-enable CIPHER_C when any of the unauthenticated ciphers is builtin
* in PSA. */
#if defined(MBEDTLS_PSA_CRYPTO_C) && \
@@ -158,7 +165,66 @@
#define MBEDTLS_MD_SHA3_512_VIA_PSA
#define MBEDTLS_MD_SOME_PSA
#endif
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+#elif defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+
+#if defined(PSA_WANT_ALG_MD5)
+#define MBEDTLS_MD_CAN_MD5
+#define MBEDTLS_MD_MD5_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA_1)
+#define MBEDTLS_MD_CAN_SHA1
+#define MBEDTLS_MD_SHA1_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA_224)
+#define MBEDTLS_MD_CAN_SHA224
+#define MBEDTLS_MD_SHA224_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA_256)
+#define MBEDTLS_MD_CAN_SHA256
+#define MBEDTLS_MD_SHA256_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA_384)
+#define MBEDTLS_MD_CAN_SHA384
+#define MBEDTLS_MD_SHA384_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA_512)
+#define MBEDTLS_MD_CAN_SHA512
+#define MBEDTLS_MD_SHA512_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_RIPEMD160)
+#define MBEDTLS_MD_CAN_RIPEMD160
+#define MBEDTLS_MD_RIPEMD160_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA3_224)
+#define MBEDTLS_MD_CAN_SHA3_224
+#define MBEDTLS_MD_SHA3_224_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA3_256)
+#define MBEDTLS_MD_CAN_SHA3_256
+#define MBEDTLS_MD_SHA3_256_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA3_384)
+#define MBEDTLS_MD_CAN_SHA3_384
+#define MBEDTLS_MD_SHA3_384_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+#if defined(PSA_WANT_ALG_SHA3_512)
+#define MBEDTLS_MD_CAN_SHA3_512
+#define MBEDTLS_MD_SHA3_512_VIA_PSA
+#define MBEDTLS_MD_SOME_PSA
+#endif
+
+#endif /* !MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */
/* Built-in implementations */
#if defined(MBEDTLS_MD5_C)
@@ -352,13 +418,6 @@
#define MBEDTLS_PK_CAN_ECDSA_SOME
#endif
-/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
- * is defined as well to include all PSA code.
- */
-#if defined(MBEDTLS_PSA_CRYPTO_C)
-#define MBEDTLS_PSA_CRYPTO_CLIENT
-#endif /* MBEDTLS_PSA_CRYPTO_C */
-
/* Helpers to state that each key is supported either on the builtin or PSA side. */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521)
#define MBEDTLS_ECP_HAVE_SECP521R1
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index 424ed4b..e6f5dad 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -108,16 +108,16 @@
*
* This module provides debugging functions.
*/
-#if (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800)
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)
#include <inttypes.h>
#define MBEDTLS_PRINTF_SIZET PRIuPTR
#define MBEDTLS_PRINTF_LONGLONG "I64d"
#else \
- /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
+ /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */
#define MBEDTLS_PRINTF_SIZET "zu"
#define MBEDTLS_PRINTF_LONGLONG "lld"
#endif \
- /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
+ /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */
#if !defined(MBEDTLS_PRINTF_MS_TIME)
#include <inttypes.h>
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index ebc9276..e16f31a 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1807,6 +1807,11 @@
* running handshake hash) only use PSA crypto if
* #MBEDTLS_USE_PSA_CRYPTO is enabled.
*
+ * \note In multithreaded applications, you must also enable
+ * #MBEDTLS_THREADING_C, even if individual TLS contexts are not
+ * shared between threads, unless only one thread ever calls
+ * TLS functions.
+ *
* Uncomment this macro to enable the support for TLS 1.3.
*/
#define MBEDTLS_SSL_PROTO_TLS1_3
@@ -2125,6 +2130,10 @@
* before calling any function from the SSL/TLS, X.509 or PK modules, except
* for the various mbedtls_xxx_init() functions which can be called at any time.
*
+ * \warning In multithreaded applications, you must also enable
+ * #MBEDTLS_THREADING_C, unless only one thread ever calls PSA functions
+ * (`psa_xxx()`), including indirect calls through SSL/TLS, X.509 or PK.
+ *
* \note An important and desirable effect of this option is that it allows
* PK, X.509 and TLS to take advantage of PSA drivers. For example, enabling
* this option is what allows use of drivers for ECDSA, ECDH and EC J-PAKE in
@@ -3211,7 +3220,18 @@
/**
* \def MBEDTLS_PSA_CRYPTO_C
*
- * Enable the Platform Security Architecture cryptography API.
+ * Enable the Platform Security Architecture (PSA) cryptography API.
+ *
+ * \note In multithreaded applications, you must enable #MBEDTLS_THREADING_C,
+ * unless only one thread ever calls `psa_xxx()` functions.
+ * That includes indirect calls, such as:
+ * - performing a TLS handshake if support for TLS 1.3 is enabled;
+ * - using a TLS 1.3 connection;
+ * - indirect calls from PK, X.509 or SSL functions when
+ * #MBEDTLS_USE_PSA_CRYPTO is enabled;
+ * - indirect calls to calculate a hash when #MBEDTLS_MD_C is disabled;
+ * - any other call to a function that requires calling psa_crypto_init()
+ * beforehand.
*
* Module: library/psa_crypto.c
*
@@ -3631,10 +3651,38 @@
* \def MBEDTLS_THREADING_C
*
* Enable the threading abstraction layer.
- * By default Mbed TLS assumes it is used in a non-threaded environment or that
- * contexts are not shared between threads. If you do intend to use contexts
+ *
+ * Traditionally, Mbed TLS assumes it is used in a non-threaded environment or
+ * that contexts are not shared between threads. If you do intend to use contexts
* between threads, you will need to enable this layer to prevent race
- * conditions. See also our Knowledge Base article about threading:
+ * conditions.
+ *
+ * The PSA subsystem has an implicit shared context. Therefore, you must
+ * enable this option if more than one thread may use any part of
+ * Mbed TLS that is implemented on top of the PSA subsystem.
+ *
+ * You must enable this option in multithreaded applications where more than
+ * one thread performs any of the following operations:
+ *
+ * - Any call to a PSA function (`psa_xxx()`).
+ * - Any call to a TLS, X.509 or PK function (`mbedtls_ssl_xxx()`,
+ * `mbedtls_x509_xxx()`, `mbedtls_pkcs7_xxx()`, `mbedtls_pk_xxx()`)
+ * if `MBEDTLS_USE_PSA_CRYPTO` is enabled (regardless of whether individual
+ * TLS, X.509 or PK contexts are shared between threads).
+ * - A TLS 1.3 connection, regardless of the compile-time configuration.
+ * - Any library feature that calculates a hash, if `MBEDTLS_MD_C` is disabled.
+ * As an exception, algorithm-specific low-level modules do not require
+ * threading protection unless the contexts are shared between threads.
+ * - Any library feature that performs symmetric encryption or decryption,
+ * if `MBEDTLS_CIPHER_C` is disabled.
+ * As an exception, algorithm-specific low-level modules do not require
+ * threading protection unless the contexts are shared between threads.
+ * - Any use of a cryptographic context if the same context is used in
+ * multiple threads.
+ * - Any call to a function where the documentation specifies that
+ * psa_crypto_init() must be called prior to that function.
+ *
+ * See also our Knowledge Base article about threading:
* https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading
*
* Module: library/threading.c
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index 85c1197..8e69bc0 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -229,7 +229,7 @@
/**
* \brief Write at most 'len' characters. If no error occurs,
- * the actual amount read is returned.
+ * the actual amount written is returned.
*
* \param ctx Socket
* \param buf The buffer to read from
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 42fffbf..97b0dcb 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1724,7 +1724,16 @@
int MBEDTLS_PRIVATE(early_data_state);
#endif
- unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
+ /** Multipurpose field.
+ *
+ * - DTLS: records with a bad MAC received.
+ * - TLS: accumulated length of handshake fragments (up to \c in_hslen).
+ *
+ * This field is multipurpose in order to preserve the ABI in the
+ * Mbed TLS 3.6 LTS branch. Until 3.6.2, it was only used in DTLS
+ * and called `badmac_seen`.
+ */
+ unsigned MBEDTLS_PRIVATE(badmac_seen_or_in_hsfraglen);
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/** Callback to customize X.509 certificate chain verification */
@@ -4440,6 +4449,10 @@
* with \c mbedtls_ssl_read()), not handshake messages.
* With DTLS, this affects both ApplicationData and handshake.
*
+ * \note Defragmentation of TLS handshake messages is supported
+ * with some limitations. See the documentation of
+ * mbedtls_ssl_handshake() for details.
+ *
* \note This sets the maximum length for a record's payload,
* excluding record overhead that will be added to it, see
* \c mbedtls_ssl_get_record_expansion().
@@ -4970,6 +4983,24 @@
* if a negotiation involving TLS 1.3 takes place (this may
* be the case even if TLS 1.3 is offered but eventually
* not selected).
+ *
+ * \note In TLS, reception of fragmented handshake messages is
+ * supported with some limitations (those limitations do
+ * not apply to DTLS, where defragmentation is fully
+ * supported):
+ * - On an Mbed TLS server that only accepts TLS 1.2,
+ * the initial ClientHello message must not be fragmented.
+ * A TLS 1.2 ClientHello may be fragmented if the server
+ * also accepts TLS 1.3 connections (meaning
+ * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the
+ * accepted versions have not been restricted with
+ * mbedtls_ssl_conf_max_tls_version() or the like).
+ * - The first fragment of a handshake message must be
+ * at least 4 bytes long.
+ * - Non-handshake records must not be interleaved between
+ * the fragments of a handshake message. (This is permitted
+ * in TLS 1.2 but not in TLS 1.3, but Mbed TLS rejects it
+ * even in TLS 1.2.)
*/
int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl);
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index f48c087..a046ba5 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -583,6 +583,35 @@
/** @} */
+/** \defgroup psa_crypto_client Functions defined by a client provider
+ *
+ * The functions in this group are meant to be implemented by providers of
+ * the PSA Crypto client interface. They are provided by the library when
+ * #MBEDTLS_PSA_CRYPTO_C is enabled.
+ *
+ * \note All functions in this group are experimental, as using
+ * alternative client interface providers is experimental.
+ *
+ * @{
+ */
+
+/** Check if PSA is capable of handling the specified hash algorithm.
+ *
+ * This means that PSA core was built with the corresponding PSA_WANT_ALG_xxx
+ * set and that psa_crypto_init has already been called.
+ *
+ * \note When using Mbed TLS version of PSA core (i.e. MBEDTLS_PSA_CRYPTO_C is
+ * set) for now this function only checks the state of the driver
+ * subsystem, not the algorithm. This might be improved in the future.
+ *
+ * \param hash_alg The hash algorithm.
+ *
+ * \return 1 if the PSA can handle \p hash_alg, 0 otherwise.
+ */
+int psa_can_do_hash(psa_algorithm_t hash_alg);
+
+/**@}*/
+
/** \addtogroup crypto_types
* @{
*/
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index df0ee50..c3c0770 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -25,18 +25,6 @@
#endif
/**
- * Tell if PSA is ready for this hash.
- *
- * \note For now, only checks the state of the driver subsystem,
- * not the algorithm. Might do more in the future.
- *
- * \param hash_alg The hash algorithm (ignored for now).
- *
- * \return 1 if the driver subsytem is ready, 0 otherwise.
- */
-int psa_can_do_hash(psa_algorithm_t hash_alg);
-
-/**
* Tell if PSA is ready for this cipher.
*
* \note For now, only checks the state of the driver subsystem,
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 9850d8c..358c7a2 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -35,9 +35,9 @@
"Empty user key ID range");
MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN < PSA_KEY_ID_VENDOR_MAX,
"Empty vendor key ID range");
-MBEDTLS_STATIC_ASSERT(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN < MBEDTLS_PSA_KEY_ID_BUILTIN_MAX,
+MBEDTLS_STATIC_ASSERT(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX,
"Empty builtin key ID range");
-MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MIN < PSA_KEY_ID_VOLATILE_MAX,
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MIN <= PSA_KEY_ID_VOLATILE_MAX,
"Empty volatile key ID range");
MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MAX < PSA_KEY_ID_VENDOR_MIN ||
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 7495ae3..348c319 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1830,10 +1830,11 @@
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl);
-void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl);
+void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl);
+void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl);
+void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl);
void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform);
-void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial);
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index dcda1d3..4adaf7d 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -25,6 +25,7 @@
#include "constant_time_internal.h"
#include "mbedtls/constant_time.h"
+#include <limits.h>
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -3220,19 +3221,34 @@
int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
{
- if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
- ssl->in_msglen));
- return MBEDTLS_ERR_SSL_INVALID_RECORD;
- }
+ if (ssl->badmac_seen_or_in_hsfraglen == 0) {
+ /* The handshake message must at least include the header.
+ * We may not have the full message yet in case of fragmentation.
+ * To simplify the code, we insist on having the header (and in
+ * particular the handshake message length) in the first
+ * fragment. */
+ if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen));
+ return MBEDTLS_ERR_SSL_INVALID_RECORD;
+ }
- ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
+ ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
+ }
MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
" %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %"
MBEDTLS_PRINTF_SIZET,
ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen));
+ if (ssl->transform_in != NULL) {
+ MBEDTLS_SSL_DEBUG_MSG(4, ("decrypted handshake message:"
+ " iv-buf=%d hdr-buf=%d hdr-buf=%d",
+ (int) (ssl->in_iv - ssl->in_buf),
+ (int) (ssl->in_hdr - ssl->in_buf),
+ (int) (ssl->in_msg - ssl->in_buf)));
+ }
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3292,10 +3308,103 @@
}
} else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
- /* With TLS we don't handle fragmentation (for now) */
- if (ssl->in_msglen < ssl->in_hslen) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("TLS handshake fragmentation not supported"));
- return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ {
+ unsigned char *const reassembled_record_start =
+ ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
+ unsigned char *const payload_start =
+ reassembled_record_start + mbedtls_ssl_in_hdr_len(ssl);
+ unsigned char *payload_end = payload_start + ssl->badmac_seen_or_in_hsfraglen;
+ /* How many more bytes we want to have a complete handshake message. */
+ const size_t hs_remain = ssl->in_hslen - ssl->badmac_seen_or_in_hsfraglen;
+ /* How many bytes of the current record are part of the first
+ * handshake message. There may be more handshake messages (possibly
+ * incomplete) in the same record; if so, we leave them after the
+ * current record, and ssl_consume_current_message() will take
+ * care of consuming the next handshake message. */
+ const size_t hs_this_fragment_len =
+ ssl->in_msglen > hs_remain ? hs_remain : ssl->in_msglen;
+ (void) hs_this_fragment_len;
+
+ MBEDTLS_SSL_DEBUG_MSG(3,
+ ("%s handshake fragment: %" MBEDTLS_PRINTF_SIZET
+ ", %u..%u of %" MBEDTLS_PRINTF_SIZET,
+ (ssl->badmac_seen_or_in_hsfraglen != 0 ?
+ "subsequent" :
+ hs_this_fragment_len == ssl->in_hslen ?
+ "sole" :
+ "initial"),
+ ssl->in_msglen,
+ ssl->badmac_seen_or_in_hsfraglen,
+ ssl->badmac_seen_or_in_hsfraglen +
+ (unsigned) hs_this_fragment_len,
+ ssl->in_hslen));
+
+ /* Move the received handshake fragment to have the whole message
+ * (at least the part received so far) in a single segment at a
+ * known offset in the input buffer.
+ * - When receiving a non-initial handshake fragment, append it to
+ * the initial segment.
+ * - Even the initial handshake fragment is moved, if it was
+ * encrypted with an explicit IV: decryption leaves the payload
+ * after the explicit IV, but here we move it to start where the
+ * IV was.
+ */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t const in_buf_len = ssl->in_buf_len;
+#else
+ size_t const in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+ if (payload_end + ssl->in_msglen > ssl->in_buf + in_buf_len) {
+ MBEDTLS_SSL_DEBUG_MSG(1,
+ ("Shouldn't happen: no room to move handshake fragment %"
+ MBEDTLS_PRINTF_SIZET " from %p to %p (buf=%p len=%"
+ MBEDTLS_PRINTF_SIZET ")",
+ ssl->in_msglen,
+ (void *) ssl->in_msg, (void *) payload_end,
+ (void *) ssl->in_buf, in_buf_len));
+ return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ }
+ memmove(payload_end, ssl->in_msg, ssl->in_msglen);
+
+ ssl->badmac_seen_or_in_hsfraglen += (unsigned) ssl->in_msglen;
+ payload_end += ssl->in_msglen;
+
+ if (ssl->badmac_seen_or_in_hsfraglen < ssl->in_hslen) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("Prepare: waiting for more handshake fragments "
+ "%u/%" MBEDTLS_PRINTF_SIZET,
+ ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen));
+ ssl->in_hdr = payload_end;
+ ssl->in_msglen = 0;
+ mbedtls_ssl_update_in_pointers(ssl);
+ return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
+ } else {
+ ssl->in_msglen = ssl->badmac_seen_or_in_hsfraglen;
+ ssl->badmac_seen_or_in_hsfraglen = 0;
+ ssl->in_hdr = reassembled_record_start;
+ mbedtls_ssl_update_in_pointers(ssl);
+
+ /* Update the record length in the fully reassembled record */
+ if (ssl->in_msglen > 0xffff) {
+ MBEDTLS_SSL_DEBUG_MSG(1,
+ ("Shouldn't happen: in_msglen=%"
+ MBEDTLS_PRINTF_SIZET " > 0xffff",
+ ssl->in_msglen));
+ return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ }
+ MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0);
+
+ size_t record_len = mbedtls_ssl_in_hdr_len(ssl) + ssl->in_msglen;
+ (void) record_len;
+ MBEDTLS_SSL_DEBUG_BUF(4, "reassembled record",
+ ssl->in_hdr, record_len);
+ if (ssl->in_hslen < ssl->in_msglen) {
+ MBEDTLS_SSL_DEBUG_MSG(3,
+ ("More handshake messages in the record: "
+ "%" MBEDTLS_PRINTF_SIZET " + %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_hslen,
+ ssl->in_msglen - ssl->in_hslen));
+ }
+ }
}
return 0;
@@ -4640,6 +4749,14 @@
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
+ if (ssl->badmac_seen_or_in_hsfraglen != 0) {
+ /* Not all handshake fragments have arrived, do not consume. */
+ MBEDTLS_SSL_DEBUG_MSG(3, ("Consume: waiting for more handshake fragments "
+ "%u/%" MBEDTLS_PRINTF_SIZET,
+ ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen));
+ return 0;
+ }
+
/*
* Get next Handshake message in the current record
*/
@@ -4665,6 +4782,7 @@
ssl->in_msglen -= ssl->in_hslen;
memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen,
ssl->in_msglen);
+ MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0);
MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record",
ssl->in_msg, ssl->in_msglen);
@@ -4967,10 +5085,12 @@
return ret;
}
- if (ssl->conf->badmac_limit != 0 &&
- ++ssl->badmac_seen >= ssl->conf->badmac_limit) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC"));
- return MBEDTLS_ERR_SSL_INVALID_MAC;
+ if (ssl->conf->badmac_limit != 0) {
+ ++ssl->badmac_seen_or_in_hsfraglen;
+ if (ssl->badmac_seen_or_in_hsfraglen >= ssl->conf->badmac_limit) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC"));
+ return MBEDTLS_ERR_SSL_INVALID_MAC;
+ }
}
/* As above, invalid records cause
@@ -5028,6 +5148,18 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* If we're in the middle of a fragmented TLS handshake message,
+ * we don't accept any other message type. For TLS 1.3, the spec forbids
+ * interleaving other message types between handshake fragments. For TLS
+ * 1.2, the spec does not forbid it but we do. */
+ if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM &&
+ ssl->badmac_seen_or_in_hsfraglen != 0 &&
+ ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("non-handshake message in the middle"
+ " of a fragmented handshake message"));
+ return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+ }
+
/*
* Handle particular types of records
*/
@@ -5339,7 +5471,7 @@
} else
#endif
{
- ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
+ ssl->in_ctr = ssl->in_buf;
ssl->in_len = ssl->in_hdr + 3;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl->in_cid = ssl->in_len;
@@ -5355,24 +5487,35 @@
* Setup an SSL context
*/
-void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl)
+void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl)
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+ ssl->in_hdr = ssl->in_buf;
+ } else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ ssl->in_hdr = ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
+ }
+
+ /* Derive other internal pointers. */
+ mbedtls_ssl_update_in_pointers(ssl);
+}
+
+void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl)
{
/* Set the incoming and outgoing record pointers. */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
ssl->out_hdr = ssl->out_buf;
- ssl->in_hdr = ssl->in_buf;
} else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
{
ssl->out_ctr = ssl->out_buf;
- ssl->out_hdr = ssl->out_buf + 8;
- ssl->in_hdr = ssl->in_buf + 8;
+ ssl->out_hdr = ssl->out_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
}
-
/* Derive other internal pointers. */
mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */);
- mbedtls_ssl_update_in_pointers(ssl);
}
/*
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index c773365..7f74248 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -344,12 +344,13 @@
size_t out_buf_new_len)
{
int modified = 0;
- size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
+ size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0, hdr_in = 0;
size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
if (ssl->in_buf != NULL) {
written_in = ssl->in_msg - ssl->in_buf;
iv_offset_in = ssl->in_iv - ssl->in_buf;
len_offset_in = ssl->in_len - ssl->in_buf;
+ hdr_in = ssl->in_hdr - ssl->in_buf;
if (downsizing ?
ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
ssl->in_buf_len < in_buf_new_len) {
@@ -381,7 +382,10 @@
}
if (modified) {
/* Update pointers here to avoid doing it twice. */
- mbedtls_ssl_reset_in_out_pointers(ssl);
+ ssl->in_hdr = ssl->in_buf + hdr_in;
+ mbedtls_ssl_update_in_pointers(ssl);
+ mbedtls_ssl_reset_out_pointers(ssl);
+
/* Fields below might not be properly updated with record
* splitting or with CID, so they are manually updated here. */
ssl->out_msg = ssl->out_buf + written_out;
@@ -1409,7 +1413,8 @@
goto error;
}
- mbedtls_ssl_reset_in_out_pointers(ssl);
+ mbedtls_ssl_reset_in_pointers(ssl);
+ mbedtls_ssl_reset_out_pointers(ssl);
#if defined(MBEDTLS_SSL_DTLS_SRTP)
memset(&ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info));
@@ -1474,7 +1479,8 @@
/* Cancel any possibly running timer */
mbedtls_ssl_set_timer(ssl, 0);
- mbedtls_ssl_reset_in_out_pointers(ssl);
+ mbedtls_ssl_reset_in_pointers(ssl);
+ mbedtls_ssl_reset_out_pointers(ssl);
/* Reset incoming message parsing */
ssl->in_offt = NULL;
@@ -1485,6 +1491,12 @@
ssl->keep_current_message = 0;
ssl->transform_in = NULL;
+ /* TLS: reset in_hsfraglen, which is part of message parsing.
+ * DTLS: on a client reconnect, don't reset badmac_seen. */
+ if (!partial) {
+ ssl->badmac_seen_or_in_hsfraglen = 0;
+ }
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
ssl->next_record_offset = 0;
ssl->in_epoch = 0;
@@ -5014,7 +5026,7 @@
* uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value
* uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use
* // fields from ssl_context
- * uint32 badmac_seen; // DTLS: number of records with failing MAC
+ * uint32 badmac_seen_or_in_hsfraglen; // DTLS: number of records with failing MAC
* uint64 in_window_top; // DTLS: last validated record seq_num
* uint64 in_window; // DTLS: bitmask for replay protection
* uint8 disable_datagram_packing; // DTLS: only one record per datagram
@@ -5156,7 +5168,7 @@
*/
used += 4;
if (used <= buf_len) {
- MBEDTLS_PUT_UINT32_BE(ssl->badmac_seen, p, 0);
+ MBEDTLS_PUT_UINT32_BE(ssl->badmac_seen_or_in_hsfraglen, p, 0);
p += 4;
}
@@ -5386,7 +5398,7 @@
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- ssl->badmac_seen = MBEDTLS_GET_UINT32_BE(p, 0);
+ ssl->badmac_seen_or_in_hsfraglen = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 03722ac..67df428 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -1057,28 +1057,6 @@
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}
- {
- size_t handshake_len = MBEDTLS_GET_UINT24_BE(buf, 1);
- MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake len.: %u",
- (unsigned) handshake_len));
-
- /* The record layer has a record size limit of 2^14 - 1 and
- * fragmentation is not supported, so buf[1] should be zero. */
- if (buf[1] != 0) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != 0",
- (unsigned) buf[1]));
- return MBEDTLS_ERR_SSL_DECODE_ERROR;
- }
-
- /* We don't support fragmentation of ClientHello (yet?) */
- if (msg_len != mbedtls_ssl_hs_hdr_len(ssl) + handshake_len) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != %u + %u",
- (unsigned) msg_len,
- (unsigned) mbedtls_ssl_hs_hdr_len(ssl),
- (unsigned) handshake_len));
- return MBEDTLS_ERR_SSL_DECODE_ERROR;
- }
- }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
index 51e8781..b9a0fe8 100644
--- a/programs/ssl/ssl_context_info.c
+++ b/programs/ssl/ssl_context_info.c
@@ -743,6 +743,13 @@
* uint8 alpn_chosen_len;
* uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
*
+ * Note: In the mbedtls_ssl_context structure, badmac_seen is called
+ * badmac_seen_or_in_hsfraglen since Mbed TLS 3.6.2. The field contains
+ * the badmac_seen value in DTLS, and a handshake parsing intermediate
+ * value in non-DTLS TLS. The value is only meaningful for DTLS and should
+ * not be saved in non-DTLS TLS, so in this program, the context info file
+ * filed remains badmac_seen.
+ *
* /p ssl pointer to serialized session
* /p len number of bytes in the buffer
*/
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index 9614333..d7fe80f 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -243,8 +243,8 @@
* - free the provided PK context and re-initilize it as an opaque PK context
* wrapping the PSA key imported in the above step.
*
- * \param[in/out] pk On input the non-opaque PK context which contains the
- * key to be wrapped. On output the re-initialized PK
+ * \param[in,out] pk On input, the non-opaque PK context which contains the
+ * key to be wrapped. On output, the re-initialized PK
* context which represents the opaque version of the one
* provided as input.
* \param[in] psa_alg The primary algorithm that will be associated to the
diff --git a/scripts/make_generated_files.bat b/scripts/make_generated_files.bat
index 0c15c38..75c2de0 100644
--- a/scripts/make_generated_files.bat
+++ b/scripts/make_generated_files.bat
@@ -28,4 +28,5 @@
python framework\scripts\generate_psa_tests.py || exit /b 1
python framework\scripts\generate_test_keys.py --output framework\tests\include\test\test_keys.h || exit /b 1
python framework\scripts\generate_test_cert_macros.py --output tests\src\test_certs.h || exit /b 1
+python framework\scripts\generate_tls_handshake_tests.py || exit /b 1
python framework\scripts\generate_tls13_compat_tests.py || exit /b 1
diff --git a/tests/.gitignore b/tests/.gitignore
index 0c58875..10eb873 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -18,6 +18,7 @@
###START_GENERATED_FILES###
# Generated source files
+/opt-testcases/handshake-generated.sh
/opt-testcases/tls13-compat.sh
/suites/*.generated.data
/suites/test_suite_config.mbedtls_boolean.data
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 98973c9..aa8ae23 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -124,6 +124,24 @@
# change too often in ways that don't affect the result
# ((un)commenting some options).
)
+
+ add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_SOURCE_DIR}/opt-testcases/handshake-generated.sh
+ WORKING_DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ COMMAND
+ "${MBEDTLS_PYTHON_EXECUTABLE}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_tls_handshake_tests.py"
+ DEPENDS
+ ${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/mbedtls_framework/tls_test_case.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_tls_handshake_tests.py
+ )
+ add_custom_target(handshake-generated.sh
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/opt-testcases/handshake-generated.sh)
+ set_target_properties(handshake-generated.sh PROPERTIES EXCLUDE_FROM_ALL NO)
+ add_dependencies(${ssl_opt_target} handshake-generated.sh)
+
add_custom_command(
OUTPUT
${ecp_generated_data_files}
diff --git a/tests/Makefile b/tests/Makefile
index dd1af15..1fa5dd1 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -58,6 +58,13 @@
# Generated files needed to (fully) run ssl-opt.sh
.PHONY: ssl-opt
+opt-testcases/handshake-generated.sh: ../framework/scripts/mbedtls_framework/tls_test_case.py
+opt-testcases/handshake-generated.sh: ../framework/scripts/generate_tls_handshake_tests.py
+ echo " Gen $@"
+ $(PYTHON) ../framework/scripts/generate_tls_handshake_tests.py -o $@
+GENERATED_FILES += opt-testcases/handshake-generated.sh
+ssl-opt: opt-testcases/handshake-generated.sh
+
opt-testcases/tls13-compat.sh: ../framework/scripts/generate_tls13_compat_tests.py
echo " Gen $@"
$(PYTHON) ../framework/scripts/generate_tls13_compat_tests.py -o $@
diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh
index b61c5ac..088f16f 100755
--- a/tests/scripts/check-generated-files.sh
+++ b/tests/scripts/check-generated-files.sh
@@ -135,6 +135,7 @@
check scripts/generate_query_config.pl programs/test/query_config.c
check scripts/generate_features.pl library/version_features.c
check framework/scripts/generate_ssl_debug_helpers.py library/ssl_debug_helpers_generated.c
+ check framework/scripts/generate_tls_handshake_tests.py tests/opt-testcases/handshake-generated.sh
check framework/scripts/generate_tls13_compat_tests.py tests/opt-testcases/tls13-compat.sh
check framework/scripts/generate_test_cert_macros.py tests/src/test_certs.h
# generate_visualc_files enumerates source files (library/*.c). It doesn't
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 0376018..fdbe0a9 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -14457,6 +14457,20 @@
-c "Handshake was completed" \
-s "dumping .client hello, compression. (2 bytes)"
+# Handshake defragmentation testing
+
+# Most test cases are in opt-testcases/handshake-generated.sh
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_certificate_authentication
+run_test "Handshake defragmentation on server: len=32, TLS 1.2 ClientHello" \
+ "$P_SRV debug_level=4 force_version=tls12 auth_mode=required" \
+ "$O_NEXT_CLI -tls1_2 -split_send_frag 32 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
+ 1 \
+ -s "The SSL configuration is tls12 only" \
+ -s "bad client hello message" \
+ -s "SSL - A message could not be parsed due to a syntactic error"
+
# Test heap memory usage after handshake
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_MEMORY_DEBUG
diff --git a/tests/suites/test_suite_debug.data b/tests/suites/test_suite_debug.data
index 8b17eb8..46b6be4 100644
--- a/tests/suites/test_suite_debug.data
+++ b/tests/suites/test_suite_debug.data
@@ -1,3 +1,12 @@
+printf "%" MBEDTLS_PRINTF_SIZET, 0
+printf_int_expr:PRINTF_SIZET:sizeof(size_t):0:"0"
+
+printf "%" MBEDTLS_PRINTF_LONGLONG, 0
+printf_int_expr:PRINTF_LONGLONG:sizeof(long long):0:"0"
+
+printf "%" MBEDTLS_PRINTF_MS_TIME, 0
+printf_int_expr:PRINTF_MS_TIME:sizeof(mbedtls_ms_time_t):0:"0"
+
Debug print msg (threshold 1, level 0)
debug_print_msg_threshold:1:0:"MyFile":999:"MyFile(0999)\: Text message, 2 == 2\n"
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index 878ceed..9e53107 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -4,11 +4,34 @@
#include "mbedtls/pk.h"
#include <test/ssl_helpers.h>
+#if defined(_WIN32)
+# include <stdlib.h>
+# include <crtdbg.h>
+#endif
+
+// Dummy type for builds without MBEDTLS_HAVE_TIME
+#if !defined(MBEDTLS_HAVE_TIME)
+typedef int64_t mbedtls_ms_time_t;
+#endif
+
+typedef enum {
+ PRINTF_SIZET,
+ PRINTF_LONGLONG,
+ PRINTF_MS_TIME,
+} printf_format_indicator_t;
+
+const char *const printf_formats[] = {
+ [PRINTF_SIZET] = "%" MBEDTLS_PRINTF_SIZET,
+ [PRINTF_LONGLONG] = "%" MBEDTLS_PRINTF_LONGLONG,
+ [PRINTF_MS_TIME] = "%" MBEDTLS_PRINTF_MS_TIME,
+};
+
struct buffer_data {
char buf[2000];
char *ptr;
};
+#if defined(MBEDTLS_SSL_TLS_C)
static void string_debug(void *data, int level, const char *file, int line, const char *str)
{
struct buffer_data *buffer = (struct buffer_data *) data;
@@ -44,14 +67,77 @@
buffer->ptr = p;
}
+#endif /* MBEDTLS_SSL_TLS_C */
+
+#if defined(_WIN32)
+static void noop_invalid_parameter_handler(
+ const wchar_t *expression,
+ const wchar_t *function,
+ const wchar_t *file,
+ unsigned int line,
+ uintptr_t pReserved)
+{
+ (void) expression;
+ (void) function;
+ (void) file;
+ (void) line;
+ (void) pReserved;
+}
+#endif /* _WIN32 */
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_DEBUG_C:MBEDTLS_SSL_TLS_C
+ * depends_on:MBEDTLS_DEBUG_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
+void printf_int_expr(int format_indicator, intmax_t sizeof_x, intmax_t x, char *result)
+{
+#if defined(_WIN32)
+ /* Windows treats any invalid format specifiers passsed to the CRT as fatal assertion failures.
+ Disable this behaviour temporarily, so the rest of the test cases can complete. */
+ _invalid_parameter_handler saved_handler =
+ _set_invalid_parameter_handler(noop_invalid_parameter_handler);
+
+ // Disable assertion pop-up window in Debug builds
+ int saved_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_REPORT_MODE);
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+#endif
+
+ const char *format = printf_formats[format_indicator];
+ char *output = NULL;
+ const size_t n = strlen(result);
+
+ /* Nominal case: buffer just large enough */
+ TEST_CALLOC(output, n + 1);
+ if ((size_t) sizeof_x <= sizeof(int)) { // Any smaller integers would be promoted to an int due to calling a vararg function
+ TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, (int) x));
+ } else if (sizeof_x == sizeof(long)) {
+ TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, (long) x));
+ } else if (sizeof_x == sizeof(long long)) {
+ TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, (long long) x));
+ } else {
+ TEST_FAIL(
+ "sizeof_x <= sizeof(int) || sizeof_x == sizeof(long) || sizeof_x == sizeof(long long)");
+ }
+ TEST_MEMORY_COMPARE(result, n + 1, output, n + 1);
+
+exit:
+ mbedtls_free(output);
+ output = NULL;
+
+#if defined(_WIN32)
+ // Restore default Windows behaviour
+ _set_invalid_parameter_handler(saved_handler);
+ _CrtSetReportMode(_CRT_ASSERT, saved_report_mode);
+ (void) saved_report_mode;
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C */
void debug_print_msg_threshold(int threshold, int level, char *file,
int line, char *result_str)
{
@@ -90,7 +176,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C */
void mbedtls_debug_print_ret(char *file, int line, char *text, int value,
char *result_str)
{
@@ -126,7 +212,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C */
void mbedtls_debug_print_buf(char *file, int line, char *text,
data_t *data, char *result_str)
{
@@ -162,7 +248,7 @@
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
void mbedtls_debug_print_crt(char *crt_file, char *file, int line,
char *prefix, char *result_str)
{
@@ -202,7 +288,7 @@
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_BIGNUM_C */
void mbedtls_debug_print_mpi(char *value, char *file, int line,
char *prefix, char *result_str)
{
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 4e62154..4497d04 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -420,7 +420,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */
void md_psa_dynamic_dispatch(int md_type, int pre_psa_ret, int post_psa_engine)
{
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);