Merge pull request #8664 from valeriosetti/issue7764
Conversion function from ecp group to PSA curve
diff --git a/ChangeLog.d/8060.txt b/ChangeLog.d/8060.txt
deleted file mode 100644
index a5fd93c..0000000
--- a/ChangeLog.d/8060.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Features
- * The CCM and GCM modules no longer depend on MBEDTLS_CIPHER_C. People who
- use CCM and GCM but don't need the Cipher API can now disable
- MBEDTLS_CIPHER_C in order to save code size.
diff --git a/ChangeLog.d/8357.txt b/ChangeLog.d/8357.txt
deleted file mode 100644
index 9cae396..0000000
--- a/ChangeLog.d/8357.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Features
- * It is now possible to have AEADs support (CCM, GCM and ChaChaPoly) without
- MBEDTLS_CIPHER_C. This holds both for the builtin suport (MBEDTLS_CCM_C,
- MBEDTLS_GCM_C and MBEDTLS_CHACHAPOLY_C) as well as the PSA one
- (PSA_WANT_ALG_CCM, PSA_WANT_ALG_GCM, PSA_WANT_ALG_CHACHA20_POLY1305).
- On the PSA side this means that it is possible to enable
- MBEDTLS_PSA_CRYPTO_C without MBEDTLS_CIPHER_C if none of the
- non-authenticated ciphers is enabled.
diff --git a/ChangeLog.d/8358.txt b/ChangeLog.d/8358.txt
deleted file mode 100644
index 70b795a..0000000
--- a/ChangeLog.d/8358.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Features
- * If a cipher or AEAD mechanism has a PSA driver, you can now build the
- library without the corresponding built-in implementation. See
- docs/driver-only-builds.md for full details and current limitations.
- * It is possible to disable MBEDTLS_CIPHER_C in some circumstances, please
- see docs/driver-only-builds.md for full details and current limitations.
- * The CTR_DRBG module will now use AES from a PSA driver if MBEDTLS_AES_C is
- disabled. This requires PSA_WANT_ALG_ECB_NO_PADDING in addition to
- MBEDTLS_PSA_CRYPTO_C and PSA_WANT_KEY_TYPE_AES.
diff --git a/ChangeLog.d/add-record-size-limit-extension-support.txt b/ChangeLog.d/add-record-size-limit-extension-support.txt
new file mode 100644
index 0000000..3562b85
--- /dev/null
+++ b/ChangeLog.d/add-record-size-limit-extension-support.txt
@@ -0,0 +1,5 @@
+Features
+ * Add support for record size limit extension as defined by RFC 8449
+ and configured with MBEDTLS_SSL_RECORD_SIZE_LIMIT.
+ Application data sent and received will be fragmented according to
+ Record size limits negotiated during handshake.
diff --git a/ChangeLog.d/ctr-perf.txt b/ChangeLog.d/ctr-perf.txt
new file mode 100644
index 0000000..bc04080
--- /dev/null
+++ b/ChangeLog.d/ctr-perf.txt
@@ -0,0 +1,3 @@
+Features
+ * Improve performance of AES-GCM, AES-CTR and CTR-DRBG when
+ hardware accelerated AES is not present (around 13-23% on 64-bit Arm).
diff --git a/ChangeLog.d/driver-only-cipher.txt b/ChangeLog.d/driver-only-cipher.txt
new file mode 100644
index 0000000..331b2f9
--- /dev/null
+++ b/ChangeLog.d/driver-only-cipher.txt
@@ -0,0 +1,11 @@
+Features
+ * If a cipher or AEAD mechanism has a PSA driver, you can now build the
+ library without the corresponding built-in implementation. Generally
+ speaking that requires both the key type and algorithm to be accelerated
+ or they'll both be built in. However, for CCM and GCM the built-in
+ implementation is able to take advantage of a driver that only
+ accelerates the key type (that is, the block cipher primitive). See
+ docs/driver-only-builds.md for full details and current limitations.
+ * The CTR_DRBG module will now use AES from a PSA driver if MBEDTLS_AES_C is
+ disabled. This requires PSA_WANT_ALG_ECB_NO_PADDING in addition to
+ MBEDTLS_PSA_CRYPTO_C and PSA_WANT_KEY_TYPE_AES.
diff --git a/ChangeLog.d/fix-tls-SuiteB.txt b/ChangeLog.d/fix-tls-SuiteB.txt
new file mode 100644
index 0000000..0be753a
--- /dev/null
+++ b/ChangeLog.d/fix-tls-SuiteB.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Remove accidental introduction of RSA signature algorithms
+ in TLS Suite B Profile. Fixes #8221.
diff --git a/ChangeLog.d/fix-tls13-server-min-version-check.txt b/ChangeLog.d/fix-tls13-server-min-version-check.txt
new file mode 100644
index 0000000..258ec6d
--- /dev/null
+++ b/ChangeLog.d/fix-tls13-server-min-version-check.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Fix TLS server accepting TLS 1.2 handshake while TLS 1.2
+ is disabled at runtime. Fixes #8593.
diff --git a/ChangeLog.d/no-cipher.txt b/ChangeLog.d/no-cipher.txt
new file mode 100644
index 0000000..87f2f6d
--- /dev/null
+++ b/ChangeLog.d/no-cipher.txt
@@ -0,0 +1,9 @@
+Features
+ * Fewer modules depend on MBEDTLS_CIPHER_C, making it possible to save code
+ size by disabling it in more circumstances. In particular, the CCM and
+ GCM modules no longer depend on MBEDTLS_CIPHER_C. Also,
+ MBEDTLS_PSA_CRYPTO can now be enabled without MBEDTLS_CIPHER_C if all
+ unauthenticated (non-AEAD) ciphers are disabled, or if they're all
+ fully provided by drivers. See docs/driver-only-builds.md for full
+ details and current limitations; in particular, NIST_KW and PKCS5/PKCS12
+ decryption still unconditionally depend on MBEDTLS_CIPHER_C.
diff --git a/docs/architecture/psa-migration/md-cipher-dispatch.md b/docs/architecture/psa-migration/md-cipher-dispatch.md
index 430b0ca..eda65a3 100644
--- a/docs/architecture/psa-migration/md-cipher-dispatch.md
+++ b/docs/architecture/psa-migration/md-cipher-dispatch.md
@@ -494,7 +494,7 @@
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.
-As a starting point, return 1 if PSA crypto has been initialized. This will be refined later (to return 1 if the [accelerator subsystem](https://github.com/Mbed-TLS/mbedtls/issues/6007) has been initialized).
+As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
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`.
@@ -514,7 +514,7 @@
#### Error code conversion
-After calling a PSA function, call `mbedtls_md_error_from_psa` to convert its status code.
+After calling a PSA function, MD light calls `mbedtls_md_error_from_psa` to convert its status code.
### Support all legacy algorithms in PSA
@@ -566,14 +566,15 @@
* 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 (Cipher light)
+### Internal "block cipher" abstraction (previously known as "Cipher light")
#### Definition
-The new module is automatically enabled in `build_info.h` by modules that need
-it, namely: CCM, GCM, only when `CIPHER_C` is not available. Note: CCM and GCM
-currently depend on the full `CIPHER_C` (enforced by `check_config.h`); this
-hard dependency would be replaced by the above auto-enablement.
+The new module is automatically enabled in `config_adjust_legacy_crypto.h` by modules that need
+it (namely: CCM, GCM) only when `CIPHER_C` is not available, or the new module
+is needed for PSA dispatch (see next section). Note: CCM and GCM currently
+depend on the full `CIPHER_C` (enforced by `check_config.h`); this hard
+dependency would be replaced by the above auto-enablement.
The following API functions are offered:
```
@@ -593,6 +594,23 @@
an `mbedtls_cipher_id_t` in the `setup()` function, because that's how they're
identifed by callers (GCM/CCM).
-#### Cipher light dual dispatch
+#### Block cipher dual dispatch
-This is likely to come in the future, but has not been defined yet.
+Support for dual dispatch in the new internal module `block_cipher` is extremely similar to that in MD light.
+
+A block cipher context contains either a legacy module's context (AES, ARIA, Camellia) or a PSA key identifier; it has a field indicating which one is in use. All fields are private.
+
+The `engine` field is almost redundant with knowledge about `type`. However, when an algorithm is available both via a legacy module and a PSA accelerator, we will choose based on the runtime availability of the accelerator when the context is set up. This choice needs to be recorded in the context structure.
+
+Support is determined at runtime using the new internal function
+```
+int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg);
+```
+
+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. As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
+
+Each function in the module needs to know whether to dispatch via PSA or legacy. All functions consult the context's `engine` field, except `setup()` which will set it according to the key type and the return value of `psa_can_do_cipher()` as discussed above.
+
+Note that this assumes that an operation that has been started via PSA can be completed. This implies that `mbedtls_psa_crypto_free` must not be called while an operation using PSA is in progress.
+
+After calling a PSA function, `block_cipher` functions call `mbedtls_cipher_error_from_psa` to convert its status code.
diff --git a/docs/driver-only-builds.md b/docs/driver-only-builds.md
index f085471..f59420e 100644
--- a/docs/driver-only-builds.md
+++ b/docs/driver-only-builds.md
@@ -16,6 +16,7 @@
In order to have some mechanism provided only by a driver, you'll want
the following compile-time configuration options enabled:
+
- `MBEDTLS_PSA_CRYPTO_C` (enabled by default) - this enables PSA Crypto.
- `MBEDTLS_USE_PSA_CRYPTO` (disabled by default) - this makes PK, X.509 and
TLS use PSA Crypto. You need to enable this if you're using PK, X.509 or TLS
@@ -28,6 +29,7 @@
TLS](proposed/psa-conditional-inclusion-c.md) for details.
In addition, for each mechanism you want provided only by your driver:
+
- Define the corresponding `PSA_WANT` macro in `psa/crypto_config.h` - this
means the algorithm will be available in the PSA Crypto API.
- Define the corresponding `MBEDTLS_PSA_ACCEL` in your build. This could be
@@ -52,9 +54,12 @@
------------------
For now, only the following (families of) mechanisms are supported:
+
- hashes: SHA-3, SHA-2, SHA-1, MD5, etc.
- elliptic-curve cryptography (ECC): ECDH, ECDSA, EC J-PAKE, ECC key types.
- finite-field Diffie-Hellman: FFDH algorithm, DH key types.
+- RSA: PKCS#1 v1.5 and v2.1 signature and encryption algorithms, RSA key types
+ (for now, only crypto, no X.509 or TLS support).
- AEADs:
- GCM and CCM with AES, ARIA and Camellia key types
- ChachaPoly with ChaCha20 Key type
@@ -71,15 +76,13 @@
in the "Limitations" sub-sections of the sections dedicated to each family
below.
-Currently (mid-2023) we don't have plans to extend this to RSA. If
-you're interested in driver-only support for RSA, please let us know.
-
Hashes
------
It is possible to have all hash operations provided only by a driver.
More precisely:
+
- you can enable `PSA_WANT_ALG_SHA_256` without `MBEDTLS_SHA256_C`, provided
you have `MBEDTLS_PSA_ACCEL_ALG_SHA_256` enabled;
- and similarly for all supported hash algorithms: `MD5`, `RIPEMD160`,
@@ -98,6 +101,7 @@
If you want to check at compile-time whether a certain hash algorithm is
available in the present build of Mbed TLS, regardless of whether it's
provided by a driver or built-in, you should use the following macros:
+
- for code that uses only the PSA Crypto API: `PSA_WANT_ALG_xxx` from
`psa/crypto.h`;
- for code that uses non-PSA crypto APIs: `MBEDTLS_MD_CAN_xxx` from
@@ -107,10 +111,12 @@
---------------------------------
It is possible to have most ECC operations provided only by a driver:
+
- the ECDH, ECDSA and EC J-PAKE algorithms;
- key import, export, and random generation.
More precisely, if:
+
- you have driver support for ECC public and using private keys (that is,
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY` and
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC` are enabled), and
@@ -119,6 +125,7 @@
`MBEDTLS_PSA_ACCEL_ECC_xxx` macros is enabled as well);
then you can:
+
- enable `PSA_WANT_ALG_ECDH` without `MBEDTLS_ECDH_C`, provided
`MBEDTLS_PSA_ACCEL_ALG_ECDH` is enabled
- enable `PSA_WANT_ALG_ECDSA` without `MBEDTLS_ECDSA_C`, provided
@@ -127,6 +134,7 @@
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is enabled.
In addition, if:
+
- none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`, `MBEDTLS_ECJPAKE_C` are enabled
(see conditions above), and
- you have driver support for all enabled ECC key pair operations - that is,
@@ -138,9 +146,11 @@
still be included in the build, see limitations sub-section below.
In addition, if:
-- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below), and
-- support for RSA key types and algorithms is fully disabled, and
-- support for DH key types and the FFDH algorithm is either disabled, or
+
+- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below),
+- and support for RSA key types and algorithms is either fully disabled or
+ fully provided by a driver,
+- and support for DH key types and the FFDH algorithm is either disabled or
fully provided by a driver,
then you can also disable `MBEDTLS_BIGNUM_C`.
@@ -148,6 +158,7 @@
In such builds, all crypto operations via the PSA Crypto API will work as
usual, as well as the PK, X.509 and TLS modules if `MBEDTLS_USE_PSA_CRYPTO` is
enabled, with the following exceptions:
+
- direct calls to APIs from the disabled modules are not possible;
- PK, X.509 and TLS will not support restartable ECC operations (see
limitation sub-section below).
@@ -155,6 +166,7 @@
If you want to check at compile-time whether a certain curve is available in
the present build of Mbed TLS, regardless of whether ECC is provided by a
driver or built-in, you should use the following macros:
+
- for code that uses only the PSA Crypto API: `PSA_WANT_ECC_xxx` from
`psa/crypto.h`;
- for code that may also use non-PSA crypto APIs: `MBEDTLS_ECP_HAVE_xxx` from
@@ -170,6 +182,7 @@
A limited subset of `ecp.c` will still be automatically re-enabled if any of
the following is enabled:
+
- `MBEDTLS_PK_PARSE_EC_COMPRESSED` - support for parsing ECC keys where the
public part is in compressed format;
- `MBEDTLS_PK_PARSE_EC_EXTENDED` - support for parsing ECC keys where the
@@ -243,12 +256,37 @@
`[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_FFDH` allow builds accelerating FFDH and
removing builtin support (i.e. `MBEDTLS_DHM_C`).
+RSA
+---
+
+It is possible for all RSA operations to be provided only by a driver.
+
+More precisely, if:
+
+- all the RSA algorithms that are enabled (`PSA_WANT_ALG_RSA_*`) are also
+ accelerated (`MBEDTLS_PSA_ACCEL_ALG_RSA_*`),
+- and all the RSA key types that are enabled (`PSA_WANT_KEY_TYPE_RSA_*`) are
+ also accelerated (`MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_*`),
+
+then you can disable `MBEDTLS_RSA_C`, `MBEDTLS_PKCS1_V15` and
+`MBEDTLS_PKCS1_V21`, and RSA will still work in PSA Crypto.
+
+### Limitations on RSA acceleration
+
+Unlike other mechanisms, for now in configurations with driver-only RSA, only
+PSA Crypto works. In particular, PK, X.509 and TLS will _not_ work with
+driver-only RSA even if `MBEDTLS_USE_PSA_CRYPTO` is enabled.
+
+Currently (early 2024) we don't have plans to extend this support. If you're
+interested in wider driver-only support for RSA, please let us know.
+
Ciphers (unauthenticated and AEAD)
----------------------------------
It is possible to have all ciphers and AEAD operations provided only by a
driver. More precisely, for each desired combination of key type and
algorithm/mode you can:
+
- Enable desired PSA key type(s):
- `PSA_WANT_KEY_TYPE_AES`,
- `PSA_WANT_KEY_TYPE_ARIA`,
@@ -305,6 +343,7 @@
Some legacy modules can't take advantage of PSA drivers yet, and will either
need to be disabled, or have reduced features when the built-in implementations
of some ciphers are removed:
+
- `MBEDTLS_NIST_KW_C` needs built-in AES: it must be disabled when
`MBEDTLS_AES_C` is disabled.
- `MBEDTLS_CMAC_C` needs built-in AES/DES: it must be disabled when
@@ -329,6 +368,7 @@
Note that the relationship between legacy (i.e. `MBEDTLS_xxx_C`) and PSA
(i.e. `PSA_WANT_xxx`) symbols is not always 1:1. For example:
+
- ECB mode is always enabled in the legacy configuration for each key type that
allows it (AES, ARIA, Camellia, DES), whereas it must be explicitly enabled
in PSA with `PSA_WANT_ALG_ECB_NO_PADDING`.
@@ -349,9 +389,12 @@
ECB mode (`PSA_WANT_ALG_ECB_NO_PADDING` + `MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING`)
together with desired key type(s) (`PSA_WANT_KEY_TYPE_[AES|ARIA|CAMELLIA]` +
`MBEDTLS_PSA_ACCEL_KEY_TYPE_[AES|ARIA|CAMELLIA]`).
+
In such configurations it is possible to:
+
- Use CCM and GCM via the PSA Crypto APIs.
-- Use CCM and GCM via legacy functions (`mbedtls_[ccm|gcm]_xxx()`).
+- Use CCM and GCM via legacy functions `mbedtls_[ccm|gcm]_xxx()` (but not the
+ legacy functions `mbedtls_cipher_xxx()`).
- Disable legacy key types (`MBEDTLS_[AES|ARIA|CAMELLIA]_C`) if there is no
other dependency requiring them.
@@ -362,6 +405,7 @@
The legacy CTR-DRBG module (enabled by `MBEDTLS_CTR_DRBG_C`) can also benefit
from PSA acceleration if both of the following conditions are met:
+
- The legacy AES module (`MBEDTLS_AES_C`) is not enabled and
- AES is supported on the PSA side together with ECB mode, i.e.
`PSA_WANT_KEY_TYPE_AES` + `PSA_WANT_ALG_ECB_NO_PADDING`.
@@ -370,6 +414,7 @@
It is possible to save code size by disabling MBEDTLS_CIPHER_C when all of the
following conditions are met:
+
- The application is not using the `mbedtls_cipher_` API.
- In PSA, all unauthenticated (that is, non-AEAD) ciphers are either disabled or
fully accelerated (that is, all compatible key types are accelerated too).
@@ -379,6 +424,7 @@
a driver.)
In such a build, everything will work as usual except for the following:
+
- Encryption/decryption functions from the PKCS5 and PKCS12 module will not be
available (only key derivation functions).
- Parsing of PKCS5- or PKCS12-encrypted keys in PK parse will fail.
diff --git a/docs/redirects.yaml b/docs/redirects.yaml
index 7ea1d95..969ffe4 100644
--- a/docs/redirects.yaml
+++ b/docs/redirects.yaml
@@ -7,5 +7,5 @@
# expose it.
- type: exact
- from_url: /projects/api/en/latest/$rest
- to_url: /projects/api/en/development/
+ from_url: /projects/api/en/latest/*
+ to_url: /projects/api/en/development/:splat
diff --git a/include/mbedtls/config_adjust_ssl.h b/include/mbedtls/config_adjust_ssl.h
index 8415f3e..5dd331c 100644
--- a/include/mbedtls/config_adjust_ssl.h
+++ b/include/mbedtls/config_adjust_ssl.h
@@ -65,6 +65,7 @@
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
#undef MBEDTLS_SSL_EARLY_DATA
+#undef MBEDTLS_SSL_RECORD_SIZE_LIMIT
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 043988f..3629526 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -447,7 +447,7 @@
/*
* TLS 1.3 signature algorithms
- * RFC 8446, Section 4.2.2
+ * RFC 8446, Section 4.2.3
*/
/* RSASSA-PKCS1-v1_5 algorithms */
@@ -1188,6 +1188,11 @@
unsigned char MBEDTLS_PRIVATE(mfl_code); /*!< MaxFragmentLength negotiated by peer */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+/*!< RecordSizeLimit received from the peer */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ uint16_t MBEDTLS_PRIVATE(record_size_limit);
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
unsigned char MBEDTLS_PRIVATE(exported);
/** TLS version negotiated in the session. Used if and when renegotiating
@@ -3751,6 +3756,8 @@
* used for certificate signature are controlled by the
* verification profile, see \c mbedtls_ssl_conf_cert_profile().
*
+ * \deprecated Superseded by mbedtls_ssl_conf_sig_algs().
+ *
* \note This list should be ordered by decreasing preference
* (preferred hash first).
*
@@ -3775,13 +3782,16 @@
#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */
/**
- * \brief Configure allowed signature algorithms for use in TLS 1.3
+ * \brief Configure allowed signature algorithms for use in TLS
*
* \param conf The SSL configuration to use.
* \param sig_algs List of allowed IANA values for TLS 1.3 signature algorithms,
- * terminated by \c MBEDTLS_TLS1_3_SIG_NONE. The list must remain
- * available throughout the lifetime of the conf object. Supported
- * values are available as \c MBEDTLS_TLS1_3_SIG_XXXX
+ * terminated by #MBEDTLS_TLS1_3_SIG_NONE. The list must remain
+ * available throughout the lifetime of the conf object.
+ * - For TLS 1.3, values of \c MBEDTLS_TLS1_3_SIG_XXXX should be
+ * used.
+ * - For TLS 1.2, values should be given as
+ * "(HashAlgorithm << 8) | SignatureAlgorithm".
*/
void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf,
const uint16_t *sig_algs);
diff --git a/library/aes.c b/library/aes.c
index f4b9739..b1a5c3e 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -53,6 +53,7 @@
#endif
#include "mbedtls/platform.h"
+#include "ctr.h"
/*
* This is a convenience shorthand macro to check if we need reverse S-box and
@@ -1441,36 +1442,38 @@
const unsigned char *input,
unsigned char *output)
{
- int c, i;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t n;
- n = *nc_off;
+ size_t offset = *nc_off;
- if (n > 0x0F) {
+ if (offset > 0x0F) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
- while (length--) {
- if (n == 0) {
+ for (size_t i = 0; i < length;) {
+ size_t n = 16;
+ if (offset == 0) {
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
if (ret != 0) {
goto exit;
}
-
- for (i = 16; i > 0; i--) {
- if (++nonce_counter[i - 1] != 0) {
- break;
- }
- }
+ mbedtls_ctr_increment_counter(nonce_counter);
+ } else {
+ n -= offset;
}
- c = *input++;
- *output++ = (unsigned char) (c ^ stream_block[n]);
- n = (n + 1) & 0x0F;
+ if (n > (length - i)) {
+ n = (length - i);
+ }
+ mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
+ // offset might be non-zero for the last block, but in that case, we don't use it again
+ offset = 0;
+ i += n;
}
- *nc_off = n;
+ // capture offset for future resumption
+ *nc_off = (*nc_off + length) % 16;
+
ret = 0;
exit:
diff --git a/library/ctr.h b/library/ctr.h
new file mode 100644
index 0000000..aa48fb9
--- /dev/null
+++ b/library/ctr.h
@@ -0,0 +1,35 @@
+/**
+ * \file ctr.h
+ *
+ * \brief This file contains common functionality for counter algorithms.
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef MBEDTLS_CTR_H
+#define MBEDTLS_CTR_H
+
+#include "common.h"
+
+/**
+ * \brief Increment a big-endian 16-byte value.
+ * This is quite performance-sensitive for AES-CTR and CTR-DRBG.
+ *
+ * \param n A 16-byte value to be incremented.
+ */
+static inline void mbedtls_ctr_increment_counter(uint8_t n[16])
+{
+ // The 32-bit version seems to perform about the same as a 64-bit version
+ // on 64-bit architectures, so no need to define a 64-bit version.
+ for (int i = 3;; i--) {
+ uint32_t x = MBEDTLS_GET_UINT32_BE(n, i << 2);
+ x += 1;
+ MBEDTLS_PUT_UINT32_BE(x, n, i << 2);
+ if (x != 0 || i == 0) {
+ break;
+ }
+ }
+}
+
+#endif /* MBEDTLS_CTR_H */
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index da34f95..66d9d28 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -14,6 +14,7 @@
#if defined(MBEDTLS_CTR_DRBG_C)
+#include "ctr.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@@ -333,7 +334,7 @@
{
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp;
- int i, j;
+ int j;
int ret = 0;
#if !defined(MBEDTLS_AES_C)
psa_status_t status;
@@ -346,11 +347,7 @@
/*
* Increase counter
*/
- for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
- if (++ctx->counter[i - 1] != 0) {
- break;
- }
- }
+ mbedtls_ctr_increment_counter(ctx->counter);
/*
* Crypt counter block
@@ -372,9 +369,7 @@
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
- for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) {
- tmp[i] ^= data[i];
- }
+ mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN);
/*
* Update key and counter
@@ -617,10 +612,11 @@
{
int ret = 0;
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
- unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = output;
- unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
- int i;
+ struct {
+ unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
+ unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
+ } locals;
size_t use_len;
if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
@@ -631,7 +627,7 @@
return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
}
- memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
+ memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
if (ctx->reseed_counter > ctx->reseed_interval ||
ctx->prediction_resistance) {
@@ -642,30 +638,26 @@
}
if (add_len > 0) {
- if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
+ if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) {
goto exit;
}
- if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
+ if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
goto exit;
}
}
while (output_len > 0) {
/*
- * Increase counter
+ * Increase counter (treat it as a 128-bit big-endian integer).
*/
- for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
- if (++ctx->counter[i - 1] != 0) {
- break;
- }
- }
+ mbedtls_ctr_increment_counter(ctx->counter);
/*
* Crypt counter block
*/
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
- ctx->counter, tmp)) != 0) {
+ ctx->counter, locals.tmp)) != 0) {
goto exit;
}
#else
@@ -673,7 +665,7 @@
size_t tmp_len;
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
- tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
+ locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
@@ -685,20 +677,19 @@
/*
* Copy random block to destination
*/
- memcpy(p, tmp, use_len);
+ memcpy(p, locals.tmp, use_len);
p += use_len;
output_len -= use_len;
}
- if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
+ if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
goto exit;
}
ctx->reseed_counter++;
exit:
- mbedtls_platform_zeroize(add_input, sizeof(add_input));
- mbedtls_platform_zeroize(tmp, sizeof(tmp));
+ mbedtls_platform_zeroize(&locals, sizeof(locals));
return ret;
}
diff --git a/library/gcm.c b/library/gcm.c
index 20d55c0..c677ca4 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -401,12 +401,9 @@
/* Increment the counter. */
static void gcm_incr(unsigned char y[16])
{
- size_t i;
- for (i = 16; i > 12; i--) {
- if (++y[i - 1] != 0) {
- break;
- }
- }
+ uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
+ x++;
+ MBEDTLS_PUT_UINT32_BE(x, y, 12);
}
/* Calculate and apply the encryption mask. Process use_len bytes of data,
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 850f206..b4dffa9 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -890,8 +890,9 @@
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
- * On success, the returned key slot is locked. It is the responsibility of
- * the caller to unlock the key slot when it does not access it anymore.
+ * On success, the returned key slot has been registered for reading.
+ * It is the responsibility of the caller to call psa_unregister_read(slot)
+ * when they have finished reading the contents of the slot.
*/
static psa_status_t psa_get_and_lock_key_slot_with_policy(
mbedtls_svc_key_id_t key,
@@ -935,7 +936,7 @@
error:
*p_slot = NULL;
- psa_unlock_key_slot(slot);
+ psa_unregister_read(slot);
return status;
}
@@ -950,8 +951,9 @@
* psa_get_and_lock_key_slot_with_policy() when there is no opaque key support
* for a cryptographic operation.
*
- * On success, the returned key slot is locked. It is the responsibility of the
- * caller to unlock the key slot when it does not access it anymore.
+ * On success, the returned key slot has been registered for reading.
+ * It is the responsibility of the caller to call psa_unregister_read(slot)
+ * when they have finished reading the contents of the slot.
*/
static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
mbedtls_svc_key_id_t key,
@@ -966,7 +968,7 @@
}
if (psa_key_lifetime_is_external((*p_slot)->attr.lifetime)) {
- psa_unlock_key_slot(*p_slot);
+ psa_unregister_read(*p_slot);
*p_slot = NULL;
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -994,15 +996,41 @@
/*
* As the return error code may not be handled in case of multiple errors,
- * do our best to report an unexpected lock counter. Assert with
- * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is equal to one:
+ * do our best to report an unexpected amount of registered readers or
+ * an unexpected state.
+ * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that the slot is valid for
+ * wiping.
* if the MBEDTLS_TEST_HOOKS configuration option is enabled and the
* function is called as part of the execution of a test suite, the
* execution of the test suite is stopped in error if the assertion fails.
*/
- if (slot->lock_count != 1) {
- MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count == 1);
- status = PSA_ERROR_CORRUPTION_DETECTED;
+ switch (slot->state) {
+ case PSA_SLOT_FULL:
+ /* In this state psa_wipe_key_slot() must only be called if the
+ * caller is the last reader. */
+ case PSA_SLOT_PENDING_DELETION:
+ /* In this state psa_wipe_key_slot() must only be called if the
+ * caller is the last reader. */
+ if (slot->registered_readers != 1) {
+ MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1);
+ status = PSA_ERROR_CORRUPTION_DETECTED;
+ }
+ break;
+ case PSA_SLOT_FILLING:
+ /* In this state registered_readers must be 0. */
+ if (slot->registered_readers != 0) {
+ MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 0);
+ status = PSA_ERROR_CORRUPTION_DETECTED;
+ }
+ break;
+ case PSA_SLOT_EMPTY:
+ /* The slot is already empty, it cannot be wiped. */
+ MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->state != PSA_SLOT_EMPTY);
+ status = PSA_ERROR_CORRUPTION_DETECTED;
+ break;
+ default:
+ /* The slot's state is invalid. */
+ status = PSA_ERROR_CORRUPTION_DETECTED;
}
/* Multipart operations may still be using the key. This is safe
@@ -1012,7 +1040,8 @@
* key material can linger until all operations are completed. */
/* At this point, key material and other type-specific content has
* been wiped. Clear remaining metadata. We can call memset and not
- * zeroize because the metadata is not particularly sensitive. */
+ * zeroize because the metadata is not particularly sensitive.
+ * This memset also sets the slot's state to PSA_SLOT_EMPTY. */
memset(slot, 0, sizeof(*slot));
return status;
}
@@ -1031,28 +1060,26 @@
}
/*
- * Get the description of the key in a key slot. In case of a persistent
- * key, this will load the key description from persistent memory if not
- * done yet. We cannot avoid this loading as without it we don't know if
+ * Get the description of the key in a key slot, and register to read it.
+ * In the case of a persistent key, this will load the key description
+ * from persistent memory if not done yet.
+ * We cannot avoid this loading as without it we don't know if
* the key is operated by an SE or not and this information is needed by
- * the current implementation.
- */
+ * the current implementation. */
status = psa_get_and_lock_key_slot(key, &slot);
if (status != PSA_SUCCESS) {
return status;
}
- /*
- * If the key slot containing the key description is under access by the
- * library (apart from the present access), the key cannot be destroyed
- * yet. For the time being, just return in error. Eventually (to be
- * implemented), the key should be destroyed when all accesses have
- * stopped.
- */
- if (slot->lock_count > 1) {
- psa_unlock_key_slot(slot);
- return PSA_ERROR_GENERIC_ERROR;
- }
+ /* Set the key slot containing the key description's state to
+ * PENDING_DELETION. This stops new operations from registering
+ * to read the slot. Current readers can safely continue to access
+ * the key within the slot; the last registered reader will
+ * automatically wipe the slot when they call psa_unregister_read().
+ * If the key is persistent, we can now delete the copy of the key
+ * from memory. If the key is opaque, we require the driver to
+ * deal with the deletion. */
+ slot->state = PSA_SLOT_PENDING_DELETION;
if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
/* Refuse the destruction of a read-only key (which may or may not work
@@ -1100,6 +1127,9 @@
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
+ /* Destroy the copy of the persistent key from storage.
+ * The slot will still hold a copy of the key until the last reader
+ * unregisters. */
status = psa_destroy_persistent_key(slot->attr.id);
if (overall_status == PSA_SUCCESS) {
overall_status = status;
@@ -1126,8 +1156,11 @@
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
exit:
- status = psa_wipe_key_slot(slot);
- /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
+ /* Unregister from reading the slot. If we are the last active reader
+ * then this will wipe the slot. */
+ status = psa_unregister_read(slot);
+ /* Prioritize CORRUPTION_DETECTED from unregistering over
+ * a storage error. */
if (status != PSA_SUCCESS) {
overall_status = status;
}
@@ -1252,7 +1285,7 @@
psa_reset_key_attributes(attributes);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -1348,7 +1381,7 @@
slot->key.data, slot->key.bytes,
data, data_size, data_length);
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -1462,7 +1495,7 @@
data, data_size, data_length);
exit:
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -1579,8 +1612,9 @@
* In case of failure at any step, stop the sequence and call
* psa_fail_key_creation().
*
- * On success, the key slot is locked. It is the responsibility of the caller
- * to unlock the key slot when it does not access it anymore.
+ * On success, the key slot's state is PSA_SLOT_FILLING.
+ * It is the responsibility of the caller to change the slot's state to
+ * PSA_SLOT_EMPTY/FULL once key creation has finished.
*
* \param method An identification of the calling function.
* \param[in] attributes Key attributes for the new key.
@@ -1611,7 +1645,7 @@
return status;
}
- status = psa_get_empty_key_slot(&volatile_key_id, p_slot);
+ status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
if (status != PSA_SUCCESS) {
return status;
}
@@ -1637,7 +1671,7 @@
/* Erase external-only flags from the internal copy. To access
* external-only flags, query `attributes`. Thanks to the check
* in psa_validate_key_attributes(), this leaves the dual-use
- * flags and any internal flag that psa_get_empty_key_slot()
+ * flags and any internal flag that psa_reserve_free_key_slot()
* may have set. */
slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
@@ -1689,8 +1723,6 @@
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
- slot->status = PSA_SLOT_OCCUPIED;
-
return PSA_SUCCESS;
}
@@ -1702,9 +1734,9 @@
* See the documentation of psa_start_key_creation() for the intended use
* of this function.
*
- * If the finalization succeeds, the function unlocks the key slot (it was
- * locked by psa_start_key_creation()) and the key slot cannot be accessed
- * anymore as part of the key creation process.
+ * If the finalization succeeds, the function sets the key slot's state to
+ * PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the
+ * key creation process.
*
* \param[in,out] slot Pointer to the slot with key material.
* \param[in] driver The secure element driver for the key,
@@ -1780,7 +1812,8 @@
if (status == PSA_SUCCESS) {
*key = slot->attr.id;
- status = psa_unlock_key_slot(slot);
+ status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
+ PSA_SLOT_FULL);
if (status != PSA_SUCCESS) {
*key = MBEDTLS_SVC_KEY_ID_INIT;
}
@@ -1795,7 +1828,7 @@
* or after psa_finish_key_creation() fails. In other circumstances, this
* function may not clean up persistent storage.
* See the documentation of psa_start_key_creation() for the intended use
- * of this function.
+ * of this function. Sets the slot's state to PSA_SLOT_EMPTY.
*
* \param[in,out] slot Pointer to the slot with key material.
* \param[in] driver The secure element driver for the key,
@@ -2134,7 +2167,7 @@
psa_fail_key_creation(target_slot, driver);
}
- unlock_status = psa_unlock_key_slot(source_slot);
+ unlock_status = psa_unregister_read(source_slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -2455,7 +2488,7 @@
psa_mac_abort(operation);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -2641,7 +2674,7 @@
psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -2785,7 +2818,7 @@
psa_wipe_tag_output_buffer(signature, status, signature_size,
*signature_length);
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -2833,7 +2866,7 @@
signature, signature_length);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
@@ -3100,7 +3133,7 @@
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
exit:
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -3152,7 +3185,7 @@
output, output_size, output_length);
exit:
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -3261,7 +3294,7 @@
psa_sign_hash_abort_internal(operation);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
if (unlock_status != PSA_SUCCESS) {
operation->error_occurred = 1;
@@ -3406,7 +3439,7 @@
psa_verify_hash_abort_internal(operation);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
if (unlock_status != PSA_SUCCESS) {
operation->error_occurred = 1;
@@ -3978,7 +4011,7 @@
psa_cipher_abort(operation);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -4223,7 +4256,7 @@
output_size - default_iv_length, output_length);
exit:
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
if (status == PSA_SUCCESS) {
status = unlock_status;
}
@@ -4284,7 +4317,7 @@
output, output_size, output_length);
exit:
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
if (status == PSA_SUCCESS) {
status = unlock_status;
}
@@ -4410,7 +4443,7 @@
}
exit:
- psa_unlock_key_slot(slot);
+ psa_unregister_read(slot);
return status;
}
@@ -4465,7 +4498,7 @@
}
exit:
- psa_unlock_key_slot(slot);
+ psa_unregister_read(slot);
return status;
}
@@ -4577,7 +4610,7 @@
operation->key_type = psa_get_key_type(&attributes);
exit:
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
if (status == PSA_SUCCESS) {
status = unlock_status;
@@ -6900,7 +6933,7 @@
slot->key.data,
slot->key.bytes);
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -7057,7 +7090,7 @@
}
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -7118,7 +7151,7 @@
*output_length = output_size;
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@@ -7792,7 +7825,7 @@
if (status != PSA_SUCCESS) {
psa_pake_abort(operation);
}
- unlock_status = psa_unlock_key_slot(slot);
+ unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index ff01add..1edd63e 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -47,8 +47,10 @@
typedef enum {
PSA_SLOT_EMPTY = 0,
- PSA_SLOT_OCCUPIED,
-} psa_key_slot_status_t;
+ PSA_SLOT_FILLING,
+ PSA_SLOT_FULL,
+ PSA_SLOT_PENDING_DELETION,
+} psa_key_slot_state_t;
/** The data structure representing a key slot, containing key material
* and metadata for one key.
@@ -56,18 +58,37 @@
typedef struct {
psa_core_key_attributes_t attr;
- psa_key_slot_status_t status;
+ /*
+ * The current state of the key slot, as described in
+ * docs/architecture/psa-thread-safety/psa-thread-safety.md.
+ *
+ * Library functions can modify the state of a key slot by calling
+ * psa_key_slot_state_transition.
+ *
+ * The state variable is used to help determine whether library functions
+ * which operate on the slot succeed. For example, psa_finish_key_creation,
+ * which transfers the state of a slot from PSA_SLOT_FILLING to
+ * PSA_SLOT_FULL, must fail with error code PSA_ERROR_CORRUPTION_DETECTED
+ * if the state of the slot is not PSA_SLOT_FILLING.
+ *
+ * Library functions which traverse the array of key slots only consider
+ * slots that are in a suitable state for the function.
+ * For example, psa_get_and_lock_key_slot_in_memory, which finds a slot
+ * containing a given key ID, will only check slots whose state variable is
+ * PSA_SLOT_FULL. */
+ psa_key_slot_state_t state;
/*
- * Number of locks on the key slot held by the library.
+ * Number of functions registered as reading the material in the key slot.
*
- * This counter is incremented by one each time a library function
- * retrieves through one of the dedicated internal API a pointer to the
- * key slot.
+ * Library functions must not write directly to registered_readers
*
- * This counter is decremented by one each time a library function stops
- * accessing the key slot and states it by calling the
- * psa_unlock_key_slot() API.
+ * A function must call psa_register_read(slot) before reading the current
+ * contents of the slot for an operation.
+ * They then must call psa_unregister_read(slot) once they have finished
+ * reading the current contents of the slot.
+ * A function must call psa_key_slot_has_readers(slot) to check if
+ * the slot is in use for reading.
*
* This counter is used to prevent resetting the key slot while the library
* may access it. For example, such control is needed in the following
@@ -78,10 +99,9 @@
* the library cannot be reclaimed to free a key slot to load the
* persistent key.
* . In case of a multi-threaded application where one thread asks to close
- * or purge or destroy a key while it is in used by the library through
- * another thread.
- */
- size_t lock_count;
+ * or purge or destroy a key while it is in use by the library through
+ * another thread. */
+ size_t registered_readers;
/* Dynamically allocated key data buffer.
* Format as specified in psa_export_key(). */
@@ -96,31 +116,15 @@
#define PSA_KA_MASK_INTERNAL_ONLY ( \
0)
-/** Test whether a key slot is occupied.
- *
- * A key slot is occupied iff the key type is nonzero. This works because
- * no valid key can have 0 as its key type.
+/** Test whether a key slot has any registered readers.
*
* \param[in] slot The key slot to test.
*
- * \return 1 if the slot is occupied, 0 otherwise.
+ * \return 1 if the slot has any registered readers, 0 otherwise.
*/
-static inline int psa_is_key_slot_occupied(const psa_key_slot_t *slot)
+static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot)
{
- return slot->status == PSA_SLOT_OCCUPIED;
-}
-
-/** Test whether a key slot is locked.
- *
- * A key slot is locked iff its lock counter is strictly greater than 0.
- *
- * \param[in] slot The key slot to test.
- *
- * \return 1 if the slot is locked, 0 otherwise.
- */
-static inline int psa_is_key_slot_locked(const psa_key_slot_t *slot)
-{
- return slot->lock_count > 0;
+ return slot->registered_readers > 0;
}
/** Retrieve flags from psa_key_slot_t::attr::core::flags.
@@ -190,13 +194,18 @@
/** Completely wipe a slot in memory, including its policy.
*
* Persistent storage is not affected.
+ * Sets the slot's state to PSA_SLOT_EMPTY.
*
* \param[in,out] slot The key slot to wipe.
*
* \retval #PSA_SUCCESS
- * Success. This includes the case of a key slot that was
- * already fully wiped.
- * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * The slot has been successfully wiped.
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * The slot's state was PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION, and
+ * the amount of registered readers was not equal to 1. Or,
+ * the slot's state was PSA_SLOT_EMPTY. Or,
+ * the slot's state was PSA_SLOT_FILLING, and the amount
+ * of registered readers was not equal to 0.
*/
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot);
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 5ecc3a7..8d7ff90 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -108,7 +108,9 @@
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
slot = &global_data.key_slots[slot_idx];
- if (mbedtls_svc_key_id_equal(key, slot->attr.id)) {
+ /* Only consider slots which are in a full state. */
+ if ((slot->state == PSA_SLOT_FULL) &&
+ (mbedtls_svc_key_id_equal(key, slot->attr.id))) {
break;
}
}
@@ -117,7 +119,7 @@
}
if (status == PSA_SUCCESS) {
- status = psa_lock_key_slot(slot);
+ status = psa_register_read(slot);
if (status == PSA_SUCCESS) {
*p_slot = slot;
}
@@ -141,36 +143,38 @@
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
- slot->lock_count = 1;
+ slot->registered_readers = 1;
+ slot->state = PSA_SLOT_PENDING_DELETION;
(void) psa_wipe_key_slot(slot);
}
global_data.key_slots_initialized = 0;
}
-psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
- psa_key_slot_t **p_slot)
+psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
+ psa_key_slot_t **p_slot)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t slot_idx;
- psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot;
+ psa_key_slot_t *selected_slot, *unused_persistent_key_slot;
if (!global_data.key_slots_initialized) {
status = PSA_ERROR_BAD_STATE;
goto error;
}
- selected_slot = unlocked_persistent_key_slot = NULL;
+ selected_slot = unused_persistent_key_slot = NULL;
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
- if (!psa_is_key_slot_occupied(slot)) {
+ if (slot->state == PSA_SLOT_EMPTY) {
selected_slot = slot;
break;
}
- if ((unlocked_persistent_key_slot == NULL) &&
- (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
- (!psa_is_key_slot_locked(slot))) {
- unlocked_persistent_key_slot = slot;
+ if ((unused_persistent_key_slot == NULL) &&
+ (slot->state == PSA_SLOT_FULL) &&
+ (!psa_key_slot_has_readers(slot)) &&
+ (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime))) {
+ unused_persistent_key_slot = slot;
}
}
@@ -182,14 +186,18 @@
* storage.
*/
if ((selected_slot == NULL) &&
- (unlocked_persistent_key_slot != NULL)) {
- selected_slot = unlocked_persistent_key_slot;
- selected_slot->lock_count = 1;
- psa_wipe_key_slot(selected_slot);
+ (unused_persistent_key_slot != NULL)) {
+ selected_slot = unused_persistent_key_slot;
+ psa_register_read(selected_slot);
+ status = psa_wipe_key_slot(selected_slot);
+ if (status != PSA_SUCCESS) {
+ goto error;
+ }
}
if (selected_slot != NULL) {
- status = psa_lock_key_slot(selected_slot);
+ status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY,
+ PSA_SLOT_FILLING);
if (status != PSA_SUCCESS) {
goto error;
}
@@ -239,7 +247,8 @@
slot, data->slot_number, sizeof(data->slot_number));
if (status == PSA_SUCCESS) {
- slot->status = PSA_SLOT_OCCUPIED;
+ status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
+ PSA_SLOT_FULL);
}
goto exit;
}
@@ -250,7 +259,8 @@
goto exit;
}
- slot->status = PSA_SLOT_OCCUPIED;
+ status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
+ PSA_SLOT_FULL);
exit:
psa_free_persistent_key_data(key_data, key_data_length);
@@ -324,8 +334,9 @@
/* Copy actual key length and core attributes into the slot on success */
slot->key.bytes = key_buffer_length;
slot->attr = attributes.core;
- slot->status = PSA_SLOT_OCCUPIED;
+ status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
+ PSA_SLOT_FULL);
exit:
if (status != PSA_SUCCESS) {
psa_remove_key_data_from_memory(slot);
@@ -358,7 +369,7 @@
defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
psa_key_id_t volatile_key_id;
- status = psa_get_empty_key_slot(&volatile_key_id, p_slot);
+ status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
if (status != PSA_SUCCESS) {
return status;
}
@@ -380,12 +391,17 @@
if (status != PSA_SUCCESS) {
psa_wipe_key_slot(*p_slot);
+
if (status == PSA_ERROR_DOES_NOT_EXIST) {
status = PSA_ERROR_INVALID_HANDLE;
}
} else {
/* Add implicit usage flags. */
psa_extend_key_usage_flags(&(*p_slot)->attr.policy.usage);
+
+ psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING,
+ PSA_SLOT_FULL);
+ status = psa_register_read(*p_slot);
}
return status;
@@ -394,26 +410,37 @@
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
}
-psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot)
+psa_status_t psa_unregister_read(psa_key_slot_t *slot)
{
if (slot == NULL) {
return PSA_SUCCESS;
}
+ if ((slot->state != PSA_SLOT_FULL) &&
+ (slot->state != PSA_SLOT_PENDING_DELETION)) {
+ return PSA_ERROR_CORRUPTION_DETECTED;
+ }
- if (slot->lock_count > 0) {
- slot->lock_count--;
+ /* If we are the last reader and the slot is marked for deletion,
+ * we must wipe the slot here. */
+ if ((slot->state == PSA_SLOT_PENDING_DELETION) &&
+ (slot->registered_readers == 1)) {
+ return psa_wipe_key_slot(slot);
+ }
+
+ if (psa_key_slot_has_readers(slot)) {
+ slot->registered_readers--;
return PSA_SUCCESS;
}
/*
* As the return error code may not be handled in case of multiple errors,
- * do our best to report if the lock counter is equal to zero. Assert with
- * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is strictly greater
- * than zero: if the MBEDTLS_TEST_HOOKS configuration option is enabled and
+ * do our best to report if there are no registered readers. Assert with
+ * MBEDTLS_TEST_HOOK_TEST_ASSERT that there are registered readers:
+ * if the MBEDTLS_TEST_HOOKS configuration option is enabled and
* the function is called as part of the execution of a test suite, the
* execution of the test suite is stopped in error if the assertion fails.
*/
- MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count > 0);
+ MBEDTLS_TEST_HOOK_TEST_ASSERT(psa_key_slot_has_readers(slot));
return PSA_ERROR_CORRUPTION_DETECTED;
}
@@ -480,7 +507,7 @@
*handle = key;
- return psa_unlock_key_slot(slot);
+ return psa_unregister_read(slot);
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
(void) key;
@@ -506,10 +533,10 @@
return status;
}
- if (slot->lock_count <= 1) {
+ if (slot->registered_readers == 1) {
return psa_wipe_key_slot(slot);
} else {
- return psa_unlock_key_slot(slot);
+ return psa_unregister_read(slot);
}
}
@@ -524,10 +551,10 @@
}
if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
- (slot->lock_count <= 1)) {
+ (slot->registered_readers == 1)) {
return psa_wipe_key_slot(slot);
} else {
- return psa_unlock_key_slot(slot);
+ return psa_unregister_read(slot);
}
}
@@ -539,10 +566,10 @@
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
const psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
- if (psa_is_key_slot_locked(slot)) {
+ if (psa_key_slot_has_readers(slot)) {
++stats->locked_slots;
}
- if (!psa_is_key_slot_occupied(slot)) {
+ if (slot->state == PSA_SLOT_EMPTY) {
++stats->empty_slots;
continue;
}
diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h
index 6041a35..0b0d7b3 100644
--- a/library/psa_crypto_slot_management.h
+++ b/library/psa_crypto_slot_management.h
@@ -54,8 +54,9 @@
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
- * On success, the returned key slot is locked. It is the responsibility of
- * the caller to unlock the key slot when it does not access it anymore.
+ * On success, the returned key slot has been registered for reading.
+ * It is the responsibility of the caller to call psa_unregister_read(slot)
+ * when they have finished reading the contents of the slot.
*
* \param key Key identifier to query.
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
@@ -95,50 +96,85 @@
* This does not affect persistent storage. */
void psa_wipe_all_key_slots(void);
-/** Find a free key slot.
+/** Find a free key slot and reserve it to be filled with a key.
*
- * This function returns a key slot that is available for use and is in its
- * ground state (all-bits-zero). On success, the key slot is locked. It is
- * the responsibility of the caller to unlock the key slot when it does not
- * access it anymore.
+ * This function finds a key slot that is free,
+ * sets its state to PSA_SLOT_FILLING and then returns the slot.
+ *
+ * On success, the key slot's state is PSA_SLOT_FILLING.
+ * It is the responsibility of the caller to change the slot's state to
+ * PSA_SLOT_EMPTY/FULL once key creation has finished.
*
* \param[out] volatile_key_id On success, volatile key identifier
* associated to the returned slot.
* \param[out] p_slot On success, a pointer to the slot.
*
* \retval #PSA_SUCCESS \emptydescription
- * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * There were no free key slots.
* \retval #PSA_ERROR_BAD_STATE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * This function attempted to operate on a key slot which was in an
+ * unexpected state.
*/
-psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
- psa_key_slot_t **p_slot);
+psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
+ psa_key_slot_t **p_slot);
-/** Lock a key slot.
+/** Change the state of a key slot.
*
- * This function increments the key slot lock counter by one.
+ * This function changes the state of the key slot from expected_state to
+ * new state. If the state of the slot was not expected_state, the state is
+ * unchanged.
+ *
+ * \param[in] slot The key slot.
+ * \param[in] expected_state The current state of the slot.
+ * \param[in] new_state The new state of the slot.
+ *
+ * \retval #PSA_SUCCESS
+ The key slot's state variable is new_state.
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * The slot's state was not expected_state.
+ */
+static inline psa_status_t psa_key_slot_state_transition(
+ psa_key_slot_t *slot, psa_key_slot_state_t expected_state,
+ psa_key_slot_state_t new_state)
+{
+ if (slot->state != expected_state) {
+ return PSA_ERROR_CORRUPTION_DETECTED;
+ }
+ slot->state = new_state;
+ return PSA_SUCCESS;
+}
+
+/** Register as a reader of a key slot.
+ *
+ * This function increments the key slot registered reader counter by one.
*
* \param[in] slot The key slot.
*
* \retval #PSA_SUCCESS
- The key slot lock counter was incremented.
+ The key slot registered reader counter was incremented.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
- * The lock counter already reached its maximum value and was not
- * increased.
+ * The reader counter already reached its maximum value and was not
+ * increased, or the slot's state was not PSA_SLOT_FULL.
*/
-static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot)
+static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
{
- if (slot->lock_count >= SIZE_MAX) {
+ if ((slot->state != PSA_SLOT_FULL) ||
+ (slot->registered_readers >= SIZE_MAX)) {
return PSA_ERROR_CORRUPTION_DETECTED;
}
-
- slot->lock_count++;
+ slot->registered_readers++;
return PSA_SUCCESS;
}
-/** Unlock a key slot.
+/** Unregister from reading a key slot.
*
- * This function decrements the key slot lock counter by one.
+ * This function decrements the key slot registered reader counter by one.
+ * If the state of the slot is PSA_SLOT_PENDING_DELETION,
+ * and there is only one registered reader (the caller),
+ * this function will call psa_wipe_key_slot().
*
* \note To ease the handling of errors in retrieving a key slot
* a NULL input pointer is valid, and the function returns
@@ -146,13 +182,16 @@
*
* \param[in] slot The key slot.
* \retval #PSA_SUCCESS
- * \p slot is NULL or the key slot lock counter has been
- * decremented successfully.
+ * \p slot is NULL or the key slot reader counter has been
+ * decremented (and potentially wiped) successfully.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
- * The lock counter was equal to 0.
- *
+ * The slot's state was neither PSA_SLOT_FULL nor
+ * PSA_SLOT_PENDING_DELETION.
+ * Or a wipe was attempted and the slot's state was not
+ * PSA_SLOT_PENDING_DELETION.
+ * Or registered_readers was equal to 0.
*/
-psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot);
+psa_status_t psa_unregister_read(psa_key_slot_t *slot);
/** Test whether a lifetime designates a key in an external cryptoprocessor.
*
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 270db41..d585ca5 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -609,7 +609,7 @@
int ssl_write_supported_groups_ext_flags = 0;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
- if (propose_tls13 && mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
+ if (propose_tls13 && mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
ssl_write_supported_groups_ext_flags |=
SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG;
}
@@ -637,7 +637,7 @@
int write_sig_alg_ext = 0;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
write_sig_alg_ext = write_sig_alg_ext ||
- (propose_tls13 && mbedtls_ssl_conf_tls13_ephemeral_enabled(ssl));
+ (propose_tls13 && mbedtls_ssl_conf_tls13_is_ephemeral_enabled(ssl));
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
write_sig_alg_ext = write_sig_alg_ext || propose_tls12;
@@ -668,7 +668,7 @@
/* The "pre_shared_key" extension (RFC 8446 Section 4.2.11)
* MUST be the last extension in the ClientHello.
*/
- if (propose_tls13 && mbedtls_ssl_conf_tls13_some_psk_enabled(ssl)) {
+ if (propose_tls13 && mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl)) {
ret = mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
ssl, p, end, &output_len, binders_len);
if (ret != 0) {
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index b9801a0..96afe76 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -439,6 +439,19 @@
size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl);
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+/**
+ * \brief Get the size limit in bytes for the protected outgoing records
+ * as defined in RFC 8449
+ *
+ * \param ssl SSL context
+ *
+ * \return The size limit in bytes for the protected outgoing
+ * records as defined in RFC 8449.
+ */
+size_t mbedtls_ssl_get_output_record_size_limit(const mbedtls_ssl_context *ssl);
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
static inline size_t mbedtls_ssl_get_output_buflen(const mbedtls_ssl_context *ctx)
{
@@ -1901,89 +1914,89 @@
/*
* Helper functions around key exchange modes.
*/
-static inline unsigned mbedtls_ssl_conf_tls13_check_kex_modes(mbedtls_ssl_context *ssl,
- int kex_mode_mask)
+static inline int mbedtls_ssl_conf_tls13_is_kex_mode_enabled(mbedtls_ssl_context *ssl,
+ int kex_mode_mask)
{
return (ssl->conf->tls13_kex_modes & kex_mode_mask) != 0;
}
-static inline int mbedtls_ssl_conf_tls13_psk_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_conf_tls13_is_psk_enabled(mbedtls_ssl_context *ssl)
{
- return mbedtls_ssl_conf_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK);
+ return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK);
}
-static inline int mbedtls_ssl_conf_tls13_psk_ephemeral_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(mbedtls_ssl_context *ssl)
{
- return mbedtls_ssl_conf_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL);
+ return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL);
}
-static inline int mbedtls_ssl_conf_tls13_ephemeral_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_conf_tls13_is_ephemeral_enabled(mbedtls_ssl_context *ssl)
{
- return mbedtls_ssl_conf_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL);
+ return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL);
}
-static inline int mbedtls_ssl_conf_tls13_some_ephemeral_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(mbedtls_ssl_context *ssl)
{
- return mbedtls_ssl_conf_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL);
+ return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL);
}
-static inline int mbedtls_ssl_conf_tls13_some_psk_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_conf_tls13_is_some_psk_enabled(mbedtls_ssl_context *ssl)
{
- return mbedtls_ssl_conf_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL);
+ return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL);
}
#if defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/**
* Given a list of key exchange modes, check if at least one of them is
- * supported.
+ * supported by peer.
*
* \param[in] ssl SSL context
* \param kex_modes_mask Mask of the key exchange modes to check
*
- * \return 0 if at least one of the key exchange modes is supported,
- * !=0 otherwise.
+ * \return Non-zero if at least one of the key exchange modes is supported by
+ * the peer, otherwise \c 0.
*/
-static inline unsigned mbedtls_ssl_tls13_check_kex_modes(mbedtls_ssl_context *ssl,
- int kex_modes_mask)
+static inline int mbedtls_ssl_tls13_is_kex_mode_supported(mbedtls_ssl_context *ssl,
+ int kex_modes_mask)
{
- return (ssl->handshake->tls13_kex_modes & kex_modes_mask) == 0;
+ return (ssl->handshake->tls13_kex_modes & kex_modes_mask) != 0;
}
-static inline int mbedtls_ssl_tls13_psk_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_tls13_is_psk_supported(mbedtls_ssl_context *ssl)
{
- return !mbedtls_ssl_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK);
+ return mbedtls_ssl_tls13_is_kex_mode_supported(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK);
}
-static inline int mbedtls_ssl_tls13_psk_ephemeral_enabled(
+static inline int mbedtls_ssl_tls13_is_psk_ephemeral_supported(
mbedtls_ssl_context *ssl)
{
- return !mbedtls_ssl_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL);
+ return mbedtls_ssl_tls13_is_kex_mode_supported(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL);
}
-static inline int mbedtls_ssl_tls13_ephemeral_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_tls13_is_ephemeral_supported(mbedtls_ssl_context *ssl)
{
- return !mbedtls_ssl_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL);
+ return mbedtls_ssl_tls13_is_kex_mode_supported(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL);
}
-static inline int mbedtls_ssl_tls13_some_ephemeral_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_tls13_is_some_ephemeral_supported(mbedtls_ssl_context *ssl)
{
- return !mbedtls_ssl_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL);
+ return mbedtls_ssl_tls13_is_kex_mode_supported(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL);
}
-static inline int mbedtls_ssl_tls13_some_psk_enabled(mbedtls_ssl_context *ssl)
+static inline int mbedtls_ssl_tls13_is_some_psk_supported(mbedtls_ssl_context *ssl)
{
- return !mbedtls_ssl_tls13_check_kex_modes(ssl,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL);
+ return mbedtls_ssl_tls13_is_kex_mode_supported(ssl,
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL);
}
#endif /* MBEDTLS_SSL_SRV_C &&
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
@@ -2691,12 +2704,18 @@
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH (2)
-#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN (64)
+#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN (64) /* As defined in RFC 8449 */
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end);
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+int mbedtls_ssl_tls13_write_record_size_limit_ext(mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *out_len);
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
#if defined(MBEDTLS_SSL_ALPN)
@@ -2769,47 +2788,53 @@
#define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800)
-static inline unsigned int mbedtls_ssl_session_get_ticket_flags(
+static inline unsigned int mbedtls_ssl_tls13_session_get_ticket_flags(
mbedtls_ssl_session *session, unsigned int flags)
{
return session->ticket_flags &
(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
}
-static inline unsigned int mbedtls_ssl_session_check_ticket_flags(
+/**
+ * Check if at least one of the given flags is set in
+ * the session ticket. See the definition of
+ * `MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK` to get all
+ * permitted flags.
+ */
+static inline int mbedtls_ssl_tls13_session_ticket_has_flags(
mbedtls_ssl_session *session, unsigned int flags)
{
- return mbedtls_ssl_session_get_ticket_flags(session, flags) == 0;
+ return mbedtls_ssl_tls13_session_get_ticket_flags(session, flags) != 0;
}
-static inline unsigned int mbedtls_ssl_session_ticket_allow_psk(
+static inline int mbedtls_ssl_tls13_session_ticket_allow_psk(
mbedtls_ssl_session *session)
{
- return !mbedtls_ssl_session_check_ticket_flags(session,
- MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION);
+ return mbedtls_ssl_tls13_session_ticket_has_flags(
+ session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION);
}
-static inline unsigned int mbedtls_ssl_session_ticket_allow_psk_ephemeral(
+static inline int mbedtls_ssl_tls13_session_ticket_allow_psk_ephemeral(
mbedtls_ssl_session *session)
{
- return !mbedtls_ssl_session_check_ticket_flags(session,
- MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION);
+ return mbedtls_ssl_tls13_session_ticket_has_flags(
+ session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION);
}
-static inline unsigned int mbedtls_ssl_session_ticket_allow_early_data(
+static inline unsigned int mbedtls_ssl_tls13_session_ticket_allow_early_data(
mbedtls_ssl_session *session)
{
- return !mbedtls_ssl_session_check_ticket_flags(session,
- MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
+ return mbedtls_ssl_tls13_session_ticket_has_flags(
+ session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
}
-static inline void mbedtls_ssl_session_set_ticket_flags(
+static inline void mbedtls_ssl_tls13_session_set_ticket_flags(
mbedtls_ssl_session *session, unsigned int flags)
{
session->ticket_flags |= (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
}
-static inline void mbedtls_ssl_session_clear_ticket_flags(
+static inline void mbedtls_ssl_tls13_session_clear_ticket_flags(
mbedtls_ssl_session *session, unsigned int flags)
{
session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index e1fb128..8c1e372 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1342,7 +1342,7 @@
* bad config.
*
*/
- if (mbedtls_ssl_conf_tls13_ephemeral_enabled(
+ if (mbedtls_ssl_conf_tls13_is_ephemeral_enabled(
(mbedtls_ssl_context *) ssl) &&
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
ssl->conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
@@ -2455,6 +2455,7 @@
* uint8 ticket_flags;
* opaque resumption_key<0..255>;
* uint32 max_early_data_size;
+ * uint16 record_size_limit;
* select ( endpoint ) {
* case client: ClientOnlyData;
* case server: uint64 ticket_creation_time;
@@ -2490,6 +2491,9 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
needed += 4; /* max_early_data_size */
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ needed += 2; /* record_size_limit */
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
#if defined(MBEDTLS_HAVE_TIME)
needed += 8; /* ticket_creation_time or ticket_reception_time */
@@ -2534,6 +2538,10 @@
MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0);
p += 4;
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ MBEDTLS_PUT_UINT16_BE(session->record_size_limit, p, 0);
+ p += 2;
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
@@ -2610,6 +2618,13 @@
session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
@@ -3372,6 +3387,31 @@
}
}
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+
+size_t mbedtls_ssl_get_output_record_size_limit(const mbedtls_ssl_context *ssl)
+{
+ const size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
+ size_t record_size_limit = max_len;
+
+ if (ssl->session != NULL &&
+ ssl->session->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN &&
+ ssl->session->record_size_limit < max_len) {
+ record_size_limit = ssl->session->record_size_limit;
+ }
+
+ // TODO: this is currently untested
+ /* During a handshake, use the value being negotiated */
+ if (ssl->session_negotiate != NULL &&
+ ssl->session_negotiate->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN &&
+ ssl->session_negotiate->record_size_limit < max_len) {
+ record_size_limit = ssl->session_negotiate->record_size_limit;
+ }
+
+ return record_size_limit;
+}
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl)
{
@@ -3458,6 +3498,7 @@
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
+ !defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) && \
!defined(MBEDTLS_SSL_PROTO_DTLS)
(void) ssl;
#endif
@@ -3470,6 +3511,30 @@
}
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ const size_t record_size_limit = mbedtls_ssl_get_output_record_size_limit(ssl);
+
+ if (max_len > record_size_limit) {
+ max_len = record_size_limit;
+ }
+#endif
+
+ if (ssl->transform_out != NULL &&
+ ssl->transform_out->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
+ /*
+ * In TLS 1.3 case, when records are protected, `max_len` as computed
+ * above is the maximum length of the TLSInnerPlaintext structure that
+ * along the plaintext payload contains the inner content type (one byte)
+ * and some zero padding. Given the algorithm used for padding
+ * in mbedtls_ssl_encrypt_buf(), compute the maximum length for
+ * the plaintext payload. Round down to a multiple of
+ * MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY and
+ * subtract 1.
+ */
+ max_len = ((max_len / MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY) *
+ MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY) - 1;
+ }
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (mbedtls_ssl_get_current_mtu(ssl) != 0) {
const size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
@@ -3492,7 +3557,8 @@
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
- !defined(MBEDTLS_SSL_PROTO_DTLS)
+ !defined(MBEDTLS_SSL_PROTO_DTLS) && \
+ !defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
((void) ssl);
#endif
@@ -5052,23 +5118,17 @@
// == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512)
#endif
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
- defined(MBEDTLS_MD_CAN_SHA512)
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_MD_CAN_SHA512)
MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512,
-#endif \
- /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_MD_CAN_SHA512 */
+#endif
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
- defined(MBEDTLS_MD_CAN_SHA384)
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_MD_CAN_SHA384)
MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384,
-#endif \
- /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_MD_CAN_SHA384 */
+#endif
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
- defined(MBEDTLS_MD_CAN_SHA256)
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_MD_CAN_SHA256)
MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
-#endif \
- /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_MD_CAN_SHA256 */
+#endif
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA512)
MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512,
@@ -5088,42 +5148,47 @@
/* NOTICE: see above */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static uint16_t ssl_tls12_preset_default_sig_algs[] = {
+
#if defined(MBEDTLS_MD_CAN_SHA512)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512),
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512,
-#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+#endif
#if defined(MBEDTLS_RSA_C)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA512),
#endif
-#endif /* MBEDTLS_MD_CAN_SHA512*/
+#endif /* MBEDTLS_MD_CAN_SHA512 */
+
#if defined(MBEDTLS_MD_CAN_SHA384)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384),
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384,
-#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+#endif
#if defined(MBEDTLS_RSA_C)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384),
#endif
-#endif /* MBEDTLS_MD_CAN_SHA384*/
+#endif /* MBEDTLS_MD_CAN_SHA384 */
+
#if defined(MBEDTLS_MD_CAN_SHA256)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256),
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
-#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+#endif
#if defined(MBEDTLS_RSA_C)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA256),
#endif
-#endif /* MBEDTLS_MD_CAN_SHA256*/
+#endif /* MBEDTLS_MD_CAN_SHA256 */
+
MBEDTLS_TLS_SIG_NONE
};
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
/* NOTICE: see above */
static uint16_t ssl_preset_suiteb_sig_algs[] = {
@@ -5141,38 +5206,25 @@
// == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384)
#endif
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
- defined(MBEDTLS_MD_CAN_SHA256)
- MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
-#endif \
- /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_MD_CAN_SHA256*/
-
-#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256)
- MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256,
-#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA256*/
-
MBEDTLS_TLS_SIG_NONE
};
/* NOTICE: see above */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
+
#if defined(MBEDTLS_MD_CAN_SHA256)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256),
#endif
-#if defined(MBEDTLS_RSA_C)
- MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA256),
-#endif
-#endif /* MBEDTLS_MD_CAN_SHA256*/
+#endif /* MBEDTLS_MD_CAN_SHA256 */
+
#if defined(MBEDTLS_MD_CAN_SHA384)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384),
#endif
-#if defined(MBEDTLS_RSA_C)
- MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384),
-#endif
-#endif /* MBEDTLS_MD_CAN_SHA256*/
+#endif /* MBEDTLS_MD_CAN_SHA384 */
+
MBEDTLS_TLS_SIG_NONE
};
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index ae11364..5c668bd 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -621,7 +621,7 @@
/* Skip writing extension if no PSK key exchange mode
* is enabled in the config.
*/
- if (!mbedtls_ssl_conf_tls13_some_psk_enabled(ssl)) {
+ if (!mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl)) {
MBEDTLS_SSL_DEBUG_MSG(3, ("skip psk_key_exchange_modes extension"));
return 0;
}
@@ -640,14 +640,14 @@
*/
p += 5;
- if (mbedtls_ssl_conf_tls13_psk_ephemeral_enabled(ssl)) {
+ if (mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl)) {
*p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE;
ke_modes_len++;
MBEDTLS_SSL_DEBUG_MSG(4, ("Adding PSK-ECDHE key exchange mode"));
}
- if (mbedtls_ssl_conf_tls13_psk_enabled(ssl)) {
+ if (mbedtls_ssl_conf_tls13_is_psk_enabled(ssl)) {
*p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE;
ke_modes_len++;
@@ -684,8 +684,8 @@
mbedtls_ssl_session *session = ssl->session_negotiate;
return ssl->handshake->resume &&
session != NULL && session->ticket != NULL &&
- mbedtls_ssl_conf_tls13_check_kex_modes(
- ssl, mbedtls_ssl_session_get_ticket_flags(
+ mbedtls_ssl_conf_tls13_is_kex_mode_enabled(
+ ssl, mbedtls_ssl_tls13_session_get_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL));
}
@@ -695,7 +695,7 @@
mbedtls_ssl_session *session = ssl->session_negotiate;
return ssl->handshake->resume &&
session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
- mbedtls_ssl_session_ticket_allow_early_data(session) &&
+ mbedtls_ssl_tls13_session_ticket_allow_early_data(session) &&
mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, session->ciphersuite);
}
#endif
@@ -1160,8 +1160,17 @@
}
p += ext_len;
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ ret = mbedtls_ssl_tls13_write_record_size_limit_ext(
+ ssl, p, end, &ext_len);
+ if (ret != 0) {
+ return ret;
+ }
+ p += ext_len;
+#endif
+
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
- if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
+ if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
ret = ssl_tls13_write_key_share_ext(ssl, p, end, &ext_len);
if (ret != 0) {
return ret;
@@ -1171,7 +1180,7 @@
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (mbedtls_ssl_conf_tls13_some_psk_enabled(ssl) &&
+ if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
ssl_tls13_early_data_has_valid_ticket(ssl) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
@@ -1457,7 +1466,7 @@
ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
buf, (size_t) (end - buf)));
- if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
+ if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
ret = ssl_tls13_reset_key_share(ssl);
if (ret != 0) {
return ret;
@@ -1499,7 +1508,7 @@
* in the ClientHello.
* In a PSK only key exchange that what we expect.
*/
- if (!mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
+ if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
MBEDTLS_SSL_DEBUG_MSG(1,
("Unexpected HRR in pure PSK key exchange."));
MBEDTLS_SSL_PEND_FATAL_ALERT(
@@ -1776,7 +1785,7 @@
case MBEDTLS_TLS_EXT_KEY_SHARE:
MBEDTLS_SSL_DEBUG_MSG(3, ("found key_shares extension"));
- if (!mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
+ if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
goto cleanup;
}
@@ -1879,7 +1888,7 @@
goto cleanup;
}
- if (!mbedtls_ssl_conf_tls13_check_kex_modes(
+ if (!mbedtls_ssl_conf_tls13_is_kex_mode_enabled(
ssl, handshake->key_exchange_mode)) {
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
MBEDTLS_SSL_DEBUG_MSG(
@@ -2113,12 +2122,11 @@
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
ssl, p, p + extension_data_len);
-
- /* TODO: Return unconditionally here until we handle the record
- * size limit correctly. Once handled correctly, only return in
- * case of errors. */
- return ret;
-
+ if (ret != 0) {
+ MBEDTLS_SSL_DEBUG_RET(
+ 1, ("mbedtls_ssl_tls13_parse_record_size_limit_ext"), ret);
+ return ret;
+ }
break;
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
@@ -2132,6 +2140,17 @@
p += extension_data_len;
}
+ if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) &&
+ (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(MAX_FRAGMENT_LENGTH))) {
+ MBEDTLS_SSL_DEBUG_MSG(3,
+ (
+ "Record size limit extension cannot be used with max fragment length extension"));
+ MBEDTLS_SSL_PEND_FATAL_ALERT(
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
+ MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
+ return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
+ }
+
MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
handshake->received_extensions);
@@ -2685,7 +2704,7 @@
MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 4);
session->max_early_data_size = MBEDTLS_GET_UINT32_BE(buf, 0);
- mbedtls_ssl_session_set_ticket_flags(
+ mbedtls_ssl_tls13_session_set_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
MBEDTLS_SSL_DEBUG_MSG(
3, ("received max_early_data_size: %u",
@@ -2836,7 +2855,7 @@
session->ticket_len = ticket_len;
/* Clear all flags in ticket_flags */
- mbedtls_ssl_session_clear_ticket_flags(
+ mbedtls_ssl_tls13_session_clear_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
@@ -2923,7 +2942,7 @@
session->resumption_key_len);
/* Set ticket_flags depends on the selected key exchange modes */
- mbedtls_ssl_session_set_ticket_flags(
+ mbedtls_ssl_tls13_session_set_ticket_flags(
session, ssl->conf->tls13_kex_modes);
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index fe2a2eb..47fa65c 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -1698,6 +1698,7 @@
}
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+
/* RFC 8449, section 4:
*
* The ExtensionData of the "record_size_limit" extension is
@@ -1731,27 +1732,56 @@
MBEDTLS_SSL_DEBUG_MSG(2, ("RecordSizeLimit: %u Bytes", record_size_limit));
- /* RFC 8449, section 4
+ /* RFC 8449, section 4:
*
* Endpoints MUST NOT send a "record_size_limit" extension with a value
* smaller than 64. An endpoint MUST treat receipt of a smaller value
* as a fatal error and generate an "illegal_parameter" alert.
*/
if (record_size_limit < MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid record size limit : %u Bytes",
+ record_size_limit));
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
- MBEDTLS_SSL_DEBUG_MSG(
- 2, ("record_size_limit extension is still in development. Aborting handshake."));
+ ssl->session_negotiate->record_size_limit = record_size_limit;
- MBEDTLS_SSL_PEND_FATAL_ALERT(
- MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
- MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION);
- return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
+ return 0;
}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+int mbedtls_ssl_tls13_write_record_size_limit_ext(mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *out_len)
+{
+ unsigned char *p = buf;
+ *out_len = 0;
+
+ MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_IN_CONTENT_LEN >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN,
+ "MBEDTLS_SSL_IN_CONTENT_LEN is less than the "
+ "minimum record size limit");
+
+ MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
+
+ MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT, p, 0);
+ MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH,
+ p, 2);
+ MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_IN_CONTENT_LEN, p, 4);
+
+ *out_len = 6;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("Sent RecordSizeLimit: %d Bytes",
+ MBEDTLS_SSL_IN_CONTENT_LEN));
+
+ mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT);
+
+ return 0;
+}
+
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
#endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index fe7a674..6e2866a 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -95,9 +95,9 @@
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_check_psk_key_exchange(mbedtls_ssl_context *ssl);
+static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_check_psk_ephemeral_key_exchange(mbedtls_ssl_context *ssl);
+static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_identity_match_ticket(
@@ -175,12 +175,12 @@
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
key_exchanges = 0;
- if (mbedtls_ssl_session_ticket_allow_psk_ephemeral(session) &&
- ssl_tls13_check_psk_ephemeral_key_exchange(ssl)) {
+ if (mbedtls_ssl_tls13_session_ticket_allow_psk_ephemeral(session) &&
+ ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
}
- if (mbedtls_ssl_session_ticket_allow_psk(session) &&
- ssl_tls13_check_psk_key_exchange(ssl)) {
+ if (mbedtls_ssl_tls13_session_ticket_allow_psk(session) &&
+ ssl_tls13_key_exchange_is_psk_available(ssl)) {
key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
}
@@ -1003,12 +1003,12 @@
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_ticket_permission_check(mbedtls_ssl_context *ssl,
- unsigned int kex_mode)
+static int ssl_tls13_ticket_is_kex_mode_permitted(mbedtls_ssl_context *ssl,
+ unsigned int kex_mode)
{
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
if (ssl->handshake->resume) {
- if (mbedtls_ssl_session_check_ticket_flags(
+ if (!mbedtls_ssl_tls13_session_ticket_has_flags(
ssl->session_negotiate, kex_mode)) {
return 0;
}
@@ -1022,10 +1022,10 @@
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_check_ephemeral_key_exchange(mbedtls_ssl_context *ssl)
+static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ssl)
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
- return mbedtls_ssl_conf_tls13_ephemeral_enabled(ssl) &&
+ return mbedtls_ssl_conf_tls13_is_ephemeral_enabled(ssl) &&
ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(ssl);
#else
((void) ssl);
@@ -1034,13 +1034,13 @@
}
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_check_psk_key_exchange(mbedtls_ssl_context *ssl)
+static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
- return ssl_tls13_ticket_permission_check(
+ return ssl_tls13_ticket_is_kex_mode_permitted(
ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
- mbedtls_ssl_conf_tls13_psk_enabled(ssl) &&
- mbedtls_ssl_tls13_psk_enabled(ssl) &&
+ mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) &&
+ mbedtls_ssl_tls13_is_psk_supported(ssl) &&
ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl);
#else
((void) ssl);
@@ -1049,13 +1049,13 @@
}
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_check_psk_ephemeral_key_exchange(mbedtls_ssl_context *ssl)
+static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
- return ssl_tls13_ticket_permission_check(
+ return ssl_tls13_ticket_is_kex_mode_permitted(
ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
- mbedtls_ssl_conf_tls13_psk_ephemeral_enabled(ssl) &&
- mbedtls_ssl_tls13_psk_ephemeral_enabled(ssl) &&
+ mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) &&
+ mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) &&
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl);
#else
((void) ssl);
@@ -1083,17 +1083,17 @@
ssl->handshake->key_exchange_mode =
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
- if (ssl_tls13_check_psk_ephemeral_key_exchange(ssl)) {
+ if (ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
ssl->handshake->key_exchange_mode =
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral"));
} else
- if (ssl_tls13_check_ephemeral_key_exchange(ssl)) {
+ if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) {
ssl->handshake->key_exchange_mode =
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral"));
} else
- if (ssl_tls13_check_psk_key_exchange(ssl)) {
+ if (ssl_tls13_key_exchange_is_psk_available(ssl)) {
ssl->handshake->key_exchange_mode =
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk"));
@@ -1699,14 +1699,11 @@
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
ssl, p, extension_data_end);
-
- /*
- * TODO: Return unconditionally here until we handle the record
- * size limit correctly.
- * Once handled correctly, only return in case of errors.
- */
- return ret;
-
+ if (ret != 0) {
+ MBEDTLS_SSL_DEBUG_RET(
+ 1, ("mbedtls_ssl_tls13_parse_record_size_limit_ext"), ret);
+ return ret;
+ }
break;
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
@@ -1737,8 +1734,8 @@
* - The content up to but excluding the PSK extension, if present.
*/
/* If we've settled on a PSK-based exchange, parse PSK identity ext */
- if (ssl_tls13_check_psk_key_exchange(ssl) ||
- ssl_tls13_check_psk_ephemeral_key_exchange(ssl)) {
+ if (ssl_tls13_key_exchange_is_psk_available(ssl) ||
+ ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
ret = handshake->update_checksum(ssl, buf,
pre_shared_key_ext - buf);
if (0 != ret) {
@@ -1845,7 +1842,7 @@
}
- if (!mbedtls_ssl_session_ticket_allow_early_data(ssl->session_negotiate)) {
+ if (!mbedtls_ssl_tls13_session_ticket_allow_early_data(ssl->session_negotiate)) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, early_data not allowed in ticket "
@@ -1928,13 +1925,23 @@
* by MBEDTLS_SSL_PROC_CHK_NEG. */
/*
- * Version 1.2 of the protocol has been chosen, set the
+ * Version 1.2 of the protocol has to be used for the handshake.
+ * If TLS 1.2 is not supported, abort the handshake. Otherwise, set the
* ssl->keep_current_message flag for the ClientHello to be kept and parsed
* as a TLS 1.2 ClientHello. We also change ssl->tls_version to
* MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step()
* will dispatch to the TLS 1.2 state machine.
*/
if (SSL_CLIENT_HELLO_TLS1_2 == parse_client_hello_ret) {
+ /* Check if server supports TLS 1.2 */
+ if (!mbedtls_ssl_conf_is_tls12_enabled(ssl->conf)) {
+ MBEDTLS_SSL_DEBUG_MSG(
+ 1, ("TLS 1.2 not supported."));
+ MBEDTLS_SSL_PEND_FATAL_ALERT(
+ MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION,
+ MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION);
+ return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
+ }
ssl->keep_current_message = 1;
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
return 0;
@@ -2533,6 +2540,17 @@
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ if (ssl->handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) {
+ ret = mbedtls_ssl_tls13_write_record_size_limit_ext(
+ ssl, p, end, &output_len);
+ if (ret != 0) {
+ return ret;
+ }
+ p += output_len;
+ }
+#endif
+
extensions_len = (p - p_extensions_len) - 2;
MBEDTLS_PUT_UINT16_BE(extensions_len, p_extensions_len, 0);
@@ -3072,7 +3090,7 @@
* expected to be resolved with issue#6395.
*/
/* Sent NewSessionTicket message only when client supports PSK */
- if (mbedtls_ssl_tls13_some_psk_enabled(ssl)) {
+ if (mbedtls_ssl_tls13_is_some_psk_supported(ssl)) {
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
} else
@@ -3131,17 +3149,17 @@
#endif
/* Set ticket_flags depends on the advertised psk key exchange mode */
- mbedtls_ssl_session_clear_ticket_flags(
+ mbedtls_ssl_tls13_session_clear_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
- mbedtls_ssl_session_set_ticket_flags(
+ mbedtls_ssl_tls13_session_set_ticket_flags(
session, ssl->handshake->tls13_kex_modes);
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED &&
ssl->conf->max_early_data_size > 0) {
- mbedtls_ssl_session_set_ticket_flags(
+ mbedtls_ssl_tls13_session_set_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -3321,7 +3339,7 @@
p += 2;
#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (mbedtls_ssl_session_ticket_allow_early_data(session)) {
+ if (mbedtls_ssl_tls13_session_ticket_allow_early_data(session)) {
size_t output_len;
if ((ret = mbedtls_ssl_tls13_write_early_data_ext(
diff --git a/library/x509_create.c b/library/x509_create.c
index 8f31c3b..f7a17e7 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -382,6 +382,10 @@
{
mbedtls_asn1_named_data *cur;
+ if (val_len > (SIZE_MAX - 1)) {
+ return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+ }
+
if ((cur = mbedtls_asn1_store_named_data(head, oid, oid_len,
NULL, val_len + 1)) == NULL) {
return MBEDTLS_ERR_X509_ALLOC_FAILED;
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index e6ebd8e..598d38c 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3521,7 +3521,7 @@
mbedtls_printf(" [ Record expansion is unknown ]\n");
}
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) || defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
mbedtls_printf(" [ Maximum incoming record payload length is %u ]\n",
(unsigned int) mbedtls_ssl_get_max_in_record_payload(&ssl));
mbedtls_printf(" [ Maximum outgoing record payload length is %u ]\n",
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 755a731..6f7f69b 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -507,7 +507,7 @@
char md5, ripemd160, sha1, sha256, sha512,
sha3_224, sha3_256, sha3_384, sha3_512,
des3, des,
- aes_cbc, aes_cfb128, aes_cfb8, aes_gcm, aes_ccm, aes_xts, chachapoly,
+ aes_cbc, aes_cfb128, aes_cfb8, aes_ctr, aes_gcm, aes_ccm, aes_xts, chachapoly,
aes_cmac, des3_cmac,
aria, camellia, chacha20,
poly1305,
@@ -571,6 +571,8 @@
todo.aes_cfb128 = 1;
} else if (strcmp(argv[i], "aes_cfb8") == 0) {
todo.aes_cfb8 = 1;
+ } else if (strcmp(argv[i], "aes_ctr") == 0) {
+ todo.aes_ctr = 1;
} else if (strcmp(argv[i], "aes_xts") == 0) {
todo.aes_xts = 1;
} else if (strcmp(argv[i], "aes_gcm") == 0) {
@@ -774,6 +776,31 @@
mbedtls_aes_free(&aes);
}
#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ if (todo.aes_ctr) {
+ int keysize;
+ mbedtls_aes_context aes;
+
+ uint8_t stream_block[16];
+ size_t nc_off;
+
+ mbedtls_aes_init(&aes);
+ for (keysize = 128; keysize <= 256; keysize += 64) {
+ mbedtls_snprintf(title, sizeof(title), "AES-CTR-%d", keysize);
+
+ memset(buf, 0, sizeof(buf));
+ memset(tmp, 0, sizeof(tmp));
+ memset(stream_block, 0, sizeof(stream_block));
+ nc_off = 0;
+
+ CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
+
+ TIME_AND_TSC(title, mbedtls_aes_crypt_ctr(&aes, BUFSIZE, &nc_off, tmp, stream_block,
+ buf, buf));
+ }
+ mbedtls_aes_free(&aes);
+ }
+#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
if (todo.aes_xts) {
int keysize;
diff --git a/scripts/config.py b/scripts/config.py
index d5fb85e..ab0e5ea 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -207,7 +207,6 @@
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY', # interacts with *_USE_ARMV8_A_CRYPTO_IF_PRESENT
'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # setting *_USE_ARMV8_A_CRYPTO is sufficient
- 'MBEDTLS_SSL_RECORD_SIZE_LIMIT', # in development, currently breaks other tests
'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
'MBEDTLS_X509_REMOVE_INFO', # removes a feature
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 8f899c0..44930d2 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -74,6 +74,7 @@
# * component_check_XXX: quick tests that aren't worth parallelizing.
# * component_build_XXX: build things but don't run them.
# * component_test_XXX: build and test.
+# * component_release_XXX: tests that the CI should skip during PR testing.
# * support_XXX: if support_XXX exists and returns false then
# component_XXX is not run by default.
# * post_XXX: things to do after running the tests.
@@ -750,7 +751,7 @@
# Require OpenSSL and GnuTLS if running any tests (as opposed to
# only doing builds). Not all tests run OpenSSL and GnuTLS, but this
# is a good enough approximation in practice.
- *" test_"*)
+ *" test_"* | *" release_test_"*)
# To avoid setting OpenSSL and GnuTLS for each call to compat.sh
# and ssl-opt.sh, we just export the variables they require.
export OPENSSL="$OPENSSL"
@@ -1540,7 +1541,7 @@
make test
}
-component_test_full_no_cipher () {
+component_test_full_no_cipher_no_psa_crypto () {
msg "build: full no CIPHER no PSA_CRYPTO_C"
scripts/config.py full
scripts/config.py unset MBEDTLS_CIPHER_C
@@ -1565,8 +1566,8 @@
}
# This is a common configurator and test function that is used in:
-# - component_test_full_no_cipher_with_crypto
-# - component_test_full_no_cipher_with_crypto_config
+# - component_test_full_no_cipher_with_psa_crypto
+# - component_test_full_no_cipher_with_psa_crypto_config
# It accepts 2 input parameters:
# - $1: boolean value which basically reflects status of MBEDTLS_PSA_CRYPTO_CONFIG
# - $2: a text string which describes the test component
@@ -1614,11 +1615,11 @@
make test
}
-component_test_full_no_cipher_with_crypto() {
+component_test_full_no_cipher_with_psa_crypto() {
common_test_full_no_cipher_with_psa_crypto 0 "full no CIPHER no CRYPTO_CONFIG"
}
-component_test_full_no_cipher_with_crypto_config() {
+component_test_full_no_cipher_with_psa_crypto_config() {
common_test_full_no_cipher_with_psa_crypto 1 "full no CIPHER"
}
@@ -3741,9 +3742,9 @@
}
# This is a common configuration function used in:
-# - component_test_psa_crypto_config_accel_cipher_aead
-# - component_test_psa_crypto_config_reference_cipher_aead
-common_psa_crypto_config_accel_cipher_aead() {
+# - component_test_psa_crypto_config_accel_cipher_aead_cmac
+# - component_test_psa_crypto_config_reference_cipher_aead_cmac
+common_psa_crypto_config_accel_cipher_aead_cmac() {
# Start from the full config
helper_libtestdriver1_adjust_config "full"
@@ -3751,12 +3752,12 @@
}
# The 2 following test components, i.e.
-# - component_test_psa_crypto_config_accel_cipher_aead
-# - component_test_psa_crypto_config_reference_cipher_aead
+# - component_test_psa_crypto_config_accel_cipher_aead_cmac
+# - component_test_psa_crypto_config_reference_cipher_aead_cmac
# are meant to be used together in analyze_outcomes.py script in order to test
# driver's coverage for ciphers and AEADs.
-component_test_psa_crypto_config_accel_cipher_aead () {
- msg "build: full config with accelerated cipher and AEAD"
+component_test_psa_crypto_config_accel_cipher_aead_cmac () {
+ msg "build: full config with accelerated cipher inc. AEAD and CMAC"
loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 ALG_CTR ALG_CFB \
ALG_OFB ALG_XTS ALG_STREAM_CIPHER ALG_CCM_STAR_NO_TAG \
@@ -3766,7 +3767,7 @@
# Configure
# ---------
- common_psa_crypto_config_accel_cipher_aead
+ common_psa_crypto_config_accel_cipher_aead_cmac
# Disable the things that are being accelerated
scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
@@ -3810,29 +3811,29 @@
# Run the tests
# -------------
- msg "test: full config with accelerated cipher and AEAD"
+ msg "test: full config with accelerated cipher inc. AEAD and CMAC"
make test
- msg "ssl-opt: full config with accelerated cipher and AEAD"
+ msg "ssl-opt: full config with accelerated cipher inc. AEAD and CMAC"
tests/ssl-opt.sh
- msg "compat.sh: full config with accelerated cipher and AEAD"
+ msg "compat.sh: full config with accelerated cipher inc. AEAD and CMAC"
tests/compat.sh -V NO -p mbedTLS
}
-component_test_psa_crypto_config_reference_cipher_aead () {
- msg "build: full config with non-accelerated cipher and AEAD"
- common_psa_crypto_config_accel_cipher_aead
+component_test_psa_crypto_config_reference_cipher_aead_cmac () {
+ msg "build: full config with non-accelerated cipher inc. AEAD and CMAC"
+ common_psa_crypto_config_accel_cipher_aead_cmac
make
- msg "test: full config with non-accelerated cipher and AEAD"
+ msg "test: full config with non-accelerated cipher inc. AEAD and CMAC"
make test
- msg "ssl-opt: full config with non-accelerated cipher and AEAD"
+ msg "ssl-opt: full config with non-accelerated cipher inc. AEAD and CMAC"
tests/ssl-opt.sh
- msg "compat.sh: full config with non-accelerated cipher and AEAD"
+ msg "compat.sh: full config with non-accelerated cipher inc. AEAD and CMAC"
tests/compat.sh -V NO -p mbedTLS
}
@@ -5645,6 +5646,7 @@
component_test_tls13_only () {
msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3, without MBEDTLS_SSL_PROTO_TLS1_2"
scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+ scripts/config.py set MBEDTLS_SSL_RECORD_SIZE_LIMIT
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test: TLS 1.3 only, all key exchange modes enabled"
@@ -5807,21 +5809,6 @@
tests/ssl-opt.sh
}
-component_test_tls13_only_record_size_limit () {
- msg "build: TLS 1.3 only from default, record size limit extension enabled"
- scripts/config.py set MBEDTLS_SSL_RECORD_SIZE_LIMIT
- make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
- msg "test_suite_ssl: TLS 1.3 only, record size limit extension enabled"
- cd tests; ./test_suite_ssl; cd ..
-
- msg "ssl-opt.sh: (TLS 1.3 only, record size limit extension tests only)"
- # Both the server and the client will currently abort the handshake when they encounter the
- # record size limit extension. There is no way to prevent gnutls-cli from sending the extension
- # which makes all G_NEXT_CLI + P_SRV tests fail. Thus, run only the tests for the this extension.
- tests/ssl-opt.sh -f "Record Size Limit"
-}
-
component_build_mingw () {
msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 lib programs
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 3b11ca2..a867971 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -240,16 +240,16 @@
}
}
},
- 'analyze_driver_vs_reference_cipher_aead': {
+ 'analyze_driver_vs_reference_cipher_aead_cmac': {
'test_function': do_analyze_driver_vs_reference,
'args': {
- 'component_ref': 'test_psa_crypto_config_reference_cipher_aead',
- 'component_driver': 'test_psa_crypto_config_accel_cipher_aead',
+ 'component_ref': 'test_psa_crypto_config_reference_cipher_aead_cmac',
+ 'component_driver': 'test_psa_crypto_config_accel_cipher_aead_cmac',
# Modules replaced by drivers.
'ignored_suites': [
# low-level (block/stream) cipher modules
'aes', 'aria', 'camellia', 'des', 'chacha20',
- # AEAD modes
+ # AEAD modes and CMAC
'ccm', 'chachapoly', 'cmac', 'gcm',
# The Cipher abstraction layer
'cipher',
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index d02d305..3d8937d 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -1776,6 +1776,10 @@
}
#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ session->record_size_limit = 2048;
+#endif
+
return 0;
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 4762285..26c5a79 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -4481,7 +4481,7 @@
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Max fragment length: enabled, default" \
- "$P_SRV debug_level=3" \
+ "$P_SRV debug_level=3 force_version=tls12" \
"$P_CLI debug_level=3" \
0 \
-c "Maximum incoming record payload length is $MAX_CONTENT_LEN" \
@@ -4496,7 +4496,7 @@
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Max fragment length: enabled, default, larger message" \
- "$P_SRV debug_level=3" \
+ "$P_SRV debug_level=3 force_version=tls12" \
"$P_CLI debug_level=3 request_size=$(( $MAX_CONTENT_LEN + 1))" \
0 \
-c "Maximum incoming record payload length is $MAX_CONTENT_LEN" \
@@ -4534,7 +4534,7 @@
requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Max fragment length: disabled, larger message" \
- "$P_SRV debug_level=3" \
+ "$P_SRV debug_level=3 force_version=tls12" \
"$P_CLI debug_level=3 request_size=$(( $MAX_CONTENT_LEN + 1))" \
0 \
-C "Maximum incoming record payload length is 16384" \
@@ -4548,7 +4548,7 @@
requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Max fragment length, DTLS: disabled, larger message" \
- "$P_SRV debug_level=3 dtls=1" \
+ "$P_SRV debug_level=3 dtls=1 force_version=tls12" \
"$P_CLI debug_level=3 dtls=1 request_size=$(( $MAX_CONTENT_LEN + 1))" \
1 \
-C "Maximum incoming record payload length is 16384" \
@@ -4836,38 +4836,373 @@
requires_gnutls_tls1_3
requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
-run_test "Record Size Limit: TLS 1.3: Server-side parsing, debug output and fatal alert" \
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server-side parsing and debug output" \
"$P_SRV debug_level=3 force_version=tls13" \
"$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4" \
- 1 \
- -c "Preparing extension (Record Size Limit/28) for 'client hello'" \
- -c "Sending extension Record Size Limit/28 (2 bytes)" \
- -s "ClientHello: record_size_limit(28) extension received."\
- -s "found record_size_limit extension" \
+ 0 \
-s "RecordSizeLimit: 16385 Bytes" \
- -c "Received alert \[110]: An unsupported extension was sent"
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 16383" \
+ -s "bytes written in 1 fragments"
requires_gnutls_tls1_3
requires_gnutls_record_size_limit
-requires_gnutls_next_disable_tls13_compat
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
-run_test "Record Size Limit: TLS 1.3: Client-side parsing, debug output and fatal alert" \
- "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%DISABLE_TLS13_COMPAT_MODE --disable-client-cert -d 4" \
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client-side parsing and debug output" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL --disable-client-cert -d 4" \
"$P_CLI debug_level=4 force_version=tls13" \
0 \
- -s "Preparing extension (Record Size Limit/28) for 'encrypted extensions'"
-# The P_CLI can not yet send the Record Size Limit extension. Thus, the G_NEXT_SRV does not send
-# a response in its EncryptedExtensions record.
-# -s "Parsing extension 'Record Size Limit/28 (2 bytes)" \
-# -s "Sending extension Record Size Limit/28 (2 bytes)" \
-# -c "EncryptedExtensions: record_size_limit(28) extension received."\
-# -c "found record_size_limit extension" \
-# -c "RecordSizeLimit: 16385 Bytes" \
-# -s "Received alert \[110]: An unsupported extension was sent"
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "EncryptedExtensions: record_size_limit(28) extension received." \
+ -c "RecordSizeLimit: 16385 Bytes" \
+
+# In the following tests, --recordsize is the value used by the G_NEXT_CLI (3.7.2) to configure the
+# maximum record size using gnutls_record_set_max_size()
+# (https://gnutls.org/reference/gnutls-gnutls.html#gnutls-record-set-max-size).
+# There is currently a lower limit of 512, caused by gnutls_record_set_max_size()
+# not respecting the "%ALLOW_SMALL_RECORDS" priority string and not using the
+# more recent function gnutls_record_set_max_recv_size()
+# (https://gnutls.org/reference/gnutls-gnutls.html#gnutls-record-set-max-recv-size).
+# There is currently an upper limit of 4096, caused by the cli arg parser:
+# https://gitlab.com/gnutls/gnutls/-/blob/3.7.2/src/cli-args.def#L395.
+# Thus, these tests are currently limited to the value range 512-4096.
+# Also, the value sent in the extension will be one larger than the value
+# set at the command line:
+# https://gitlab.com/gnutls/gnutls/-/blob/3.7.2/lib/ext/record_size_limit.c#L142
+
+# Currently test certificates being used do not fit in 513 record size limit
+# so for 513 record size limit tests we use preshared key to avoid sending
+# the certificate.
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (513), 1 fragment" \
+ "$P_SRV debug_level=3 force_version=tls13 tls13_kex_modes=psk \
+ psk_list=Client_identity,6162636465666768696a6b6c6d6e6f70 \
+ response_size=256" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK --recordsize 512 \
+ --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70" \
+ 0 \
+ -s "RecordSizeLimit: 513 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 511" \
+ -s "256 bytes written in 1 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (513), 2 fragments" \
+ "$P_SRV debug_level=3 force_version=tls13 tls13_kex_modes=psk \
+ psk_list=Client_identity,6162636465666768696a6b6c6d6e6f70 \
+ response_size=768" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK --recordsize 512 \
+ --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70" \
+ 0 \
+ -s "RecordSizeLimit: 513 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 511" \
+ -s "768 bytes written in 2 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (513), 3 fragments" \
+ "$P_SRV debug_level=3 force_version=tls13 tls13_kex_modes=psk \
+ psk_list=Client_identity,6162636465666768696a6b6c6d6e6f70 \
+ response_size=1280" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK --recordsize 512 \
+ --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70" \
+ 0 \
+ -s "RecordSizeLimit: 513 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 511" \
+ -s "1280 bytes written in 3 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (1024), 1 fragment" \
+ "$P_SRV debug_level=3 force_version=tls13 response_size=512" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4 --recordsize 1023" \
+ 0 \
+ -s "RecordSizeLimit: 1024 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 1023" \
+ -s "512 bytes written in 1 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (1024), 2 fragments" \
+ "$P_SRV debug_level=3 force_version=tls13 response_size=1536" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4 --recordsize 1023" \
+ 0 \
+ -s "RecordSizeLimit: 1024 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 1023" \
+ -s "1536 bytes written in 2 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (1024), 3 fragments" \
+ "$P_SRV debug_level=3 force_version=tls13 response_size=2560" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4 --recordsize 1023" \
+ 0 \
+ -s "RecordSizeLimit: 1024 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 1023" \
+ -s "2560 bytes written in 3 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (4096), 1 fragment" \
+ "$P_SRV debug_level=3 force_version=tls13 response_size=2048" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4 --recordsize 4095" \
+ 0 \
+ -s "RecordSizeLimit: 4096 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 4095" \
+ -s "2048 bytes written in 1 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (4096), 2 fragments" \
+ "$P_SRV debug_level=3 force_version=tls13 response_size=6144" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4 --recordsize 4095" \
+ 0 \
+ -s "RecordSizeLimit: 4096 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 4095" \
+ -s "6144 bytes written in 2 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Server complies with record size limit (4096), 3 fragments" \
+ "$P_SRV debug_level=3 force_version=tls13 response_size=10240" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -d 4 --recordsize 4095" \
+ 0 \
+ -s "RecordSizeLimit: 4096 Bytes" \
+ -s "ClientHello: record_size_limit(28) extension exists." \
+ -s "Sent RecordSizeLimit: 16384 Bytes" \
+ -s "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -s "Maximum outgoing record payload length is 4095" \
+ -s "10240 bytes written in 3 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (513), 1 fragment" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --disable-client-cert --recordsize 512" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=256" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 513 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 511" \
+ -c "256 bytes written in 1 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (513), 2 fragments" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --disable-client-cert --recordsize 512" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=768" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 513 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 511" \
+ -c "768 bytes written in 2 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (513), 3 fragments" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --disable-client-cert --recordsize 512" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=1280" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 513 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 511" \
+ -c "1280 bytes written in 3 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (1024), 1 fragment" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --recordsize 1023" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=512" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 1024 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 1023" \
+ -c "512 bytes written in 1 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (1024), 2 fragments" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --recordsize 1023" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=1536" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 1024 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 1023" \
+ -c "1536 bytes written in 2 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (1024), 3 fragments" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --recordsize 1023" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=2560" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 1024 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 1023" \
+ -c "2560 bytes written in 3 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (4096), 1 fragment" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --recordsize 4095" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=2048" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 4096 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 4095" \
+ -c "2048 bytes written in 1 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (4096), 2 fragments" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --recordsize 4095" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=6144" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 4096 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 4095" \
+ -c "6144 bytes written in 2 fragments"
+
+requires_gnutls_tls1_3
+requires_gnutls_record_size_limit
+requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3: Client complies with record size limit (4096), 3 fragments" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL -d 4 --recordsize 4095" \
+ "$P_CLI debug_level=4 force_version=tls13 request_size=10240" \
+ 0 \
+ -c "Sent RecordSizeLimit: 16384 Bytes" \
+ -c "ClientHello: record_size_limit(28) extension exists." \
+ -c "RecordSizeLimit: 4096 Bytes" \
+ -c "EncryptedExtensions: record_size_limit(28) extension exists." \
+ -c "Maximum outgoing record payload length is 4095" \
+ -c "10240 bytes written in 3 fragments"
+
+# TODO: For time being, we send fixed value of RecordSizeLimit defined by
+# MBEDTLS_SSL_IN_CONTENT_LEN. Once we support variable buffer length of
+# RecordSizeLimit, we need to modify value of RecordSizeLimit in below test.
+requires_config_value_equals "MBEDTLS_SSL_IN_CONTENT_LEN" 16384
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_RECORD_SIZE_LIMIT
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Record Size Limit: TLS 1.3 m->m: both peer comply with record size limit (default)" \
+ "$P_SRV debug_level=4 force_version=tls13" \
+ "$P_CLI debug_level=4" \
+ 0 \
+ -c "Sent RecordSizeLimit: $MAX_IN_LEN Bytes" \
+ -c "RecordSizeLimit: $MAX_IN_LEN Bytes" \
+ -s "RecordSizeLimit: $MAX_IN_LEN Bytes" \
+ -s "Sent RecordSizeLimit: $MAX_IN_LEN Bytes" \
+ -s "Maximum outgoing record payload length is 16383" \
+ -s "Maximum incoming record payload length is 16384"
+
+# End of Record size limit tests
# Tests for renegotiation
+# G_NEXT_SRV is used in renegotiation tests becuase of the increased
+# extensions limit since we exceed the limit in G_SRV when we send
+# TLS 1.3 extensions in the initial handshake.
+
# Renegotiation SCSV always added, regardless of SSL_RENEGOTIATION
run_test "Renegotiation: none, for reference" \
"$P_SRV debug_level=3 exchanges=2 auth_mode=optional" \
@@ -5198,7 +5533,7 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renegotiation: gnutls server strict, client-initiated" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
0 \
-c "client hello, adding renegotiation extension" \
@@ -5212,7 +5547,7 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renegotiation: gnutls server unsafe, client-initiated default" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
1 \
-c "client hello, adding renegotiation extension" \
@@ -5226,7 +5561,7 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renegotiation: gnutls server unsafe, client-inititated no legacy" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
allow_legacy=0" \
1 \
@@ -5241,7 +5576,7 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renegotiation: gnutls server unsafe, client-inititated legacy" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
allow_legacy=1" \
0 \
@@ -5302,7 +5637,7 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renegotiation: DTLS, gnutls server, client-initiated" \
- "$G_SRV -u --mtu 4096" \
+ "$G_NEXT_SRV -u --mtu 4096" \
"$P_CLI debug_level=3 dtls=1 exchanges=1 renegotiation=1 renegotiate=1" \
0 \
-c "client hello, adding renegotiation extension" \
@@ -5317,7 +5652,7 @@
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renego ext: gnutls server strict, client default" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3" \
0 \
-c "found renegotiation extension" \
@@ -5327,7 +5662,7 @@
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renego ext: gnutls server unsafe, client default" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3" \
0 \
-C "found renegotiation extension" \
@@ -5337,7 +5672,7 @@
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renego ext: gnutls server unsafe, client break legacy" \
- "$G_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 allow_legacy=-1" \
1 \
-C "found renegotiation extension" \
@@ -8263,7 +8598,7 @@
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "mbedtls_ssl_get_bytes_avail: extra data (max)" \
- "$P_SRV buffer_size=100" \
+ "$P_SRV buffer_size=100 force_version=tls12" \
"$P_CLI request_size=$MAX_CONTENT_LEN" \
0 \
-s "Read from client: $MAX_CONTENT_LEN bytes read (100 + $((MAX_CONTENT_LEN - 100)))"
@@ -8452,20 +8787,20 @@
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "Large client packet TLS 1.3 AEAD" \
"$P_SRV" \
- "$P_CLI request_size=16384 \
+ "$P_CLI request_size=16383 \
force_ciphersuite=TLS1-3-AES-128-CCM-SHA256" \
0 \
- -c "16384 bytes written in $(fragments_for_write 16384) fragments" \
- -s "Read from client: $MAX_CONTENT_LEN bytes read"
+ -c "16383 bytes written in $(fragments_for_write 16383) fragments" \
+ -s "Read from client: 16383 bytes read"
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "Large client packet TLS 1.3 AEAD shorter tag" \
"$P_SRV" \
- "$P_CLI request_size=16384 \
+ "$P_CLI request_size=16383 \
force_ciphersuite=TLS1-3-AES-128-CCM-8-SHA256" \
0 \
- -c "16384 bytes written in $(fragments_for_write 16384) fragments" \
- -s "Read from client: $MAX_CONTENT_LEN bytes read"
+ -c "16383 bytes written in $(fragments_for_write 16383) fragments" \
+ -s "Read from client: 16383 bytes read"
# The tests below fail when the server's OUT_CONTENT_LEN is less than 16384.
run_test "Large server packet TLS 1.2 BlockCipher" \
@@ -8508,17 +8843,17 @@
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "Large server packet TLS 1.3 AEAD" \
- "$P_SRV response_size=16384" \
+ "$P_SRV response_size=16383" \
"$P_CLI force_ciphersuite=TLS1-3-AES-128-CCM-SHA256" \
0 \
- -c "Read from server: 16384 bytes read"
+ -c "Read from server: 16383 bytes read"
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "Large server packet TLS 1.3 AEAD shorter tag" \
- "$P_SRV response_size=16384" \
+ "$P_SRV response_size=16383" \
"$P_CLI force_ciphersuite=TLS1-3-AES-128-CCM-8-SHA256" \
0 \
- -c "Read from server: 16384 bytes read"
+ -c "Read from server: 16383 bytes read"
# Tests for restartable ECC
@@ -11613,6 +11948,21 @@
-S "Version: TLS1.2" \
-C "Protocol : TLSv1.2"
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test "TLS 1.3 m->m: Not supported version check: cli TLS 1.2 only, srv TLS 1.3 only, fail" \
+ "$P_SRV debug_level=4 max_version=tls13 min_version=tls13" \
+ "$P_CLI debug_level=4 max_version=tls12 min_version=tls12" \
+ 1 \
+ -c "The SSL configuration is tls12 only" \
+ -c "supported_versions(43) extension does not exist." \
+ -c "A fatal alert message was received from our peer" \
+ -s "The SSL configuration is tls13 only" \
+ -s "TLS 1.2 not supported."
+
requires_openssl_tls1_3_with_compatible_ephemeral
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
diff --git a/tests/suites/test_suite_aes.ctr.data b/tests/suites/test_suite_aes.ctr.data
new file mode 100644
index 0000000..a148236
--- /dev/null
+++ b/tests/suites/test_suite_aes.ctr.data
@@ -0,0 +1,137 @@
+# Test vectors from NIST Special Publication 800-38A 2001 Edition
+# Recommendation for Block Edition Cipher Modes of Operation
+
+# as below, but corrupt the key to check the test catches it
+AES-CTR NIST 128 bad
+aes_ctr:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee":1
+
+AES-CTR NIST 128
+aes_ctr:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee":0
+
+AES-CTR NIST 192
+depends_on:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+aes_ctr:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050":0
+
+AES-CTR NIST 256
+depends_on:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+aes_ctr:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6":0
+
+AES-CTR aes_encrypt_ctr_multipart 1 1
+aes_encrypt_ctr_multipart:1:1
+
+AES-CTR aes_encrypt_ctr_multipart 2 1
+aes_encrypt_ctr_multipart:2:1
+
+AES-CTR aes_encrypt_ctr_multipart 2 2
+aes_encrypt_ctr_multipart:2:2
+
+AES-CTR aes_encrypt_ctr_multipart 4 1
+aes_encrypt_ctr_multipart:4:1
+
+AES-CTR aes_encrypt_ctr_multipart 4 2
+aes_encrypt_ctr_multipart:4:2
+
+AES-CTR aes_encrypt_ctr_multipart 15 1
+aes_encrypt_ctr_multipart:15:1
+
+AES-CTR aes_encrypt_ctr_multipart 15 2
+aes_encrypt_ctr_multipart:15:2
+
+AES-CTR aes_encrypt_ctr_multipart 15 8
+aes_encrypt_ctr_multipart:15:8
+
+AES-CTR aes_encrypt_ctr_multipart 15 15
+aes_encrypt_ctr_multipart:15:15
+
+AES-CTR aes_encrypt_ctr_multipart 16 1
+aes_encrypt_ctr_multipart:16:1
+
+AES-CTR aes_encrypt_ctr_multipart 16 2
+aes_encrypt_ctr_multipart:16:2
+
+AES-CTR aes_encrypt_ctr_multipart 16 8
+aes_encrypt_ctr_multipart:16:8
+
+AES-CTR aes_encrypt_ctr_multipart 16 15
+aes_encrypt_ctr_multipart:16:15
+
+AES-CTR aes_encrypt_ctr_multipart 16 16
+aes_encrypt_ctr_multipart:16:16
+
+AES-CTR aes_encrypt_ctr_multipart 17 1
+aes_encrypt_ctr_multipart:17:1
+
+AES-CTR aes_encrypt_ctr_multipart 17 2
+aes_encrypt_ctr_multipart:17:2
+
+AES-CTR aes_encrypt_ctr_multipart 17 8
+aes_encrypt_ctr_multipart:17:8
+
+AES-CTR aes_encrypt_ctr_multipart 17 15
+aes_encrypt_ctr_multipart:17:15
+
+AES-CTR aes_encrypt_ctr_multipart 17 16
+aes_encrypt_ctr_multipart:17:16
+
+AES-CTR aes_encrypt_ctr_multipart 63 1
+aes_encrypt_ctr_multipart:63:1
+
+AES-CTR aes_encrypt_ctr_multipart 63 2
+aes_encrypt_ctr_multipart:63:2
+
+AES-CTR aes_encrypt_ctr_multipart 63 8
+aes_encrypt_ctr_multipart:63:8
+
+AES-CTR aes_encrypt_ctr_multipart 63 15
+aes_encrypt_ctr_multipart:63:15
+
+AES-CTR aes_encrypt_ctr_multipart 63 16
+aes_encrypt_ctr_multipart:63:16
+
+AES-CTR aes_encrypt_ctr_multipart 63 17
+aes_encrypt_ctr_multipart:63:17
+
+AES-CTR aes_encrypt_ctr_multipart 64 1
+aes_encrypt_ctr_multipart:64:1
+
+AES-CTR aes_encrypt_ctr_multipart 64 2
+aes_encrypt_ctr_multipart:64:2
+
+AES-CTR aes_encrypt_ctr_multipart 64 8
+aes_encrypt_ctr_multipart:64:8
+
+AES-CTR aes_encrypt_ctr_multipart 64 15
+aes_encrypt_ctr_multipart:64:15
+
+AES-CTR aes_encrypt_ctr_multipart 64 16
+aes_encrypt_ctr_multipart:64:16
+
+AES-CTR aes_encrypt_ctr_multipart 64 17
+aes_encrypt_ctr_multipart:64:17
+
+AES-CTR aes_encrypt_ctr_multipart 1024 1
+aes_encrypt_ctr_multipart:1024:1
+
+AES-CTR aes_encrypt_ctr_multipart 1024 10
+aes_encrypt_ctr_multipart:1024:10
+
+AES-CTR aes_encrypt_ctr_multipart 1024 15
+aes_encrypt_ctr_multipart:1024:15
+
+AES-CTR aes_encrypt_ctr_multipart 1024 16
+aes_encrypt_ctr_multipart:1024:16
+
+AES-CTR aes_encrypt_ctr_multipart 1024 63
+aes_encrypt_ctr_multipart:1024:63
+
+AES-CTR aes_encrypt_ctr_multipart 1024 64
+aes_encrypt_ctr_multipart:1024:64
+
+AES-CTR aes_encrypt_ctr_multipart 1024 65
+aes_encrypt_ctr_multipart:1024:65
+
+AES-CTR aes_encrypt_ctr_multipart 1024 1023
+aes_encrypt_ctr_multipart:1024:1023
+
+AES-CTR aes_encrypt_ctr_multipart 1024 1024
+aes_encrypt_ctr_multipart:1024:1024
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index 2ca3f7f..9118a98 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -88,6 +88,124 @@
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
+void aes_ctr(data_t *key, data_t *ictr, data_t *pt, data_t *ct, int expected)
+{
+ unsigned char *output = NULL;
+ unsigned char ctr[16];
+ unsigned char stream_block[16];
+ mbedtls_aes_context ctx;
+
+ // sanity checks on test input
+ TEST_ASSERT(pt->len == ct->len);
+ TEST_ASSERT(key->len == 16 || key->len == 24 || key->len == 32);
+
+ TEST_CALLOC(output, pt->len);
+
+ // expected result is always success on zero-length input, so skip len == 0 if expecting failure
+ for (size_t len = (expected == 0 ? 0 : 1); len <= pt->len; len++) {
+ for (int i = 0; i < 2; i++) {
+ mbedtls_aes_init(&ctx);
+ TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx, key->x, key->len * 8) == 0);
+
+ memcpy(ctr, ictr->x, 16);
+ memset(stream_block, 0, 16);
+ memset(output, 0, pt->len);
+
+ size_t nc_off = 0;
+
+ if (i == 0) {
+ // encrypt
+ TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, len, &nc_off, ctr,
+ stream_block, pt->x, output), 0);
+ TEST_ASSERT(!!memcmp(output, ct->x, len) == expected);
+ } else {
+ // decrypt
+ TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, len, &nc_off, ctr,
+ stream_block, ct->x, output), 0);
+ TEST_ASSERT(!!memcmp(output, pt->x, len) == expected);
+ }
+ }
+ }
+
+exit:
+ mbedtls_free(output);
+ mbedtls_aes_free(&ctx);
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
+void aes_encrypt_ctr_multipart(int length, int step_size)
+{
+ unsigned char key[16];
+ unsigned char ctr_a[16];
+ unsigned char ctr_b[16];
+ unsigned char stream_block_a[16];
+ unsigned char stream_block_b[16];
+ unsigned char *input = NULL;
+ unsigned char *output_a = NULL;
+ unsigned char *output_b = NULL;
+ mbedtls_aes_context ctx;
+ size_t nc_off_a, nc_off_b;
+
+ TEST_ASSERT(length >= 0);
+ TEST_ASSERT(step_size > 0);
+
+ TEST_CALLOC(input, length);
+ TEST_CALLOC(output_a, length);
+ TEST_CALLOC(output_b, length);
+
+ // set up a random key
+ mbedtls_test_rnd_std_rand(NULL, key, sizeof(key));
+
+ // random input
+ mbedtls_test_rnd_std_rand(NULL, input, length);
+
+
+ // complete encryption in one call
+ mbedtls_aes_init(&ctx);
+ TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx, key, sizeof(key) * 8) == 0);
+ memset(ctr_a, 0, sizeof(ctr_a));
+ memset(stream_block_a, 0, sizeof(stream_block_a));
+ nc_off_a = 0;
+ TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, length, &nc_off_a, ctr_a,
+ stream_block_a, input, output_a), 0);
+ mbedtls_aes_free(&ctx);
+
+
+ // encrypt in multiple steps of varying size
+ mbedtls_aes_init(&ctx);
+ TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx, key, sizeof(key) * 8) == 0);
+ memset(ctr_b, 0, sizeof(ctr_b));
+ memset(stream_block_b, 0, sizeof(stream_block_b));
+ nc_off_b = 0;
+ size_t remaining = length;
+ unsigned char *ip = input, *op = output_b;
+ while (remaining != 0) {
+ size_t l = MIN(remaining, (size_t) step_size);
+ step_size *= 2;
+ remaining -= l;
+ TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, l, &nc_off_b, ctr_b, stream_block_b, ip, op), 0);
+ ip += l;
+ op += l;
+ }
+
+ // finally, validate that multiple steps produced same result as single-pass
+ TEST_MEMORY_COMPARE(output_a, length, output_b, length);
+ TEST_MEMORY_COMPARE(ctr_a, sizeof(ctr_a), ctr_b, sizeof(ctr_b));
+ TEST_MEMORY_COMPARE(stream_block_a, sizeof(stream_block_a),
+ stream_block_b, sizeof(stream_block_b));
+ TEST_EQUAL(nc_off_a, nc_off_b);
+
+exit:
+ mbedtls_free(input);
+ mbedtls_free(output_a);
+ mbedtls_free(output_b);
+
+ mbedtls_aes_free(&ctx);
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
void aes_decrypt_ecb(data_t *key_str, data_t *src_str,
data_t *dst, int setkey_result)
diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data
index 028a07f..89dfb97 100644
--- a/tests/suites/test_suite_ctr_drbg.data
+++ b/tests/suites/test_suite_ctr_drbg.data
@@ -1105,3 +1105,48 @@
CTR_DRBG self test
ctr_drbg_selftest:
+
+Increment counter rollover
+ctr_increment_rollover
+
+Increment counter 00
+ctr_increment:"00"
+
+Increment counter ff00
+ctr_increment:"ff00"
+
+Increment counter ff0000
+ctr_increment:"ff0000"
+
+Increment counter ff000000
+ctr_increment:"ff000000"
+
+Increment counter ff00000000
+ctr_increment:"ff00000000"
+
+Increment counter ff0000000000
+ctr_increment:"ff0000000000"
+
+Increment counter ff000000000000
+ctr_increment:"ff000000000000"
+
+Increment counter 01
+ctr_increment:"01"
+
+Increment counter ff01
+ctr_increment:"ff01"
+
+Increment counter ff0001
+ctr_increment:"ff0001"
+
+Increment counter ff000001
+ctr_increment:"ff000001"
+
+Increment counter ff00000001
+ctr_increment:"ff00000001"
+
+Increment counter ff0000000001
+ctr_increment:"ff0000000001"
+
+Increment counter ff000000000001
+ctr_increment:"ff000000000001"
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 1f0a072..425c43e 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -2,6 +2,7 @@
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "string.h"
+#include "ctr.h"
#if defined(MBEDTLS_THREADING_PTHREAD)
#include "mbedtls/threading.h"
@@ -443,3 +444,75 @@
AES_PSA_DONE();
}
/* END_CASE */
+
+/* BEGIN_CASE */
+void ctr_increment_rollover()
+{
+ uint8_t c[16];
+ uint8_t r[16];
+
+ // test all increments from 2^n - 1 to 2^n (i.e. where we roll over into the next bit)
+ for (int n = 0; n <= 128; n++) {
+ memset(c, 0, 16);
+ memset(r, 0, 16);
+
+ // set least significant (highest address) n bits to 1, i.e. generate (2^n - 1)
+ for (int i = 0; i < n; i++) {
+ int bit = i % 8;
+ int byte = (i / 8);
+ c[15 - byte] |= 1 << bit;
+ }
+ // increment to get 2^n
+ mbedtls_ctr_increment_counter(c);
+
+ // now generate a reference result equal to 2^n - i.e. set only bit (n + 1)
+ // if n == 127, this will not set any bits (i.e. wraps to 0).
+ int bit = n % 8;
+ int byte = n / 8;
+ if (byte < 16) {
+ r[15 - byte] = 1 << bit;
+ }
+
+ TEST_MEMORY_COMPARE(c, 16, r, 16);
+ }
+
+ uint64_t lsb = 10, msb = 20;
+ MBEDTLS_PUT_UINT64_BE(msb, c, 0);
+ MBEDTLS_PUT_UINT64_BE(lsb, c, 8);
+ memcpy(r, c, 16);
+ mbedtls_ctr_increment_counter(c);
+ for (int i = 15; i >= 0; i--) {
+ r[i] += 1;
+ if (r[i] != 0) {
+ break;
+ }
+ }
+ TEST_MEMORY_COMPARE(c, 16, r, 16);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void ctr_increment(data_t *x)
+{
+ uint8_t c[16];
+ uint8_t r[16];
+
+ // initialise c and r from test argument
+ memset(c, 0, 16);
+ memcpy(c, x->x, x->len);
+ memcpy(r, c, 16);
+
+ // increment c
+ mbedtls_ctr_increment_counter(c);
+ // increment reference
+ for (int i = 15; i >= 0; i--) {
+ r[i] += 1;
+ if (r[i] != 0) {
+ break;
+ }
+ }
+
+ // test that mbedtls_ctr_increment_counter behaviour matches reference
+ TEST_MEMORY_COMPARE(c, 16, r, 16);
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 05571a1..8a03d1b 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -2096,6 +2096,10 @@
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ TEST_ASSERT(original.record_size_limit == restored.record_size_limit);
+#endif
+
exit:
mbedtls_ssl_session_free(&original);
mbedtls_ssl_session_free(&restored);
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 28cef30..5c6a903 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -265,3 +265,6 @@
Check max serial length
x509_set_serial_check:
+
+Check max extension length
+x509_set_extension_length_check:
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index b59fd48..503d976 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -752,3 +752,24 @@
USE_PSA_DONE();
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CSR_WRITE_C */
+void x509_set_extension_length_check()
+{
+ int ret = 0;
+
+ mbedtls_x509write_csr ctx;
+ mbedtls_x509write_csr_init(&ctx);
+
+ unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 };
+ unsigned char *p = buf + sizeof(buf);
+
+ ret = mbedtls_x509_set_extension(&(ctx.MBEDTLS_PRIVATE(extensions)),
+ MBEDTLS_OID_EXTENDED_KEY_USAGE,
+ MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
+ 0,
+ p,
+ SIZE_MAX);
+ TEST_ASSERT(MBEDTLS_ERR_X509_BAD_INPUT_DATA == ret);
+}
+/* END_CASE */