Merge pull request #8921 from gilles-peskine-arm/pk_import_into_psa-test-lifetime
pk_import_into_psa: test persistent keys
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4fb26b5
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "framework"]
+ path = framework
+ url = https://github.com/Mbed-TLS/mbedtls-framework
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 72f126f..2b10f86 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -5,6 +5,11 @@
# Required
version: 2
+# Include the framework submodule in the build
+submodules:
+ include:
+ - framework
+
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5585c78..e37ca2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,9 +34,15 @@
cmake_policy(SET CMP0012 NEW)
if(TEST_CPP)
- project("Mbed TLS" LANGUAGES C CXX)
+ project("Mbed TLS"
+ LANGUAGES C CXX
+ VERSION 3.5.2
+ )
else()
- project("Mbed TLS" LANGUAGES C)
+ project("Mbed TLS"
+ LANGUAGES C
+ VERSION 3.5.2
+ )
endif()
include(GNUInstallDirs)
@@ -277,6 +283,11 @@
set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}")
endif()
+if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt")
+ message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt not found. Run `git submodule update --init` from the source tree to fetch the submodule contents.")
+endif()
+add_subdirectory(framework)
+
add_subdirectory(include)
add_subdirectory(3rdparty)
diff --git a/ChangeLog.d/8709.txt b/ChangeLog.d/8709.txt
new file mode 100644
index 0000000..e0bea44
--- /dev/null
+++ b/ChangeLog.d/8709.txt
@@ -0,0 +1,4 @@
+Features
+ * The new functions mbedtls_pk_copy_from_psa() and
+ mbedtls_pk_copy_public_from_psa() provide ways to set up a PK context
+ with the same content as a PSA key.
diff --git a/ChangeLog.d/8824.txt b/ChangeLog.d/8824.txt
index abc305f..6d6bcb7 100644
--- a/ChangeLog.d/8824.txt
+++ b/ChangeLog.d/8824.txt
@@ -1,7 +1,8 @@
Bugfix
* Fix mbedtls_pk_sign(), mbedtls_pk_verify(), mbedtls_pk_decrypt() and
mbedtls_pk_encrypt() on non-opaque RSA keys to honor the padding mode in
- the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled, they always
- used PKCS#1 v1.5 even when the RSA context was configured for PKCS#1 v2.1
- (PSS/OAEP). Fixes #8824.
+ the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled and the
+ RSA context was configured for PKCS#1 v2.1 (PSS/OAEP), the sign/verify
+ functions performed a PKCS#1 v1.5 signature instead and the
+ encrypt/decrypt functions returned an error. Fixes #8824.
diff --git a/ChangeLog.d/8825.txt b/ChangeLog.d/8825.txt
new file mode 100644
index 0000000..914bd08
--- /dev/null
+++ b/ChangeLog.d/8825.txt
@@ -0,0 +1,6 @@
+Features
+ * mbedtls_psa_get_random() is always available as soon as
+ MBEDTLS_PSA_CRYPTO_CLIENT is enabled at build time and psa_crypto_init() is
+ called at runtime. This together with MBEDTLS_PSA_RANDOM_STATE can be
+ used as random number generator function (f_rng) and context (p_rng) in
+ legacy functions.
diff --git a/ChangeLog.d/8848.txt b/ChangeLog.d/8848.txt
new file mode 100644
index 0000000..71bb7e3
--- /dev/null
+++ b/ChangeLog.d/8848.txt
@@ -0,0 +1,6 @@
+Removals
+ * Temporary function mbedtls_pk_wrap_as_opaque() is removed. To mimic the
+ same behavior mbedtls_pk_get_psa_attributes() and
+ mbedtls_pk_import_into_psa() can be used to import a PK key into PSA,
+ while mbedtls_pk_setup_opaque() can be used to wrap a PSA key into a opaque
+ PK context.
diff --git a/ChangeLog.d/add_get_ecp_group_id.txt b/ChangeLog.d/add_get_ecp_group_id.txt
new file mode 100644
index 0000000..3328062
--- /dev/null
+++ b/ChangeLog.d/add_get_ecp_group_id.txt
@@ -0,0 +1,3 @@
+Features
+ * Add new accessor to expose the private group id member of
+ `mbedtls_ecdh_context` structure.
diff --git a/ChangeLog.d/add_ssl_session_accessors.txt b/ChangeLog.d/add_ssl_session_accessors.txt
new file mode 100644
index 0000000..516a3bf
--- /dev/null
+++ b/ChangeLog.d/add_ssl_session_accessors.txt
@@ -0,0 +1,6 @@
+Features
+ * Add new accessors to expose the private session-id,
+ session-id length, and ciphersuite-id members of
+ `mbedtls_ssl_session` structure.
+ Add new accessor to expose the ciphersuite-id of
+ `mbedtls_ssl_ciphersuite_t` structure.Design ref: #8529
diff --git a/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt b/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt
new file mode 100644
index 0000000..435cc98
--- /dev/null
+++ b/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt
@@ -0,0 +1,5 @@
+Requirement changes
+ * Drop support for Visual Studio 2013 and 2015, and Arm Compiler 5.
+Changes
+ * Rename directory containing Visual Studio files from visualc/VS2013 to
+ visualc/VS2017.
diff --git a/ChangeLog.d/early-data.txt b/ChangeLog.d/early-data.txt
new file mode 100644
index 0000000..3c3826c
--- /dev/null
+++ b/ChangeLog.d/early-data.txt
@@ -0,0 +1,5 @@
+Features
+ * Mbed TLS now supports the writing and reading of TLS 1.3 early data (see
+ docs/tls13-early-data.md). The support enablement is controlled at build
+ time by the MBEDTLS_SSL_EARLY_DATA configuration option and at runtime by
+ the mbedtls_ssl_conf_early_data() API (by default disabled in both cases).
diff --git a/ChangeLog.d/ecp_write_key.txt b/ChangeLog.d/ecp_write_key.txt
new file mode 100644
index 0000000..73354c8
--- /dev/null
+++ b/ChangeLog.d/ecp_write_key.txt
@@ -0,0 +1,8 @@
+Features
+ * The new function mbedtls_ecp_write_key_ext() is similar to
+ mbedtls_ecp_write_key(), but can be used without separately calculating
+ the output length.
+
+New deprecations
+ * mbedtls_ecp_write_key() is deprecated in favor of
+ mbedtls_ecp_write_key_ext().
diff --git a/ChangeLog.d/fix-alpn-negotiating-bug.txt b/ChangeLog.d/fix-alpn-negotiating-bug.txt
new file mode 100644
index 0000000..3bceb37
--- /dev/null
+++ b/ChangeLog.d/fix-alpn-negotiating-bug.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Fix the restoration of the ALPN when loading serialized connection with
+ * the mbedtls_ssl_context_load() API.
diff --git a/ChangeLog.d/fix-new-rn-on-hrr.txt b/ChangeLog.d/fix-new-rn-on-hrr.txt
new file mode 100644
index 0000000..1b4f5e6
--- /dev/null
+++ b/ChangeLog.d/fix-new-rn-on-hrr.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * In TLS 1.3 clients, fix an interoperability problem due to the client
+ generating a new random after a HelloRetryRequest. Fixes #8669.
diff --git a/ChangeLog.d/fix-ssl-session-serialization-config.txt b/ChangeLog.d/fix-ssl-session-serialization-config.txt
new file mode 100644
index 0000000..ca1cc81
--- /dev/null
+++ b/ChangeLog.d/fix-ssl-session-serialization-config.txt
@@ -0,0 +1,4 @@
+Bugfix
+ * Fix missing bitflags in SSL session serialization headers. Their absence
+ allowed SSL sessions saved in one configuration to be loaded in a
+ different, incompatible configuration.
diff --git a/ChangeLog.d/use_exp_mod_core.txt b/ChangeLog.d/use_exp_mod_core.txt
new file mode 100644
index 0000000..8f7193a
--- /dev/null
+++ b/ChangeLog.d/use_exp_mod_core.txt
@@ -0,0 +1,6 @@
+Changes
+ * mbedtls_mpi_exp_mod and code that uses it, notably RSA and DHM operations,
+ have changed their speed/memory compromise as part of a proactive security
+ improvement. The new default value of MBEDTLS_MPI_WINDOW_SIZE roughly
+ preserves the current speed, at the expense of increasing memory
+ consumption.
diff --git a/ChangeLog.d/x509-add-ca_istrue.txt b/ChangeLog.d/x509-add-ca_istrue.txt
new file mode 100644
index 0000000..c950dbc
--- /dev/null
+++ b/ChangeLog.d/x509-add-ca_istrue.txt
@@ -0,0 +1,5 @@
+Features
+ * Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of
+ `mbedtls_x509_crt` structure. This requires setting
+ the MBEDTLS_X509_EXT_BASIC_CONSTRAINTS bit in the certificate's
+ ext_types field.
diff --git a/Makefile b/Makefile
index 885948c..fb80529 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,20 @@
PREFIX=mbedtls_
PERL ?= perl
+ifneq (,$(filter-out lib library/%,$(or $(MAKECMDGOALS),all)))
+ ifeq (,$(wildcard framework/exported.make))
+ # Use the define keyword to get a multi-line message.
+ # GNU make appends ". Stop.", so tweak the ending of our message accordingly.
+ define error_message
+$(MBEDTLS_PATH)/framework/exported.make not found.
+Run `git submodule update --init` to fetch the submodule contents.
+This is a fatal error
+ endef
+ $(error $(error_message))
+ endif
+ include framework/exported.make
+endif
+
.SILENT:
.PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean
@@ -60,7 +74,7 @@
endif
.PHONY: visualc_files
-VISUALC_FILES = visualc/VS2013/mbedTLS.sln visualc/VS2013/mbedTLS.vcxproj
+VISUALC_FILES = visualc/VS2017/mbedTLS.sln visualc/VS2017/mbedTLS.vcxproj
# TODO: $(app).vcxproj for each $(app) in programs/
visualc_files: $(VISUALC_FILES)
@@ -69,9 +83,9 @@
# they just need to be present.
$(VISUALC_FILES): | library/generated_files
$(VISUALC_FILES): $(gen_file_dep) scripts/generate_visualc_files.pl
-$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2013-app-template.vcxproj
-$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2013-main-template.vcxproj
-$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2013-sln-template.sln
+$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-app-template.vcxproj
+$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-main-template.vcxproj
+$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-sln-template.sln
# TODO: also the list of .c and .h source files, but not their content
$(VISUALC_FILES):
echo " Gen $@ ..."
@@ -147,10 +161,10 @@
$(MAKE) -C programs neat
$(MAKE) -C tests neat
ifndef WINDOWS
- rm -f visualc/VS2013/*.vcxproj visualc/VS2013/mbedTLS.sln
+ rm -f visualc/VS2017/*.vcxproj visualc/VS2017/mbedTLS.sln
else
- if exist visualc\VS2013\*.vcxproj del /Q /F visualc\VS2013\*.vcxproj
- if exist visualc\VS2013\mbedTLS.sln del /Q /F visualc\VS2013\mbedTLS.sln
+ if exist visualc\VS2017\*.vcxproj del /Q /F visualc\VS2017\*.vcxproj
+ if exist visualc\VS2017\mbedTLS.sln del /Q /F visualc\VS2017\mbedTLS.sln
endif
check: lib tests
diff --git a/README.md b/README.md
index 2505d8f..d226260 100644
--- a/README.md
+++ b/README.md
@@ -47,13 +47,17 @@
You need the following tools to build the library with the provided makefiles:
* GNU Make 3.82 or a build tool that CMake supports.
-* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, IAR 8 and Visual Studio 2013. More recent versions should work. Slightly older versions may work.
+* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, Arm Compiler 6, IAR 8 and Visual Studio 2017. More recent versions should work. Slightly older versions may work.
* Python 3.8 to generate the test code. Python is also needed to integrate PSA drivers and to build the development branch (see next section).
* Perl to run the tests, and to generate some source files in the development branch.
* CMake 3.10.2 or later (if using CMake).
-* Microsoft Visual Studio 2013 or later (if using Visual Studio).
+* Microsoft Visual Studio 2017 or later (if using Visual Studio).
* Doxygen 1.8.11 or later (if building the documentation; slightly older versions should work).
+### Git usage
+
+The `development` branch and the `mbedtls-3.6` long-term support branch of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar).
+
### Generated source files in the development branch
The source code of Mbed TLS includes some files that are automatically generated by scripts and whose content depends only on the Mbed TLS source, not on the platform or on the library configuration. These files are not included in the development branch of Mbed TLS, but the generated files are included in official releases. This section explains how to generate the missing files in the development branch.
@@ -221,7 +225,7 @@
### Microsoft Visual Studio
-The build files for Microsoft Visual Studio are generated for Visual Studio 2013.
+The build files for Microsoft Visual Studio are generated for Visual Studio 2017.
The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need Python and perl environments as well. However, the selftest program in `programs/test/` is still available.
diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md
index 6db0e54..d6fc19e 100644
--- a/docs/architecture/tls13-support.md
+++ b/docs/architecture/tls13-support.md
@@ -4,17 +4,8 @@
Overview
--------
-Mbed TLS provides a partial implementation of the TLS 1.3 protocol defined in
-the "Support description" section below. The TLS 1.3 support enablement
-is controlled by the MBEDTLS_SSL_PROTO_TLS1_3 configuration option.
-
-The development of the TLS 1.3 protocol is based on the TLS 1.3 prototype
-located at https://github.com/hannestschofenig/mbedtls. The prototype is
-itself based on a version of the development branch that we aim to keep as
-recent as possible (ideally the head) by merging regularly commits of the
-development branch into the prototype. The section "Prototype upstreaming
-status" below describes what remains to be upstreamed.
-
+Mbed TLS provides an implementation of the TLS 1.3 protocol. The TLS 1.3 support
+may be enabled using the MBEDTLS_SSL_PROTO_TLS1_3 configuration option.
Support description
-------------------
@@ -26,14 +17,14 @@
- Mbed TLS supports ECDHE key establishment.
- - Mbed TLS does not support DHE key establishment.
+ - Mbed TLS supports DHE key establishment.
- Mbed TLS supports pre-shared keys for key establishment, pre-shared keys
provisioned externally as well as provisioned via the ticket mechanism.
- Mbed TLS supports session resumption via the ticket mechanism.
- - Mbed TLS does not support sending or receiving early data (0-RTT data).
+ - Mbed TLS supports sending and receiving early data (0-RTT data).
- Supported cipher suites: depends on the library configuration. Potentially
all of them:
@@ -51,7 +42,7 @@
| signature_algorithms | YES |
| use_srtp | no |
| heartbeat | no |
- | apln | YES |
+ | alpn | YES |
| signed_certificate_timestamp | no |
| client_certificate_type | no |
| server_certificate_type | no |
@@ -59,7 +50,7 @@
| key_share | YES |
| pre_shared_key | YES |
| psk_key_exchange_modes | YES |
- | early_data | no |
+ | early_data | YES |
| cookie | no |
| supported_versions | YES |
| certificate_authorities | no |
@@ -71,7 +62,8 @@
Potentially all ECDHE groups:
secp256r1, x25519, secp384r1, x448 and secp521r1.
- Finite field groups (DHE) are not supported.
+ Potentially all DHE groups:
+ ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144 and ffdhe8192.
- Supported signature algorithms (both for certificates and CertificateVerify):
depends on the library configuration.
@@ -105,7 +97,7 @@
| Mbed TLS configuration option | Support |
| ---------------------------------------- | ------- |
- | MBEDTLS_SSL_ALL_ALERT_MESSAGES | no |
+ | MBEDTLS_SSL_ALL_ALERT_MESSAGES | yes |
| MBEDTLS_SSL_ASYNC_PRIVATE | no |
| MBEDTLS_SSL_CONTEXT_SERIALIZATION | no |
| MBEDTLS_SSL_DEBUG_ALL | no |
@@ -167,33 +159,6 @@
TLS 1.3 specification.
-Prototype upstreaming status
-----------------------------
-
-The following parts of the TLS 1.3 prototype remain to be upstreamed:
-
-- Sending (client) and receiving (server) early data (0-RTT data).
-
-- New TLS Message Processing Stack (MPS)
-
- The TLS 1.3 prototype is developed alongside a rewrite of the TLS messaging layer,
- encompassing low-level details such as record parsing, handshake reassembly, and
- DTLS retransmission state machine.
-
- MPS has the following components:
- - Layer 1 (Datagram handling)
- - Layer 2 (Record handling)
- - Layer 3 (Message handling)
- - Layer 4 (Retransmission State Machine)
- - Reader (Abstracted pointer arithmetic and reassembly logic for incoming data)
- - Writer (Abstracted pointer arithmetic and fragmentation logic for outgoing data)
-
- Of those components, the following have been upstreamed
- as part of `MBEDTLS_SSL_PROTO_TLS1_3`:
-
- - Reader ([`library/mps_reader.h`](../../library/mps_reader.h))
-
-
Coding rules checklist for TLS 1.3
----------------------------------
@@ -266,10 +231,6 @@
- the macro to check for data when reading from an input buffer
`MBEDTLS_SSL_CHK_BUF_READ_PTR`.
- These macros were introduced after the prototype was written thus are
- likely not to be used in prototype where we now would use them in
- development.
-
The three first types, MBEDTLS_BYTE_{0-8}, MBEDTLS_PUT_UINT{8|16|32|64}_BE
and MBEDTLS_GET_UINT{8|16|32|64}_BE improve the readability of the code and
reduce the risk of writing or reading bytes in the wrong order.
@@ -472,175 +433,3 @@
* state change: the state change is done in the main state handler to ease
the navigation of the state machine transitions.
-
-
-Writing and reading early or 0-RTT data
----------------------------------------
-
-An application function to write and send a buffer of data to a server through
-TLS may plausibly look like:
-
-```
-int write_data( mbedtls_ssl_context *ssl,
- const unsigned char *data_to_write,
- size_t data_to_write_len,
- size_t *data_written )
-{
- *data_written = 0;
-
- while( *data_written < data_to_write_len )
- {
- ret = mbedtls_ssl_write( ssl, data_to_write + *data_written,
- data_to_write_len - *data_written );
-
- if( ret < 0 &&
- ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- {
- return( ret );
- }
-
- *data_written += ret;
- }
-
- return( 0 );
-}
-```
-where ssl is the SSL context to use, data_to_write the address of the data
-buffer and data_to_write_len the number of data bytes. The handshake may
-not be completed, not even started for the SSL context ssl when the function is
-called and in that case the mbedtls_ssl_write() API takes care transparently of
-completing the handshake before to write and send data to the server. The
-mbedtls_ssl_write() may not been able to write and send all data in one go thus
-the need for a loop calling it as long as there are still data to write and
-send.
-
-An application function to write and send early data and only early data,
-data sent during the first flight of client messages while the handshake is in
-its initial phase, would look completely similar but the call to
-mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write().
-```
-int write_early_data( mbedtls_ssl_context *ssl,
- const unsigned char *data_to_write,
- size_t data_to_write_len,
- size_t *data_written )
-{
- *data_written = 0;
-
- while( *data_written < data_to_write_len )
- {
- ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written,
- data_to_write_len - *data_written );
-
- if( ret < 0 &&
- ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- {
- return( ret );
- }
-
- *data_written += ret;
- }
-
- return( 0 );
-}
-```
-Note that compared to write_data(), write_early_data() can also return
-MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled
-specifically by the user of write_early_data(). A fresh SSL context (typically
-just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would
-be expected when calling `write_early_data`.
-
-All together, code to write and send a buffer of data as long as possible as
-early data and then as standard post-handshake application data could
-plausibly look like:
-
-```
-ret = write_early_data( ssl, data_to_write, data_to_write_len,
- &early_data_written );
-if( ret < 0 &&
- ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
-{
- goto error;
-}
-
-ret = write_data( ssl, data_to_write + early_data_written,
- data_to_write_len - early_data_written, &data_written );
-if( ret < 0 )
- goto error;
-
-data_written += early_data_written;
-```
-
-Finally, taking into account that the server may reject early data, application
-code to write and send a buffer of data could plausibly look like:
-```
-ret = write_early_data( ssl, data_to_write, data_to_write_len,
- &early_data_written );
-if( ret < 0 &&
- ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
-{
- goto error;
-}
-
-/*
- * Make sure the handshake is completed as it is a requisite to
- * mbedtls_ssl_get_early_data_status().
- */
-while( !mbedtls_ssl_is_handshake_over( ssl ) )
-{
- ret = mbedtls_ssl_handshake( ssl );
- if( ret < 0 &&
- ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- {
- goto error;
- }
-}
-
-ret = mbedtls_ssl_get_early_data_status( ssl );
-if( ret < 0 )
- goto error;
-
-if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED )
- early_data_written = 0;
-
-ret = write_data( ssl, data_to_write + early_data_written,
- data_to_write_len - early_data_written, &data_written );
-if( ret < 0 )
- goto error;
-
-data_written += early_data_written;
-```
-
-Basically, the same holds for reading early data on the server side without the
-complication of possible rejection. An application function to read early data
-into a given buffer could plausibly look like:
-```
-int read_early_data( mbedtls_ssl_context *ssl,
- unsigned char *buffer,
- size_t buffer_size,
- size_t *data_len )
-{
- *data_len = 0;
-
- while( *data_len < buffer_size )
- {
- ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len,
- buffer_size - *data_len );
-
- if( ret < 0 &&
- ret != MBEDTLS_ERR_SSL_WANT_READ &&
- ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- {
- return( ret );
- }
-
- *data_len += ret;
- }
-
- return( 0 );
-}
-```
-with again calls to read_early_data() expected to be done with a fresh SSL
-context.
diff --git a/docs/psa-driver-example-and-guide.md b/docs/psa-driver-example-and-guide.md
index d041723..aa825ad 100644
--- a/docs/psa-driver-example-and-guide.md
+++ b/docs/psa-driver-example-and-guide.md
@@ -157,11 +157,11 @@
```
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_sign_hash( attributes,
key_buffer,
diff --git a/docs/psa-transition.md b/docs/psa-transition.md
index e89128c..bbb7da2 100644
--- a/docs/psa-transition.md
+++ b/docs/psa-transition.md
@@ -50,7 +50,7 @@
To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled. (It is enabled in the default configuration.)
-You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition (for example, to convert between metadata encodings or between key representations) are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled.
+You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood.
By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API (configured by `MBEDTLS_XXX` macros). The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”.
@@ -779,9 +779,9 @@
The easiest way to create a key pair object is by randomly generating it with [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). Compared with the low-level functions from the legacy API (`mbedtls_rsa_gen_key`, `mbedtls_ecp_gen_privkey`, `mbedtls_ecp_gen_keypair`, `mbedtls_ecp_gen_keypair_base`, `mbedtls_ecdsa_genkey`), this directly creates an object that can be used with high-level APIs, but removes some of the flexibility. Note that if you want to export the generated private key, you must pass the flag [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de); exporting the public key with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) is always permitted.
-For RSA keys, `psa_generate_key` always uses 65537 as the public exponent. If you need a different public exponent, use the legacy interface to create the key then import it as described in “[Importing legacy keys via the PK module](#importing-legacy-keys-via-the-pk-module)”.
+For RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga6776360ae8046a4456a5f990f997da58) to select a different public exponent. As of Mbed TLS 3.6.0, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers.
-To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of one of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details.
+To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). This function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), but only supports a single format that just contains the number(s) that make up the key, with very little metadata. The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details.
| Key type | PSA import/export format |
| -------- | ------------------------ |
@@ -795,95 +795,45 @@
There is no equivalent of `mbedtls_pk_parse_keyfile` and `mbedtls_pk_parse_public_keyfile`. Either call the legacy function or load the file data manually.
-A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsections for ways to use the PK module for key parsing and construct a PSA key object from the PK object.
+A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsection for how to use the PK module for key parsing and construct a PSA key object from the PK object.
-#### Importing legacy keys via the PK module
+### Creating a PSA key via PK
-You can use glue functions in the PK module to create a key object using the legacy API, then import that object into the PSA subsystem. This is useful for use cases that the PSA API does not currently cover, such as:
+You can use the PK module as an intermediate step to create an RSA or ECC key for use with PSA. This is useful for use cases that the PSA API does not currently cover, such as:
* Parsing a key in a format with metadata without knowing its type ahead of time.
+* Parsing a key in a format that the PK module supports, but `psa_import_key` doesn't.
* Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`.
* Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters.
-* Generating an RSA key with $e \ne 65537$.
-#### Importing a PK key by wrapping
+For such use cases:
-If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)). This function automatically determines the PSA key type and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this workflow is useful are:
+1. First create a PK object with the desired key material.
+2. Call [`mbedtls_pk_get_psa_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a7aa7b33cffb6981d95d1632631de9244) to fill PSA attributes corresponding to the PK key. Pass one of the following values as the `usage` parameter:
+ * `PSA_KEY_USAGE_SIGN_HASH` or `PSA_KEY_USAGE_SIGN_MESSAGE` for a key pair used for signing.
+ * `PSA_KEY_USAGE_DECRYPT` for a key pair used for decryption.
+ * `PSA_KEY_USAGE_DERIVE` for a key pair used for key agreement.
+ * `PSA_KEY_USAGE_VERIFY_HASH` or `PSA_KEY_USAGE_VERIFY_MESSAGE` for a public key pair used for signature verification.
+ * `PSA_KEY_USAGE_ENCRYPT` for a key pair used for encryption.
+3. Optionally, tweak the attributes (this is rarely necessary). For example:
+ * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de), [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) and/or [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to change the key's policy (by default, it allows what can be done through the PK module).
+ · Call [`psa_set_key_id`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae48fcfdc72a23e7499957d7f54ff5a64) and perhaps [`psa_set_key_lifetime`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac03ccf09ca6d36cc3d5b43f8303db6f7) to create a PSA persistent key.
+4. Call [`mbedtls_pk_import_into_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ad59835d14832daf0f4b4bd0a4555abb9) to import the key into the PSA key store.
+5. You can now free the PK object with `mbedtls_pk_free`.
-* You have working code that's calling `mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`, `mbedtls_pk_parse_keyfile` or `mbedtls_pk_parse_public_keyfile` to create a PK object.
-* You have working code that's using the `rsa.h` or `ecp.h` API to create a key object, and there is no PSA equivalent.
-
-You can use this workflow to import an RSA key via an `mbedtls_rsa_context` object or an ECC key via an `mbedtls_ecp_keypair` object:
-
-1. Call `mbedtls_pk_init` then `mbedtls_pk_setup` to set up a PK context for the desired key type (`MBEDTLS_PK_RSA` or `MBEDTLS_PK_ECKEY`).
-2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context.
-3. Call `mbedtls_rsa_xxx` or `mbedtls_ecp_xxx` functions to construct the desired key. For example:
- * `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete` to create an RSA private key without all the parameters required by the PSA API.
- * `mbedtls_rsa_gen_key` to generate an RSA private key with a custom public exponent.
-4. Call `mbedtls_pk_wrap_as_opaque` as described above to create a corresponding PSA key object.
-5. Call `mbedtls_pk_free` to free the resources associated with the PK object.
-
-#### Importing a PK key by export-import
-
-This section explains how to export a PK object in the PSA import format. The process depends on the key type. You can use `mbedtls_pk_get_type` or `mbedtls_pk_can_do` to distinguish between RSA and ECC keys. The snippets below assume that the key is in an `mbedtls_pk_context pk`, and omit error checking.
-
-For an RSA private key:
+Here is some sample code illustrating the above process, with error checking omitted.
```
-unsigned char buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
-size_t length = mbedtls_pk_write_key_der(&pk, buf, sizeof(buf));
+mbedtls_pk_context pk;
+mbedtls_pk_init(&pk);
+mbedtls_pk_parse_key(&pk, key_buffer, key_buffer_length, NULL, 0,
+ mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-psa_set_key_attributes(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
-psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
-psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
-psa_key_id_t key_id = 0;
-psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id);
+mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &attributes);
+psa_key_id_t key_id;
+mbedtls_pk_import_into_psa(&pk, &attributes, &key_id);
mbedtls_pk_free(&pk);
-```
-
-For an ECC private key (a future version of Mbed TLS [will provide a more direct way to find the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764)):
-
-```
-unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
-size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
-mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk);
-psa_ecc_curve_t curve;
-{
- mbedtls_ecp_group grp;
- mbedtls_ecp_group_init(&grp);
- mbedtls_ecp_point Q;
- mbedtls_ecp_point_init(&Q);
- mbedtls_mpi d;
- mbedtls_mpi_init(&d);
- mbedtls_ecp_export(ec, &grp, &d, &Q);
- size_t bits;
- curve = mbedtls_ecc_group_to_psa(grp.id, &bits);
- mbedtls_ecp_group_free(&grp);
- mbedtls_ecp_point_free(&Q);
- mbedtls_mpi_free(&d);
-}
-mbedtls_ecp_write_key(ec, buf, length);
-psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
-psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
-psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
-psa_key_id_t key_id = 0;
-psa_import_key(&attributes, buf, length, &key_id);
-mbedtls_pk_free(&pk);
-```
-
-For an RSA or ECC public key:
-
-```
-unsigned char buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
-size_t length = mbedtls_pk_write_pubkey(&pk, buf, sizeof(buf));
-psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-psa_set_key_attributes(&attributes, ...); // need to determine the type manually
-psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
-psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
-psa_key_id_t key_id = 0;
-psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id);
-mbedtls_pk_free(&pk);
+psa_sign_hash(key_id, ...);
```
#### Importing an elliptic curve key from ECP
@@ -900,8 +850,8 @@
// Omitted: fill ec with key material
// (the public key will not be used and does not need to be set)
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
-size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
-mbedtls_ecp_write_key(&ec, buf, length);
+size_t length;
+mbedtls_ecp_write_key_ext(&ec, &length, buf, sizeof(buf));
psa_ecc_curve_t curve = ...; // need to determine the curve family manually
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
@@ -952,11 +902,33 @@
The export format is the same format used for `psa_import_key`, described in “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” above.
-A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exporting a PK key by wrapping](#exporting-a-pk-key-by-wrapping)” for ways to use the PK module to format a PSA key.
+A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exposing a PSA key via PK](#exposing-a-psa-key-via-pk)” for ways to use the PK module to format a PSA key.
-#### Exporting a PK key by wrapping
+#### Exposing a PSA key via PK
-You can wrap a PSA key object in a PK key context with `mbedtls_pk_setup_opaque`. This allows you to call functions such as `mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey` to export the key data in various formats.
+This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. The PSA key must be an RSA or ECC key since the PK module does not support DH keys. Three functions from `pk.h` help with that:
+
+* [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed.
+* [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies the public part of a PSA key into a PK object. The PK object remains valid even if the PSA key is destroyed.
+* [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. This functionality is only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. The PK object has the type `MBEDTLS_PK_OPAQUE` regardless of whether the key is an RSA or ECC key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive.
+
+Here is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair.
+```
+int write_psa_pubkey(psa_key_id_t key_id,
+ unsigned char *buf, size_t size, size_t *len) {
+ mbedtls_pk_context pk;
+ mbedtls_pk_init(&pk);
+ int ret = mbedtls_pk_copy_public_from_psa(key_id, &pk);
+ if (ret != 0) goto exit;
+ ret = mbedtls_pk_write_pubkey_der(&pk, buf, size);
+ if (ret < 0) goto exit;
+ *len = ret;
+ memmove(buf, buf + size - ret, ret);
+ ret = 0;
+exit:
+ mbedtls_pk_free(&pk);
+}
+```
### Signature operations
@@ -983,7 +955,8 @@
#### ECDSA signature
-**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765).
+**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. To convert between the two formats, use [`mbedtls_ecdsa_raw_to_der`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga9295799b5437bdff8ce8abd524c5ef2e) or [`mbedtls_ecdsa_der_to_raw`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga33b3cf65d5992ccc724b7ee00186ae61).
+
<!-- The following are specific to the DER format and therefore have no PSA equivalent: MBEDTLS_ECDSA_MAX_SIG_LEN, MBEDTLS_ECDSA_MAX_LEN -->
ECDSA is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_verify` and `mbedtls_ecdsa_read_signature`.
@@ -1300,7 +1273,7 @@
The PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`:
* Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future.
-* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key`.
+* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key_ext`.
* Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants).
### Additional information about RSA
diff --git a/docs/tls13-early-data.md b/docs/tls13-early-data.md
new file mode 100644
index 0000000..4b6f5d3
--- /dev/null
+++ b/docs/tls13-early-data.md
@@ -0,0 +1,192 @@
+
+Writing early data
+------------------
+
+An application function to write and send a buffer of data to a server through
+TLS may plausibly look like:
+
+```
+int write_data(mbedtls_ssl_context *ssl,
+ const unsigned char *data_to_write,
+ size_t data_to_write_len,
+ size_t *data_written)
+{
+ int ret;
+ *data_written = 0;
+
+ while (*data_written < data_to_write_len) {
+ ret = mbedtls_ssl_write(ssl, data_to_write + *data_written,
+ data_to_write_len - *data_written);
+
+ if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_WANT_READ &&
+ ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ return ret;
+ }
+
+ *data_written += ret;
+ }
+
+ return 0;
+}
+```
+where ssl is the SSL context to use, data_to_write the address of the data
+buffer and data_to_write_len the number of data bytes. The handshake may
+not be completed, not even started for the SSL context ssl when the function is
+called and in that case the mbedtls_ssl_write() API takes care transparently of
+completing the handshake before to write and send data to the server. The
+mbedtls_ssl_write() may not be able to write and send all data in one go thus
+the need for a loop calling it as long as there are still data to write and
+send.
+
+An application function to write and send early data and only early data,
+data sent during the first flight of client messages while the handshake is in
+its initial phase, would look completely similar but the call to
+mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write().
+```
+int write_early_data(mbedtls_ssl_context *ssl,
+ const unsigned char *data_to_write,
+ size_t data_to_write_len,
+ size_t *data_written)
+{
+ int ret;
+ *data_written = 0;
+
+ while (*data_written < data_to_write_len) {
+ ret = mbedtls_ssl_write_early_data(ssl, data_to_write + *data_written,
+ data_to_write_len - *data_written);
+
+ if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_WANT_READ &&
+ ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ return ret;
+ }
+
+ *data_written += ret;
+ }
+
+ return 0;
+}
+```
+Note that compared to write_data(), write_early_data() can also return
+MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled
+specifically by the user of write_early_data(). A fresh SSL context (typically
+just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would
+be expected when calling `write_early_data`.
+
+All together, code to write and send a buffer of data as long as possible as
+early data and then as standard post-handshake application data could
+plausibly look like:
+
+```
+ret = write_early_data(ssl,
+ data_to_write,
+ data_to_write_len,
+ &early_data_written);
+if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) {
+ goto error;
+}
+
+ret = write_data(ssl,
+ data_to_write + early_data_written,
+ data_to_write_len - early_data_written,
+ &data_written);
+if (ret < 0) {
+ goto error;
+}
+
+data_written += early_data_written;
+```
+
+Finally, taking into account that the server may reject early data, application
+code to write and send a buffer of data could plausibly look like:
+```
+ret = write_early_data(ssl,
+ data_to_write,
+ data_to_write_len,
+ &early_data_written);
+if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) {
+ goto error;
+}
+
+/*
+ * Make sure the handshake is completed as it is a requisite of
+ * mbedtls_ssl_get_early_data_status().
+ */
+while (!mbedtls_ssl_is_handshake_over(ssl)) {
+ ret = mbedtls_ssl_handshake(ssl);
+ if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_WANT_READ &&
+ ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ goto error;
+ }
+}
+
+ret = mbedtls_ssl_get_early_data_status(ssl);
+if (ret < 0) {
+ goto error;
+}
+
+if (ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
+ early_data_written = 0;
+}
+
+ret = write_data(ssl,
+ data_to_write + early_data_written,
+ data_to_write_len - early_data_written,
+ &data_written);
+if (ret < 0) {
+ goto error;
+}
+
+data_written += early_data_written;
+```
+
+Reading early data
+------------------
+Mbed TLS provides the mbedtls_ssl_read_early_data() API to read the early data
+that a TLS 1.3 server might receive during the TLS 1.3 handshake.
+
+While establishing a TLS 1.3 connection with a client using a combination
+of the mbedtls_ssl_handshake(), mbedtls_ssl_read() and mbedtls_ssl_write() APIs,
+the reception of early data is signaled by an API returning the
+MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA error code. Early data can then be read
+with the mbedtls_ssl_read_early_data() API.
+
+For example, a typical code to establish a TLS connection, where ssl is the SSL
+context to use:
+```
+while ((int ret = mbedtls_ssl_handshake(&ssl)) != 0) {
+
+ if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_WANT_READ &&
+ ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ break;
+ }
+}
+```
+could be adapted to handle early data in the following way:
+```
+size_t data_read_len = 0;
+while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
+
+ if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
+ ret = mbedtls_ssl_read_early_data(&ssl,
+ buffer + data_read_len,
+ sizeof(buffer) - data_read_len);
+ if (ret < 0) {
+ break;
+ }
+ data_read_len += ret;
+ continue;
+ }
+
+ if (ret < 0 &&
+ ret != MBEDTLS_ERR_SSL_WANT_READ &&
+ ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ break;
+ }
+}
+```
diff --git a/framework b/framework
new file mode 160000
index 0000000..750634d
--- /dev/null
+++ b/framework
@@ -0,0 +1 @@
+Subproject commit 750634d3a51eb9d61b59fd5d801546927c946588
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 931e06d..71d7b97 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -51,15 +51,15 @@
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
- * Maximum window size used for modular exponentiation. Default: 2
+ * Maximum window size used for modular exponentiation. Default: 3
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
- * for the sliding window calculation. (So 64 by default)
+ * for the sliding window calculation. (So 8 by default)
*
* Reduction in size, reduces speed.
*/
-#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
+#define MBEDTLS_MPI_WINDOW_SIZE 3 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 792db79..a0909d6 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -142,6 +142,19 @@
mbedtls_ecdh_context;
/**
+ * \brief Return the ECP group for provided context.
+ *
+ * \note To access group specific fields, users should use
+ * `mbedtls_ecp_curve_info_from_grp_id` or
+ * `mbedtls_ecp_group_load` on the extracted `group_id`.
+ *
+ * \param ctx The ECDH context to parse. This must not be \c NULL.
+ *
+ * \return The \c mbedtls_ecp_group_id of the context.
+ */
+mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx);
+
+/**
* \brief Check whether a given group can be used for ECDH.
*
* \param gid The ECP group ID to check.
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 0201963..d8f73ae 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -24,6 +24,7 @@
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
#include "mbedtls/bignum.h"
@@ -1327,10 +1328,11 @@
int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
const unsigned char *buf, size_t buflen);
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/**
* \brief This function exports an elliptic curve private key.
*
- * \note Note that although this function accepts an output
+ * \deprecated Note that although this function accepts an output
* buffer that is smaller or larger than the key, most key
* import interfaces require the output to have exactly
* key's nominal length. It is generally simplest to
@@ -1338,6 +1340,10 @@
* checking that the output buffer is large enough.
* See the description of the \p buflen parameter for
* how to calculate the nominal length.
+ * To avoid this difficulty, use mbedtls_ecp_write_key_ext()
+ * instead.
+ * mbedtls_ecp_write_key() is deprecated and will be
+ * removed in a future version of the library.
*
* \note If the private key was not set in \p key,
* the output is unspecified. Future versions
@@ -1367,8 +1373,31 @@
* representation is larger than the available space in \p buf.
* \return Another negative error code on different kinds of failure.
*/
-int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
- unsigned char *buf, size_t buflen);
+int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
+ unsigned char *buf, size_t buflen);
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function exports an elliptic curve private key.
+ *
+ * \param key The private key.
+ * \param olen On success, the length of the private key.
+ * This is always (`grp->nbits` + 7) / 8 bytes
+ * where `grp->nbits` is the private key size in bits.
+ * \param buf The output buffer for containing the binary representation
+ * of the key.
+ * \param buflen The total length of the buffer in bytes.
+ * #MBEDTLS_ECP_MAX_BYTES is always sufficient.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
+ * representation is larger than the available space in \p buf.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is
+ * set in \p key.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
+ size_t *olen, unsigned char *buf, size_t buflen);
/**
* \brief This function exports an elliptic curve public key.
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 7cf4153..cf6d406 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1854,9 +1854,6 @@
* Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3
* is not enabled, this option does not have any effect on the build.
*
- * This feature is experimental, not completed and thus not ready for
- * production.
- *
* \note The maximum amount of early data can be set with
* MBEDTLS_SSL_MAX_EARLY_DATA_SIZE.
*
@@ -2211,7 +2208,7 @@
* Enable AES-NI support on x86-64 or x86-32.
*
* \note AESNI is only supported with certain compilers and target options:
- * - Visual Studio 2013: supported.
+ * - Visual Studio: supported
* - GCC, x86-64, target not explicitly supporting AESNI:
* requires MBEDTLS_HAVE_ASM.
* - GCC, x86-32, target not explicitly supporting AESNI:
@@ -3201,6 +3198,9 @@
* \deprecated This feature is deprecated. Please switch to the PSA driver
* interface.
*
+ * \warning This feature is not thread-safe, and should not be used in a
+ * multi-threaded environment.
+ *
* Module: library/psa_crypto_se.c
*
* Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
@@ -4142,10 +4142,6 @@
*
* If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not
* have any impact on the build.
- *
- * This feature is experimental, not completed and thus not ready for
- * production.
- *
*/
//#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 534712b..fde302f 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -458,7 +458,7 @@
* PSA_ALG_RSA_PKCS1V15_CRYPT,
* PSA_ALG_ECDSA(hash),
* PSA_ALG_ECDH, where hash is a specific hash.
- * \param usage PSA usage flag to check against, must be composed of:
+ * \param usage PSA usage flag to check against, must be composed of:
* PSA_KEY_USAGE_SIGN_HASH
* PSA_KEY_USAGE_DECRYPT
* PSA_KEY_USAGE_DERIVE.
@@ -479,25 +479,25 @@
psa_key_usage_t usage);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/**
* \brief Determine valid PSA attributes that can be used to
* import a key into PSA.
*
- * The attributes determined by this function are suitable
- * for calling mbedtls_pk_import_into_psa() to create
- * a PSA key with the same key material.
+ * The attributes determined by this function are suitable
+ * for calling mbedtls_pk_import_into_psa() to create
+ * a PSA key with the same key material.
*
- * The typical flow of operations involving this function is
- * ```
- * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- * int ret = mbedtls_pk_get_psa_attributes(pk, &attributes);
- * if (ret != 0) ...; // error handling omitted
- * // Tweak attributes if desired
- * psa_key_id_t key_id = 0;
- * ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id);
- * if (ret != 0) ...; // error handling omitted
- * ```
+ * The typical flow of operations involving this function is
+ * ```
+ * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ * int ret = mbedtls_pk_get_psa_attributes(pk, &attributes);
+ * if (ret != 0) ...; // error handling omitted
+ * // Tweak attributes if desired
+ * psa_key_id_t key_id = 0;
+ * ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id);
+ * if (ret != 0) ...; // error handling omitted
+ * ```
*
* \note This function does not support RSA-alt contexts
* (set up with mbedtls_pk_setup_rsa_alt()).
@@ -596,24 +596,23 @@
/**
* \brief Import a key into the PSA key store.
*
- * This function is equivalent to calling psa_import_key()
- * with the key material from \p pk.
+ * This function is equivalent to calling psa_import_key()
+ * with the key material from \p pk.
*
- * The typical way to use this function is:
- * -# Call mbedtls_pk_get_psa_attributes() to obtain
- * attributes for the given key.
- * -# If desired, modify the attributes, for example:
- * - To create a persistent key, call
- * psa_set_key_identifier() and optionally
- * psa_set_key_lifetime().
- * - To import only the public part of a key pair:
- * ```
- * psa_set_key_type(&attributes,
- * PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
- * psa_get_key_type(&attributes)));
- * ```
- * - Restrict the key usage if desired.
- * -# Call mbedtls_pk_import_into_psa().
+ * The typical way to use this function is:
+ * -# Call mbedtls_pk_get_psa_attributes() to obtain
+ * attributes for the given key.
+ * -# If desired, modify the attributes, for example:
+ * - To create a persistent key, call
+ * psa_set_key_identifier() and optionally
+ * psa_set_key_lifetime().
+ * - To import only the public part of a key pair:
+ *
+ * psa_set_key_type(&attributes,
+ * PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
+ * psa_get_key_type(&attributes)));
+ * - Restrict the key usage if desired.
+ * -# Call mbedtls_pk_import_into_psa().
*
* \note This function does not support RSA-alt contexts
* (set up with mbedtls_pk_setup_rsa_alt()).
@@ -640,7 +639,76 @@
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id);
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+/**
+ * \brief Create a PK context starting from a key stored in PSA.
+ * This key:
+ * - must be exportable and
+ * - must be an RSA or EC key pair or public key (FFDH is not supported in PK).
+ *
+ * The resulting PK object will be a transparent type:
+ * - #MBEDTLS_PK_RSA for RSA keys or
+ * - #MBEDTLS_PK_ECKEY for EC keys.
+ *
+ * Once this functions returns the PK object will be completely
+ * independent from the original PSA key that it was generated
+ * from.
+ * Calling mbedtls_pk_sign(), mbedtls_pk_verify(),
+ * mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting
+ * PK context will perform the corresponding algorithm for that
+ * PK context type.
+ * * For ECDSA, the choice of deterministic vs randomized will
+ * be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC.
+ * * For an RSA key, the output PK context will allow both
+ * encrypt/decrypt and sign/verify regardless of the original
+ * key's policy.
+ * The original key's policy determines the output key's padding
+ * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS,
+ * otherwise PKCS1 v1.5 is set.
+ *
+ * \param key_id The key identifier of the key stored in PSA.
+ * \param pk The PK context that will be filled. It must be initialized,
+ * but not set up.
+ *
+ * \return 0 on success.
+ * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input
+ * parameters are not correct.
+ */
+int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk);
+
+/**
+ * \brief Create a PK context for the public key of a PSA key.
+ *
+ * The key must be an RSA or ECC key. It can be either a
+ * public key or a key pair, and only the public key is copied.
+ * The resulting PK object will be a transparent type:
+ * - #MBEDTLS_PK_RSA for RSA keys or
+ * - #MBEDTLS_PK_ECKEY for EC keys.
+ *
+ * Once this functions returns the PK object will be completely
+ * independent from the original PSA key that it was generated
+ * from.
+ * Calling mbedtls_pk_verify() or
+ * mbedtls_pk_encrypt() on the resulting
+ * PK context will perform the corresponding algorithm for that
+ * PK context type.
+ *
+ * For an RSA key, the output PK context will allow both
+ * encrypt and verify regardless of the original key's policy.
+ * The original key's policy determines the output key's padding
+ * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS,
+ * otherwise PKCS1 v1.5 is set.
+ *
+ * \param key_id The key identifier of the key stored in PSA.
+ * \param pk The PK context that will be filled. It must be initialized,
+ * but not set up.
+ *
+ * \return 0 on success.
+ * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input
+ * parameters are not correct.
+ */
+int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk);
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
/**
* \brief Verify signature (including padding if relevant).
@@ -1213,33 +1281,6 @@
const mbedtls_pk_context *key);
#endif /* MBEDTLS_PK_WRITE_C */
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/**
- * \brief Turn an EC or RSA key into an opaque one.
- *
- * \warning This is a temporary utility function for tests. It might
- * change or be removed at any time without notice.
- *
- * \param pk Input: the EC or RSA key to import to a PSA key.
- * Output: a PK context wrapping that PSA key.
- * \param key Output: a PSA key identifier.
- * It's the caller's responsibility to call
- * psa_destroy_key() on that key identifier after calling
- * mbedtls_pk_free() on the PK context.
- * \param alg The algorithm to allow for use with that key.
- * \param usage The usage to allow for use with that key.
- * \param alg2 The secondary algorithm to allow for use with that key.
- *
- * \return \c 0 if successful.
- * \return An Mbed TLS error code otherwise.
- */
-int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
- mbedtls_svc_key_id_t *key,
- psa_algorithm_t alg,
- psa_key_usage_t usage,
- psa_algorithm_t alg2);
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
#ifdef __cplusplus
}
#endif
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 984f031..c78cc23 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -21,44 +21,24 @@
* otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
#include <mbedtls/asn1write.h>
-#if defined(MBEDTLS_PSA_CRYPTO_C)
-
-/* Expose whatever RNG the PSA subsystem uses to applications using the
- * mbedtls_xxx API. The declarations and definitions here need to be
- * consistent with the implementation in library/psa_crypto_random_impl.h.
- * See that file for implementation documentation. */
-
-
-/* The type of a `f_rng` random generator function that many library functions
- * take.
- *
- * This type name is not part of the Mbed TLS stable API. It may be renamed
- * or moved without warning.
- */
-typedef int mbedtls_f_rng_t(void *p_rng, unsigned char *output, size_t output_size);
-
-#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/** The random generator function for the PSA subsystem.
*
* This function is suitable as the `f_rng` random generator function
- * parameter of many `mbedtls_xxx` functions. Use #MBEDTLS_PSA_RANDOM_STATE
- * to obtain the \p p_rng parameter.
+ * parameter of many `mbedtls_xxx` functions.
*
* The implementation of this function depends on the configuration of the
* library.
*
- * \note Depending on the configuration, this may be a function or
- * a pointer to a function.
- *
* \note This function may only be used if the PSA crypto subsystem is active.
* This means that you must call psa_crypto_init() before any call to
* this function, and you must not call this function after calling
* mbedtls_psa_crypto_free().
*
- * \param p_rng The random generator context. This must be
- * #MBEDTLS_PSA_RANDOM_STATE. No other state is
- * supported.
+ * \param p_rng This parameter is only kept for backward compatibility
+ * reasons with legacy `f_rng` functions and it's ignored.
+ * Set to #MBEDTLS_PSA_RANDOM_STATE or NULL.
* \param output The buffer to fill. It must have room for
* \c output_size bytes.
* \param output_size The number of bytes to write to \p output.
@@ -80,32 +60,11 @@
/** The random generator state for the PSA subsystem.
*
- * This macro expands to an expression which is suitable as the `p_rng`
- * random generator state parameter of many `mbedtls_xxx` functions.
- * It must be used in combination with the random generator function
- * mbedtls_psa_get_random().
- *
- * The implementation of this macro depends on the configuration of the
- * library. Do not make any assumption on its nature.
+ * This macro always expands to NULL because the `p_rng` parameter is unused
+ * in mbedtls_psa_get_random(), but it's kept for interface's backward
+ * compatibility.
*/
-#define MBEDTLS_PSA_RANDOM_STATE NULL
-
-#else /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
-
-#if defined(MBEDTLS_CTR_DRBG_C)
-#include "mbedtls/ctr_drbg.h"
-typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
-static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
-#elif defined(MBEDTLS_HMAC_DRBG_C)
-#include "mbedtls/hmac_drbg.h"
-typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
-static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
-#endif
-extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
-
-#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
-
-#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
+#define MBEDTLS_PSA_RANDOM_STATE NULL
/** \defgroup psa_tls_helpers TLS helper functions
* @{
@@ -180,7 +139,7 @@
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 08c628a..172d469 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -734,6 +734,21 @@
}
mbedtls_ssl_states;
+/*
+ * Early data status, client side only.
+ */
+
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
+typedef enum {
+/*
+ * See documentation of mbedtls_ssl_get_early_data_status().
+ */
+ MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED,
+ MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED,
+ MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED,
+} mbedtls_ssl_early_data_status;
+#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
+
/**
* \brief Callback type: send data on the network.
*
@@ -1289,6 +1304,11 @@
char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C)
+ char *ticket_alpn; /*!< ALPN negotiated in the session
+ during which the ticket was generated. */
+#endif
+
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C)
/*! Time in milliseconds when the last ticket was received. */
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time);
@@ -1673,33 +1693,29 @@
#endif /* MBEDTLS_SSL_RENEGOTIATION */
/**
- * Maximum TLS version to be negotiated, then negotiated TLS version.
+ * Maximum TLS version to be negotiated, then negotiated TLS version.
*
- * It is initialized as the configured maximum TLS version to be
- * negotiated by mbedtls_ssl_setup().
+ * It is initialized as the configured maximum TLS version to be
+ * negotiated by mbedtls_ssl_setup().
*
- * When renegotiating or resuming a session, it is overwritten in the
- * ClientHello writing preparation stage with the previously negotiated
- * TLS version.
+ * When renegotiating or resuming a session, it is overwritten in the
+ * ClientHello writing preparation stage with the previously negotiated
+ * TLS version.
*
- * On client side, it is updated to the TLS version selected by the server
- * for the handshake when the ServerHello is received.
+ * On client side, it is updated to the TLS version selected by the server
+ * for the handshake when the ServerHello is received.
*
- * On server side, it is updated to the TLS version the server selects for
- * the handshake when the ClientHello is received.
+ * On server side, it is updated to the TLS version the server selects for
+ * the handshake when the ClientHello is received.
*/
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
/**
- * Status of the negotiation of the use of early data.
- * See the documentation of mbedtls_ssl_get_early_data_status() for more
- * information.
- *
- * Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is
- * reset.
+ * State of the negotiation and transfer of early data. Reset to
+ * MBEDTLS_SSL_EARLY_DATA_STATE_IDLE when the context is reset.
*/
- int MBEDTLS_PRIVATE(early_data_status);
+ int MBEDTLS_PRIVATE(early_data_state);
#endif
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
@@ -1818,7 +1834,8 @@
* within a single datagram. */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
-#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+#if defined(MBEDTLS_SSL_SRV_C)
/*
* One of:
* MBEDTLS_SSL_EARLY_DATA_NO_DISCARD
@@ -1827,6 +1844,8 @@
*/
uint8_t MBEDTLS_PRIVATE(discard_early_data_record);
#endif
+ uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */
+#endif /* MBEDTLS_SSL_EARLY_DATA */
/*
* Record layer (outgoing data)
@@ -2083,9 +2102,6 @@
* MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have
* been received. To read the early data, call mbedtls_ssl_read_early_data()
* before calling the original function again.
- *
- * \warning This interface is experimental and may change without notice.
- *
*/
void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf,
int early_data_enabled);
@@ -2111,12 +2127,9 @@
* \param[in] conf The SSL configuration to use.
* \param[in] max_early_data_size The maximum amount of 0-RTT data.
*
- * \warning This interface is experimental and may change without notice.
- *
* \warning This interface DOES NOT influence/limit the amount of early data
* that can be received through previously created and issued tickets,
* which clients may have stored.
- *
*/
void mbedtls_ssl_conf_max_early_data_size(
mbedtls_ssl_config *conf, uint32_t max_early_data_size);
@@ -2677,6 +2690,43 @@
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
/**
+ * \brief Get the session-id buffer.
+ *
+ * \param session SSL session.
+ *
+ * \return The address of the session-id buffer.
+ */
+static inline unsigned const char (*mbedtls_ssl_session_get_id(const mbedtls_ssl_session *
+ session))[32]
+{
+ return &session->MBEDTLS_PRIVATE(id);
+}
+
+/**
+ * \brief Get the size of the session-id.
+ *
+ * \param session SSL session.
+ *
+ * \return size_t size of session-id buffer.
+ */
+static inline size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *session)
+{
+ return session->MBEDTLS_PRIVATE(id_len);
+}
+
+/**
+ * \brief Get the ciphersuite-id.
+ *
+ * \param session SSL session.
+ *
+ * \return int represetation for ciphersuite.
+ */
+static inline int mbedtls_ssl_session_get_ciphersuite_id(const mbedtls_ssl_session *session)
+{
+ return session->MBEDTLS_PRIVATE(ciphersuite);
+}
+
+/**
* \brief Configure a key export callback.
* (Default: none.)
*
@@ -5150,10 +5200,6 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 1
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 2
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 3
-
#if defined(MBEDTLS_SSL_SRV_C)
/**
* \brief Read at most 'len' bytes of early data
@@ -5177,6 +5223,11 @@
* same warnings apply to any use of the
* early_exporter_master_secret.
*
+ * \warning Mbed TLS does not implement any of the anti-replay defenses
+ * defined in section 8 of the TLS 1.3 specification:
+ * single-use of tickets or ClientHello recording within a
+ * given time window.
+ *
* \note This function is used in conjunction with
* mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() and mbedtls_ssl_write() to read early
@@ -5206,17 +5257,43 @@
* \brief Try to write exactly 'len' application data bytes while
* performing the handshake (early data).
*
+ * \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
+ * IMPORTANT NOTE from section 2.3 of the specification:
+ *
+ * The security properties for 0-RTT data are weaker than
+ * those for other kinds of TLS data. Specifically:
+ * - This data is not forward secret, as it is encrypted
+ * solely under keys derived using the offered PSK.
+ * - There are no guarantees of non-replay between connections.
+ * Protection against replay for ordinary TLS 1.3 1-RTT data
+ * is provided via the server's Random value, but 0-RTT data
+ * does not depend on the ServerHello and therefore has
+ * weaker guarantees. This is especially relevant if the
+ * data is authenticated either with TLS client
+ * authentication or inside the application protocol. The
+ * same warnings apply to any use of the
+ * early_exporter_master_secret.
+ *
* \note This function behaves mainly as mbedtls_ssl_write(). The
* specification of mbedtls_ssl_write() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS1.2) applies to this
- * function and the present documentation is restricted to the
- * differences with mbedtls_ssl_write().
+ * function and the present documentation is mainly restricted
+ * to the differences with mbedtls_ssl_write(). One noticeable
+ * difference though is that mbedtls_ssl_write() aims to
+ * complete the handshake before to write application data
+ * while mbedtls_ssl_write_early() aims to drive the handshake
+ * just past the point where it is not possible to send early
+ * data anymore.
*
* \param ssl SSL context
* \param buf buffer holding the data
* \param len how many bytes must be written
*
- * \return One additional specific return value:
+ * \return The (non-negative) number of bytes actually written if
+ * successful (may be less than \p len).
+ *
+ * \return One additional specific error code compared to
+ * mbedtls_ssl_write():
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA.
*
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA is returned when it
@@ -5237,9 +5314,11 @@
* already completed.
*
* It is not possible to write early data for the SSL context
- * \p ssl but this does not preclude for using it with
+ * \p ssl and any subsequent call to this API will return this
+ * error code. But this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
- * mbedtls_ssl_handshake().
+ * mbedtls_ssl_handshake() and the handshake can be
+ * completed by calling one of these APIs.
*
* \note This function may write early data only if the SSL context
* has been configured for the handshake with a PSK for which
@@ -5272,8 +5351,8 @@
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called
* prior to completion of the handshake.
*
- * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT if the client has
- * not indicated the use of early data to the server.
+ * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED if the client
+ * has not indicated the use of early data to the server.
*
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has
* indicated the use of early data and the server has accepted
diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
index f755ef3..12d4462 100644
--- a/include/mbedtls/ssl_ciphersuites.h
+++ b/include/mbedtls/ssl_ciphersuites.h
@@ -468,6 +468,11 @@
return info->MBEDTLS_PRIVATE(name);
}
+static inline int mbedtls_ssl_ciphersuite_get_id(const mbedtls_ssl_ciphersuite_t *info)
+{
+ return info->MBEDTLS_PRIVATE(id);
+}
+
size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info);
#ifdef __cplusplus
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 5842049..2ee1400 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -108,10 +108,16 @@
* least as strong as the strongest ciphersuite
* supported. Usually that means a 256-bit key.
*
- * \note The lifetime of the keys is twice the lifetime of tickets.
- * It is recommended to pick a reasonable lifetime so as not
+ * \note It is recommended to pick a reasonable lifetime so as not
* to negate the benefits of forward secrecy.
*
+ * \note The TLS 1.3 specification states that ticket lifetime must
+ * be smaller than seven days. If ticket lifetime has been
+ * set to a value greater than seven days in this module then
+ * if the TLS 1.3 is configured to send tickets after the
+ * handshake it will fail the connection when trying to send
+ * the first ticket.
+ *
* \return 0 if successful,
* or a specific MBEDTLS_ERR_XXX error code
*/
@@ -145,10 +151,16 @@
* \note \c klength must be sufficient for use by cipher specified
* to \c mbedtls_ssl_ticket_setup
*
- * \note The lifetime of the keys is twice the lifetime of tickets.
- * It is recommended to pick a reasonable lifetime so as not
+ * \note It is recommended to pick a reasonable lifetime so as not
* to negate the benefits of forward secrecy.
*
+ * \note The TLS 1.3 specification states that ticket lifetime must
+ * be smaller than seven days. If ticket lifetime has been
+ * set to a value greater than seven days in this module then
+ * if the TLS 1.3 is configured to send tickets after the
+ * handshake it will fail the connection when trying to send
+ * the first ticket.
+ *
* \return 0 if successful,
* or a specific MBEDTLS_ERR_XXX error code
*/
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index b4e0502..d50d04e 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -112,6 +112,20 @@
* psa_key_slot_state_transition(), psa_register_read(), psa_unregister_read(),
* psa_key_slot_has_readers() and psa_wipe_key_slot(). */
extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex;
+
+/*
+ * A mutex used to make the non-rng PSA global_data struct members thread safe.
+ *
+ * This mutex must be held when reading or writing to any of the PSA global_data
+ * structure members, other than the rng_state or rng struct. */
+extern mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex;
+
+/*
+ * A mutex used to make the PSA global_data rng data thread safe.
+ *
+ * This mutex must be held when reading or writing to the PSA
+ * global_data rng_state or rng struct members. */
+extern mbedtls_threading_mutex_t mbedtls_threading_psa_rngdata_mutex;
#endif
#endif /* MBEDTLS_THREADING_C */
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 3f1a1e7..1ce0d23 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -916,6 +916,18 @@
return ctx->MBEDTLS_PRIVATE(ext_types) & ext_type;
}
+/**
+ * \brief Access the ca_istrue field
+ *
+ * \param[in] crt Certificate to be queried, must not be \c NULL
+ *
+ * \return \c 1 if this a CA certificate \c 0 otherwise.
+ * \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not contain
+ * the Optional Basic Constraint extension.
+ *
+ */
+int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt);
+
/** \} name Structures and functions for parsing and writing X.509 certificates */
#if defined(MBEDTLS_X509_CRT_WRITE_C)
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index ac21e3e..6ed1f6c 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -59,7 +59,7 @@
psa_key_attributes_t *attributes,
psa_algorithm_t alg2)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
+ attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
}
/** Retrieve the enrollment algorithm policy from key attributes.
@@ -71,7 +71,7 @@
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
+ return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -129,7 +129,7 @@
psa_key_attributes_t *attributes,
psa_key_slot_number_t slot_number)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
+ attributes->MBEDTLS_PRIVATE(has_slot_number) = 1;
attributes->MBEDTLS_PRIVATE(slot_number) = slot_number;
}
@@ -142,8 +142,7 @@
static inline void psa_clear_key_slot_number(
psa_key_attributes_t *attributes)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) &=
- ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
+ attributes->MBEDTLS_PRIVATE(has_slot_number) = 0;
}
/** Register a key that is already present in a secure element.
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 683d841..3913551 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -266,35 +266,15 @@
* conditionals. */
#define PSA_MAX_KEY_BITS 0xfff8
-/** A mask of flags that can be stored in key attributes.
- *
- * This type is also used internally to store flags in slots. Internal
- * flags are defined in library/psa_crypto_core.h. Internal flags may have
- * the same value as external flags if they are properly handled during
- * key creation and in psa_get_key_attributes.
- */
-typedef uint16_t psa_key_attributes_flag_t;
-
-#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
- ((psa_key_attributes_flag_t) 0x0001)
-
-/* A mask of key attribute flags used externally only.
- * Only meant for internal checks inside the library. */
-#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
- MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
- 0)
-
-/* A mask of key attribute flags used both internally and externally.
- * Currently there aren't any. */
-#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
- 0)
-
-typedef struct {
+struct psa_key_attributes_s {
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+ psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
+ int MBEDTLS_PRIVATE(has_slot_number);
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
psa_key_type_t MBEDTLS_PRIVATE(type);
psa_key_bits_t MBEDTLS_PRIVATE(bits);
psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime);
psa_key_policy_t MBEDTLS_PRIVATE(policy);
- psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags);
/* This type has a different layout in the client view wrt the
* service view of the key id, i.e. in service view usually is
* expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined
@@ -307,31 +287,18 @@
* struct
*/
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id);
-} psa_core_key_attributes_t;
-
-#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_TYPE_NONE, 0, \
- PSA_KEY_LIFETIME_VOLATILE, \
- PSA_KEY_POLICY_INIT, 0, \
- MBEDTLS_SVC_KEY_ID_INIT }
-
-struct psa_key_attributes_s {
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
- psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
- /* With client/service separation, struct psa_key_attributes_s is
- * marshalled through a transport channel between the client and
- * service side implementation of the PSA Crypto APIs, thus having
- * the mbedtls_svc_key_id_t id as the last field of this structure
- * allows for a more efficient marshalling/unmarshalling of parameters
- */
- psa_core_key_attributes_t MBEDTLS_PRIVATE(core);
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-#define PSA_KEY_ATTRIBUTES_INIT { 0, PSA_CORE_KEY_ATTRIBUTES_INIT }
+#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, 0,
#else
-#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT }
+#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER
#endif
+#define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \
+ PSA_KEY_TYPE_NONE, 0, \
+ PSA_KEY_LIFETIME_VOLATILE, \
+ PSA_KEY_POLICY_INIT, \
+ MBEDTLS_SVC_KEY_ID_INIT }
static inline struct psa_key_attributes_s psa_key_attributes_init(void)
{
@@ -342,12 +309,12 @@
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t key)
{
- psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
+ psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(lifetime);
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = key;
+ attributes->MBEDTLS_PRIVATE(id) = key;
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) =
+ attributes->MBEDTLS_PRIVATE(lifetime) =
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_LIFETIME_PERSISTENT,
PSA_KEY_LIFETIME_GET_LOCATION(lifetime));
@@ -357,26 +324,26 @@
static inline mbedtls_svc_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id);
+ return attributes->MBEDTLS_PRIVATE(id);
}
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
static inline void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
mbedtls_key_owner_id_t owner)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
+ attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
}
#endif
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
psa_key_lifetime_t lifetime)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = lifetime;
+ attributes->MBEDTLS_PRIVATE(lifetime) = lifetime;
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
+ attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
#else
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = 0;
+ attributes->MBEDTLS_PRIVATE(id) = 0;
#endif
}
}
@@ -384,7 +351,7 @@
static inline psa_key_lifetime_t psa_get_key_lifetime(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
+ return attributes->MBEDTLS_PRIVATE(lifetime);
}
static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags)
@@ -402,53 +369,53 @@
psa_key_usage_t usage_flags)
{
psa_extend_key_usage_flags(&usage_flags);
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
+ attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
}
static inline psa_key_usage_t psa_get_key_usage_flags(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
+ return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
}
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
psa_algorithm_t alg)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
+ attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
}
static inline psa_algorithm_t psa_get_key_algorithm(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
+ return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
}
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) = type;
+ attributes->MBEDTLS_PRIVATE(type) = type;
}
static inline psa_key_type_t psa_get_key_type(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type);
+ return attributes->MBEDTLS_PRIVATE(type);
}
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits)
{
if (bits > PSA_MAX_KEY_BITS) {
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
+ attributes->MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
} else {
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
+ attributes->MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
}
}
static inline size_t psa_get_key_bits(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits);
+ return attributes->MBEDTLS_PRIVATE(bits);
}
/**
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 47ecf17..835604f 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -56,6 +56,7 @@
padlock.c
pem.c
pk.c
+ pk_ecc.c
pk_wrap.c
pkcs12.c
pkcs5.c
diff --git a/library/Makefile b/library/Makefile
index d11a98d..52d7944 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -1,3 +1,26 @@
+ifndef MBEDTLS_PATH
+MBEDTLS_PATH := ..
+endif
+
+GENERATED_FILES := \
+ error.c version_features.c \
+ ssl_debug_helpers_generated.c \
+ psa_crypto_driver_wrappers.h \
+ psa_crypto_driver_wrappers_no_static.c
+
+ifneq ($(GENERATED_FILES),$(wildcard $(GENERATED_FILES)))
+ ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make))
+ # Use the define keyword to get a multi-line message.
+ # GNU make appends ". Stop.", so tweak the ending of our message accordingly.
+ define error_message
+$(MBEDTLS_PATH)/framework/exported.make not found.
+Run `git submodule update --init` to fetch the submodule contents.
+This is a fatal error
+ endef
+ $(error $(error_message))
+ endif
+ include $(MBEDTLS_PATH)/framework/exported.make
+endif
# Also see "include/mbedtls/mbedtls_config.h"
@@ -125,6 +148,7 @@
padlock.o \
pem.o \
pk.o \
+ pk_ecc.o \
pk_wrap.o \
pkcs12.o \
pkcs5.o \
@@ -314,11 +338,6 @@
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
.PHONY: generated_files
-GENERATED_FILES = \
- error.c version_features.c \
- ssl_debug_helpers_generated.c \
- psa_crypto_driver_wrappers.h \
- psa_crypto_driver_wrappers_no_static.c
generated_files: $(GENERATED_FILES)
# See root Makefile
diff --git a/library/bignum.c b/library/bignum.c
index d3d72ab..c45fd5b 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -37,6 +37,19 @@
#include "mbedtls/platform.h"
+
+
+/*
+ * Conditionally select an MPI sign in constant time.
+ * (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
+ * values.)
+ */
+static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
+ signed short sign1, signed short sign2)
+{
+ return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
+}
+
/*
* Compare signed values in constant time
*/
@@ -112,7 +125,7 @@
{
mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
- X->s = (int) mbedtls_ct_uint_if(do_assign, Y->s, X->s);
+ X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
@@ -149,8 +162,8 @@
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
s = X->s;
- X->s = (int) mbedtls_ct_uint_if(do_swap, Y->s, X->s);
- Y->s = (int) mbedtls_ct_uint_if(do_swap, s, Y->s);
+ X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
+ Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
@@ -288,8 +301,7 @@
* This function is not constant-time. Leading zeros in Y may be removed.
*
* Ensure that X does not shrink. This is not guaranteed by the public API,
- * but some code in the bignum module relies on this property, for example
- * in mbedtls_mpi_exp_mod().
+ * but some code in the bignum module might still rely on this property.
*/
int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
{
@@ -1598,98 +1610,11 @@
return 0;
}
-static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N)
-{
- *mm = mbedtls_mpi_core_montmul_init(N->p);
-}
-
-/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
- *
- * \param[in,out] A One of the numbers to multiply.
- * It must have at least as many limbs as N
- * (A->n >= N->n), and any limbs beyond n are ignored.
- * On successful completion, A contains the result of
- * the multiplication A * B * R^-1 mod N where
- * R = (2^ciL)^n.
- * \param[in] B One of the numbers to multiply.
- * It must be nonzero and must not have more limbs than N
- * (B->n <= N->n).
- * \param[in] N The modulus. \p N must be odd.
- * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
- * This is -N^-1 mod 2^ciL.
- * \param[in,out] T A bignum for temporary storage.
- * It must be at least twice the limb size of N plus 1
- * (T->n >= 2 * N->n + 1).
- * Its initial content is unused and
- * its final content is indeterminate.
- * It does not get reallocated.
- */
-static void mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B,
- const mbedtls_mpi *N, mbedtls_mpi_uint mm,
- mbedtls_mpi *T)
-{
- mbedtls_mpi_core_montmul(A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p);
-}
-
-/*
- * Montgomery reduction: A = A * R^-1 mod N
- *
- * See mpi_montmul() regarding constraints and guarantees on the parameters.
- */
-static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
- mbedtls_mpi_uint mm, mbedtls_mpi *T)
-{
- mbedtls_mpi_uint z = 1;
- mbedtls_mpi U;
- U.n = 1;
- U.s = 1;
- U.p = &z;
-
- mpi_montmul(A, &U, N, mm, T);
-}
-
-/**
- * Select an MPI from a table without leaking the index.
- *
- * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
- * reads the entire table in order to avoid leaking the value of idx to an
- * attacker able to observe memory access patterns.
- *
- * \param[out] R Where to write the selected MPI.
- * \param[in] T The table to read from.
- * \param[in] T_size The number of elements in the table.
- * \param[in] idx The index of the element to select;
- * this must satisfy 0 <= idx < T_size.
- *
- * \return \c 0 on success, or a negative error code.
- */
-static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
- for (size_t i = 0; i < T_size; i++) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i],
- (unsigned char) mbedtls_ct_uint_eq(i, idx)));
- }
-cleanup:
- return ret;
-}
-
-/*
- * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
- */
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t window_bitsize;
- size_t i, j, nblimbs;
- size_t bufsize, nbits;
- size_t exponent_bits_in_window = 0;
- mbedtls_mpi_uint ei, mm, state;
- mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos;
- int neg;
if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -1705,261 +1630,88 @@
}
/*
- * Init temps and window size
+ * Ensure that the exponent that we are passing to the core is not NULL.
*/
- mpi_montg_init(&mm, N);
- mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T);
- mbedtls_mpi_init(&Apos);
- mbedtls_mpi_init(&WW);
- memset(W, 0, sizeof(W));
-
- i = mbedtls_mpi_bitlen(E);
-
- window_bitsize = (i > 671) ? 6 : (i > 239) ? 5 :
- (i > 79) ? 4 : (i > 23) ? 3 : 1;
-
-#if (MBEDTLS_MPI_WINDOW_SIZE < 6)
- if (window_bitsize > MBEDTLS_MPI_WINDOW_SIZE) {
- window_bitsize = MBEDTLS_MPI_WINDOW_SIZE;
+ if (E->n == 0) {
+ ret = mbedtls_mpi_lset(X, 1);
+ return ret;
}
-#endif
-
- const size_t w_table_used_size = (size_t) 1 << window_bitsize;
/*
- * This function is not constant-trace: its memory accesses depend on the
- * exponent value. To defend against timing attacks, callers (such as RSA
- * and DHM) should use exponent blinding. However this is not enough if the
- * adversary can find the exponent in a single trace, so this function
- * takes extra precautions against adversaries who can observe memory
- * access patterns.
- *
- * This function performs a series of multiplications by table elements and
- * squarings, and we want the prevent the adversary from finding out which
- * table element was used, and from distinguishing between multiplications
- * and squarings. Firstly, when multiplying by an element of the window
- * W[i], we do a constant-trace table lookup to obfuscate i. This leaves
- * squarings as having a different memory access patterns from other
- * multiplications. So secondly, we put the accumulator in the table as
- * well, and also do a constant-trace table lookup to multiply by the
- * accumulator which is W[x_index].
- *
- * This way, all multiplications take the form of a lookup-and-multiply.
- * The number of lookup-and-multiply operations inside each iteration of
- * the main loop still depends on the bits of the exponent, but since the
- * other operations in the loop don't have an easily recognizable memory
- * trace, an adversary is unlikely to be able to observe the exact
- * patterns.
- *
- * An adversary may still be able to recover the exponent if they can
- * observe both memory accesses and branches. However, branch prediction
- * exploitation typically requires many traces of execution over the same
- * data, which is defeated by randomized blinding.
+ * Allocate working memory for mbedtls_mpi_core_exp_mod()
*/
- const size_t x_index = 0;
- mbedtls_mpi_init(&W[x_index]);
-
- j = N->n + 1;
- /* All W[i] including the accumulator must have at least N->n limbs for
- * the mpi_montmul() and mpi_montred() calls later. Here we ensure that
- * W[1] and the accumulator W[x_index] are large enough. later we'll grow
- * other W[i] to the same length. They must not be shrunk midway through
- * this function!
- */
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j));
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2));
-
- /*
- * Compensate for negative A (and correct at the end)
- */
- neg = (A->s == -1);
- if (neg) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A));
- Apos.s = 1;
- A = &Apos;
+ size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
+ mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
+ if (T == NULL) {
+ return MBEDTLS_ERR_MPI_ALLOC_FAILED;
}
+ mbedtls_mpi RR;
+ mbedtls_mpi_init(&RR);
+
/*
* If 1st call, pre-compute R^2 mod N
*/
if (prec_RR == NULL || prec_RR->p == NULL) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1));
- MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL));
- MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
if (prec_RR != NULL) {
- memcpy(prec_RR, &RR, sizeof(mbedtls_mpi));
+ *prec_RR = RR;
}
} else {
- memcpy(&RR, prec_RR, sizeof(mbedtls_mpi));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
+ RR = *prec_RR;
}
/*
- * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+ * To preserve constness we need to make a copy of A. Using X for this to
+ * save memory.
*/
- if (mbedtls_mpi_cmp_mpi(A, N) >= 0) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N));
- /* This should be a no-op because W[1] is already that large before
- * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
- * in mpi_montmul() below, so let's make sure. */
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1));
- } else {
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A));
- }
-
- /* Note that this is safe because W[1] always has at least N->n limbs
- * (it grew above and was preserved by mbedtls_mpi_copy()). */
- mpi_montmul(&W[1], &RR, N, mm, &T);
+ MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
/*
- * W[x_index] = R^2 * R^-1 mod N = R mod N
+ * Compensate for negative A (and correct at the end).
*/
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[x_index], &RR));
- mpi_montred(&W[x_index], N, mm, &T);
+ X->s = 1;
-
- if (window_bitsize > 1) {
- /*
- * W[i] = W[1] ^ i
- *
- * The first bit of the sliding window is always 1 and therefore we
- * only need to store the second half of the table.
- *
- * (There are two special elements in the table: W[0] for the
- * accumulator/result and W[1] for A in Montgomery form. Both of these
- * are already set at this point.)
- */
- j = w_table_used_size / 2;
-
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1));
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1]));
-
- for (i = 0; i < window_bitsize - 1; i++) {
- mpi_montmul(&W[j], &W[j], N, mm, &T);
- }
-
- /*
- * W[i] = W[i - 1] * W[1]
- */
- for (i = j + 1; i < w_table_used_size; i++) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1));
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1]));
-
- mpi_montmul(&W[i], &W[1], N, mm, &T);
- }
+ /*
+ * Make sure that X is in a form that is safe for consumption by
+ * the core functions.
+ *
+ * - The core functions will not touch the limbs of X above N->n. The
+ * result will be correct if those limbs are 0, which the mod call
+ * ensures.
+ * - Also, X must have at least as many limbs as N for the calls to the
+ * core functions.
+ */
+ if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
+ MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
}
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
- nblimbs = E->n;
- bufsize = 0;
- nbits = 0;
- state = 0;
-
- while (1) {
- if (bufsize == 0) {
- if (nblimbs == 0) {
- break;
- }
-
- nblimbs--;
-
- bufsize = sizeof(mbedtls_mpi_uint) << 3;
- }
-
- bufsize--;
-
- ei = (E->p[nblimbs] >> bufsize) & 1;
-
- /*
- * skip leading 0s
- */
- if (ei == 0 && state == 0) {
- continue;
- }
-
- if (ei == 0 && state == 1) {
- /*
- * out of window, square W[x_index]
- */
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
- continue;
- }
-
- /*
- * add ei to current window
- */
- state = 2;
-
- nbits++;
- exponent_bits_in_window |= (ei << (window_bitsize - nbits));
-
- if (nbits == window_bitsize) {
- /*
- * W[x_index] = W[x_index]^window_bitsize R^-1 mod N
- */
- for (i = 0; i < window_bitsize; i++) {
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
- x_index));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
- }
-
- /*
- * W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N
- */
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
- exponent_bits_in_window));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
-
- state--;
- nbits = 0;
- exponent_bits_in_window = 0;
- }
+ /*
+ * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
+ */
+ {
+ mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
+ mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
+ mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
+ mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
}
/*
- * process the remaining bits
+ * Correct for negative A.
*/
- for (i = 0; i < nbits; i++) {
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
+ if (A->s == -1 && (E->p[0] & 1) != 0) {
+ mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
+ X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
- exponent_bits_in_window <<= 1;
-
- if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) {
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
- }
+ MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
}
- /*
- * W[x_index] = A^E * R * R^-1 mod N = A^E mod N
- */
- mpi_montred(&W[x_index], N, mm, &T);
-
- if (neg && E->n != 0 && (E->p[0] & 1) != 0) {
- W[x_index].s = -1;
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&W[x_index], N, &W[x_index]));
- }
-
- /*
- * Load the result in the output variable.
- */
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
-
cleanup:
- /* The first bit of the sliding window is always 1 and therefore the first
- * half of the table was unused. */
- for (i = w_table_used_size/2; i < w_table_used_size; i++) {
- mbedtls_mpi_free(&W[i]);
- }
-
- mbedtls_mpi_free(&W[x_index]);
- mbedtls_mpi_free(&W[1]);
- mbedtls_mpi_free(&T);
- mbedtls_mpi_free(&Apos);
- mbedtls_mpi_free(&WW);
+ mbedtls_mpi_zeroize_and_free(T, T_limbs);
if (prec_RR == NULL || prec_RR->p == NULL) {
mbedtls_mpi_free(&RR);
diff --git a/library/bignum_core.c b/library/bignum_core.c
index dfed60d..1a3e0b9 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -856,16 +856,17 @@
return c;
}
-mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
- size_t limbs)
+mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
+ size_t limbs)
{
+ volatile const mbedtls_mpi_uint *force_read_A = A;
mbedtls_mpi_uint bits = 0;
for (size_t i = 0; i < limbs; i++) {
- bits |= A[i];
+ bits |= force_read_A[i];
}
- return bits;
+ return mbedtls_ct_bool(bits);
}
void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,
diff --git a/library/bignum_core.h b/library/bignum_core.h
index b56be0a..92c8d47 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -662,11 +662,11 @@
* \param[in] A The MPI to test.
* \param limbs Number of limbs in \p A.
*
- * \return 0 if `A == 0`
- * non-0 (may be any value) if `A != 0`.
+ * \return MBEDTLS_CT_FALSE if `A == 0`
+ * MBEDTLS_CT_TRUE if `A != 0`.
*/
-mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
- size_t limbs);
+mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
+ size_t limbs);
/**
* \brief Returns the number of limbs of working memory required for
diff --git a/library/cmac.c b/library/cmac.c
index f40cae2..c4f0b54 100644
--- a/library/cmac.c
+++ b/library/cmac.c
@@ -56,22 +56,29 @@
size_t blocksize)
{
const unsigned char R_128 = 0x87;
- const unsigned char R_64 = 0x1B;
unsigned char R_n, mask;
- unsigned char overflow = 0x00;
+ uint32_t overflow = 0x00;
int i;
if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
R_n = R_128;
- } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
+ }
+#if defined(MBEDTLS_DES_C)
+ else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
+ const unsigned char R_64 = 0x1B;
R_n = R_64;
- } else {
+ }
+#endif
+ else {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
- for (i = (int) blocksize - 1; i >= 0; i--) {
- output[i] = input[i] << 1 | overflow;
- overflow = input[i] >> 7;
+ for (i = (int) blocksize - 4; i >= 0; i -= 4) {
+ uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
+ uint32_t new_overflow = i32 >> 31;
+ i32 = (i32 << 1) | overflow;
+ MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
+ overflow = new_overflow;
}
/* mask = ( input[0] >> 7 ) ? 0xff : 0x00
@@ -217,6 +224,10 @@
block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
state = ctx->cmac_ctx->state;
+ /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
+ * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
+ MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE);
+
/* Is there data still to process from the last call, that's greater in
* size than a block? */
if (cmac_ctx->unprocessed_len > 0 &&
@@ -284,6 +295,7 @@
cmac_ctx = ctx->cmac_ctx;
block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
+ MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning
state = cmac_ctx->state;
mbedtls_platform_zeroize(K1, sizeof(K1));
diff --git a/library/ecdh.c b/library/ecdh.c
index 52b1617..b276c6a 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -144,6 +144,15 @@
#endif
}
+mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx)
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+ return ctx->MBEDTLS_PRIVATE(grp).id;
+#else
+ return ctx->MBEDTLS_PRIVATE(grp_id);
+#endif
+}
+
/*
* Initialize context
*/
diff --git a/library/ecp.c b/library/ecp.c
index 66b3dc1..427059b 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -3302,6 +3302,7 @@
/*
* Write a private key.
*/
+#if !defined MBEDTLS_DEPRECATED_REMOVED
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen)
{
@@ -3332,6 +3333,39 @@
return ret;
}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
+ size_t *olen, unsigned char *buf, size_t buflen)
+{
+ size_t len = (key->grp.nbits + 7) / 8;
+ if (len > buflen) {
+ /* For robustness, ensure *olen <= buflen even on error. */
+ *olen = 0;
+ return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+ }
+ *olen = len;
+
+ /* Private key not set */
+ if (key->d.n == 0) {
+ return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ }
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
+ return mbedtls_mpi_write_binary_le(&key->d, buf, len);
+ }
+#endif
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
+ return mbedtls_mpi_write_binary(&key->d, buf, len);
+ }
+#endif
+
+ /* Private key set but no recognized curve type? This shouldn't happen. */
+ return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+}
/*
* Write a public key.
diff --git a/library/gcm.c b/library/gcm.c
index 90c1d1d..5dfac23 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -412,8 +412,17 @@
while (iv_len > 0) {
use_len = (iv_len < 16) ? iv_len : 16;
+#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wstringop-overflow=0"
+#endif
+
mbedtls_xor(ctx->y, ctx->y, p, use_len);
+#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
+#pragma GCC diagnostic pop
+#endif
+
gcm_mult(ctx, ctx->y, ctx->y);
iv_len -= use_len;
diff --git a/library/pk.c b/library/pk.c
index 1ded487..ec3741b 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -35,6 +35,10 @@
#include <limits.h>
#include <stdint.h>
+#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \
+ (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \
+ PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+
/*
* Initialise a mbedtls_pk_context
*/
@@ -320,14 +324,14 @@
}
psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes);
- /* Key's enrollment is available only when MBEDTLS_PSA_CRYPTO_CLIENT is
- * defined, i.e. when the Mbed TLS implementation of PSA Crypto is being used.
+ /* Key's enrollment is available only when an Mbed TLS implementation of PSA
+ * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined.
* Even though we don't officially support using other implementations of PSA
- * Crypto with TLS and X.509 (yet), we're still trying to simplify the life of
- * people who would like to try it before it's officially supported. */
-#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+ * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations
+ * separated. */
+#if defined(MBEDTLS_PSA_CRYPTO_C)
psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes);
-#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
+#endif /* MBEDTLS_PSA_CRYPTO_C */
key_usage = psa_get_key_usage_flags(&attributes);
psa_reset_key_attributes(&attributes);
@@ -345,11 +349,11 @@
if (alg == key_alg) {
return 1;
}
-#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+#if defined(MBEDTLS_PSA_CRYPTO_C)
if (alg == key_alg2) {
return 1;
}
-#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
+#endif /* MBEDTLS_PSA_CRYPTO_C */
/*
* If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash,
@@ -357,26 +361,25 @@
* then alg is compliant with this key alg
*/
if (PSA_ALG_IS_SIGN_HASH(alg)) {
-
if (PSA_ALG_IS_SIGN_HASH(key_alg) &&
PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH &&
(alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) {
return 1;
}
-#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+#if defined(MBEDTLS_PSA_CRYPTO_C)
if (PSA_ALG_IS_SIGN_HASH(key_alg2) &&
PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH &&
(alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) {
return 1;
}
-#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
+#endif /* MBEDTLS_PSA_CRYPTO_C */
}
return 0;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#if defined(MBEDTLS_RSA_C)
static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
int want_crypt)
@@ -573,7 +576,14 @@
}
psa_set_key_usage_flags(attributes, more_usage);
+ /* Key's enrollment is available only when an Mbed TLS implementation of PSA
+ * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined.
+ * Even though we don't officially support using other implementations of PSA
+ * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations
+ * separated. */
+#if defined(MBEDTLS_PSA_CRYPTO_C)
psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE);
+#endif
return 0;
}
@@ -675,10 +685,7 @@
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t from_family = pk->ec_family;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
- /* We're only reading the key, but mbedtls_ecp_write_key()
- * is missing a const annotation on its key parameter, so
- * we need the non-const accessor here. */
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
+ const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
size_t from_bits = 0;
psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
&from_bits);
@@ -704,12 +711,9 @@
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
- /* Make sure to pass the exact key length to
- * mbedtls_ecp_write_key(), because it writes Montgomery keys
- * at the start of the buffer but Weierstrass keys at the
- * end of the buffer. */
- size_t key_length = PSA_BITS_TO_BYTES(ec->grp.nbits);
- int ret = mbedtls_ecp_write_key(ec, key_buffer, key_length);
+ size_t key_length = 0;
+ int ret = mbedtls_ecp_write_key_ext(ec, &key_length,
+ key_buffer, sizeof(key_buffer));
if (ret < 0) {
return ret;
}
@@ -856,7 +860,136 @@
return import_pair_into_psa(pk, attributes, key_id);
}
}
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+static int copy_from_psa(mbedtls_svc_key_id_t key_id,
+ mbedtls_pk_context *pk,
+ int public_only)
+{
+ psa_status_t status;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t key_type;
+ psa_algorithm_t alg_type;
+ size_t key_bits;
+ /* Use a buffer size large enough to contain either a key pair or public key. */
+ unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE];
+ size_t exp_key_len;
+ int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+
+ if (pk == NULL) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ status = psa_get_key_attributes(key_id, &key_attr);
+ if (status != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ if (public_only) {
+ status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
+ } else {
+ status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
+ }
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_TO_MBEDTLS_ERR(status);
+ goto exit;
+ }
+
+ key_type = psa_get_key_type(&key_attr);
+ if (public_only) {
+ key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
+ }
+ key_bits = psa_get_key_bits(&key_attr);
+ alg_type = psa_get_key_algorithm(&key_attr);
+
+#if defined(MBEDTLS_RSA_C)
+ if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) ||
+ (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) {
+
+ ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
+ if (ret != 0) {
+ goto exit;
+ }
+
+ if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
+ } else {
+ ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
+ }
+ if (ret != 0) {
+ goto exit;
+ }
+
+ mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
+ if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) {
+ md_type = mbedtls_md_type_from_psa_alg(alg_type);
+ }
+
+ if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) {
+ ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type);
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) ||
+ alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) {
+ ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type);
+ }
+ if (ret != 0) {
+ goto exit;
+ }
+ } else
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
+ if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ||
+ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) {
+ mbedtls_ecp_group_id grp_id;
+
+ ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
+ if (ret != 0) {
+ goto exit;
+ }
+
+ grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits);
+ ret = mbedtls_pk_ecc_set_group(pk, grp_id);
+ if (ret != 0) {
+ goto exit;
+ }
+
+ if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
+ ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len);
+ if (ret != 0) {
+ goto exit;
+ }
+ ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE);
+ } else {
+ ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len);
+ }
+ if (ret != 0) {
+ goto exit;
+ }
+ } else
+#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
+ {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+exit:
+ psa_reset_key_attributes(&key_attr);
+ mbedtls_platform_zeroize(exp_key, sizeof(exp_key));
+
+ return ret;
+}
+
+int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
+ mbedtls_pk_context *pk)
+{
+ return copy_from_psa(key_id, pk, 0);
+}
+
+int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id,
+ mbedtls_pk_context *pk)
+{
+ return copy_from_psa(key_id, pk, 1);
+}
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
/*
* Helper for mbedtls_pk_sign and mbedtls_pk_verify
@@ -1023,7 +1156,7 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
p = buf + sizeof(buf);
- key_len = mbedtls_pk_write_pubkey(&p, buf, ctx);
+ key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p);
if (key_len < 0) {
return key_len;
@@ -1188,9 +1321,41 @@
}
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+ psa_algorithm_t psa_alg, sign_alg;
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+ psa_algorithm_t psa_enrollment_alg;
+#endif /* MBEDTLS_PSA_CRYPTO_C */
psa_status_t status;
- status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
+ status = psa_get_key_attributes(ctx->priv_id, &key_attr);
+ if (status != PSA_SUCCESS) {
+ return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
+ }
+ psa_alg = psa_get_key_algorithm(&key_attr);
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+ psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+ psa_reset_key_attributes(&key_attr);
+
+ /* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
+ * alg and enrollment alg should be of type RSA_PSS. */
+ if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
+ sign_alg = psa_alg;
+ }
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+ else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
+ sign_alg = psa_enrollment_alg;
+ }
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+ else {
+ /* The opaque key has no RSA PSS algorithm associated. */
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ /* Adjust the hashing algorithm. */
+ sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
+
+ status = psa_sign_hash(ctx->priv_id, sign_alg,
hash, hash_len,
sig, sig_size, sig_len);
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
@@ -1357,124 +1522,4 @@
return ctx->pk_info->type;
}
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/*
- * Load the key to a PSA key slot,
- * then turn the PK context into a wrapper for that key slot.
- *
- * Currently only works for EC & RSA private keys.
- */
-int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
- mbedtls_svc_key_id_t *key,
- psa_algorithm_t alg,
- psa_key_usage_t usage,
- psa_algorithm_t alg2)
-{
-#if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C)
- ((void) pk);
- ((void) key);
- ((void) alg);
- ((void) usage);
- ((void) alg2);
-#else /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
- size_t d_len;
- psa_ecc_family_t curve_id;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_type_t key_type;
- size_t bits;
- psa_status_t status;
-
- /* export the private key material in the format PSA wants */
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
- unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
- status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
- if (status != PSA_SUCCESS) {
- return psa_pk_status_to_mbedtls(status);
- }
-
- curve_id = pk->ec_family;
- bits = pk->ec_bits;
-#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
- unsigned char d[MBEDTLS_ECP_MAX_BYTES];
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
- d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
- if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
- return ret;
- }
-
- curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
- key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
-
- /* prepare the key attributes */
- psa_set_key_type(&attributes, key_type);
- psa_set_key_bits(&attributes, bits);
- psa_set_key_usage_flags(&attributes, usage);
- psa_set_key_algorithm(&attributes, alg);
- if (alg2 != PSA_ALG_NONE) {
- psa_set_key_enrollment_algorithm(&attributes, alg2);
- }
-
- /* import private key into PSA */
- status = psa_import_key(&attributes, d, d_len, key);
- mbedtls_platform_zeroize(d, sizeof(d));
- if (status != PSA_SUCCESS) {
- return PSA_PK_TO_MBEDTLS_ERR(status);
- }
-
- /* make PK context wrap the key slot */
- mbedtls_pk_free(pk);
- mbedtls_pk_init(pk);
-
- return mbedtls_pk_setup_opaque(pk, *key);
- } else
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-#if defined(MBEDTLS_RSA_C)
- if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
- unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- int key_len;
- psa_status_t status;
-
- /* export the private key material in the format PSA wants */
- key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf));
- if (key_len <= 0) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- }
-
- /* prepare the key attributes */
- psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
- psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk));
- psa_set_key_usage_flags(&attributes, usage);
- psa_set_key_algorithm(&attributes, alg);
- if (alg2 != PSA_ALG_NONE) {
- psa_set_key_enrollment_algorithm(&attributes, alg2);
- }
-
- /* import private key into PSA */
- status = psa_import_key(&attributes,
- buf + sizeof(buf) - key_len,
- key_len, key);
-
- mbedtls_platform_zeroize(buf, sizeof(buf));
-
- if (status != PSA_SUCCESS) {
- return PSA_PK_TO_MBEDTLS_ERR(status);
- }
-
- /* make PK context wrap the key slot */
- mbedtls_pk_free(pk);
- mbedtls_pk_init(pk);
-
- return mbedtls_pk_setup_opaque(pk, *key);
- } else
-#endif /* MBEDTLS_RSA_C */
-#endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
- return MBEDTLS_ERR_PK_TYPE_MISMATCH;
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PK_C */
diff --git a/library/pk_ecc.c b/library/pk_ecc.c
new file mode 100644
index 0000000..86218ff
--- /dev/null
+++ b/library/pk_ecc.c
@@ -0,0 +1,255 @@
+/*
+ * ECC setters for PK.
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#include "common.h"
+
+#include "mbedtls/pk.h"
+#include "mbedtls/error.h"
+#include "mbedtls/ecp.h"
+#include "pk_internal.h"
+
+#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_HAVE_ECC_KEYS)
+
+int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
+{
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ size_t ec_bits;
+ psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits);
+
+ /* group may already be initialized; if so, make sure IDs match */
+ if ((pk->ec_family != 0 && pk->ec_family != ec_family) ||
+ (pk->ec_bits != 0 && pk->ec_bits != ec_bits)) {
+ return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
+ }
+
+ /* set group */
+ pk->ec_family = ec_family;
+ pk->ec_bits = ec_bits;
+
+ return 0;
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
+
+ /* grp may already be initialized; if so, make sure IDs match */
+ if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
+ mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
+ return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
+ }
+
+ /* set group */
+ return mbedtls_ecp_group_load(&(ecp->grp), grp_id);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+}
+
+int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len)
+{
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_usage_t flags;
+ psa_status_t status;
+
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
+ if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) {
+ /* Do not set algorithm here because Montgomery keys cannot do ECDSA and
+ * the PK module cannot do ECDH. When the key will be used in TLS for
+ * ECDH, it will be exported and then re-imported with proper flags
+ * and algorithm. */
+ flags = PSA_KEY_USAGE_EXPORT;
+ } else {
+ psa_set_key_algorithm(&attributes,
+ MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH));
+ flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE |
+ PSA_KEY_USAGE_EXPORT;
+ }
+ psa_set_key_usage_flags(&attributes, flags);
+
+ status = psa_import_key(&attributes, key, key_len, &pk->priv_id);
+ return psa_pk_status_to_mbedtls(status);
+
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+ mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
+ int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len);
+ if (ret != 0) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
+ }
+ return 0;
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+}
+
+int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
+ const unsigned char *prv, size_t prv_len,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
+{
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+
+ (void) f_rng;
+ (void) p_rng;
+ (void) prv;
+ (void) prv_len;
+ psa_status_t status;
+
+ status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
+ &pk->pub_raw_len);
+ return psa_pk_status_to_mbedtls(status);
+
+#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */
+
+ (void) f_rng;
+ (void) p_rng;
+ psa_status_t status;
+
+ mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
+ size_t curve_bits;
+ psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
+
+ /* Import private key into PSA, from serialized input */
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+ psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
+ psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
+ status = psa_import_key(&key_attr, prv, prv_len, &key_id);
+ if (status != PSA_SUCCESS) {
+ return psa_pk_status_to_mbedtls(status);
+ }
+
+ /* Export public key from PSA */
+ unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
+ size_t pub_len;
+ status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len);
+ psa_status_t destruction_status = psa_destroy_key(key_id);
+ if (status != PSA_SUCCESS) {
+ return psa_pk_status_to_mbedtls(status);
+ } else if (destruction_status != PSA_SUCCESS) {
+ return psa_pk_status_to_mbedtls(destruction_status);
+ }
+
+ /* Load serialized public key into ecp_keypair structure */
+ return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len);
+
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
+ (void) prv;
+ (void) prv_len;
+
+ mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
+ return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng);
+
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+}
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/*
+ * Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case.
+ *
+ * Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA
+ * functions to handle keys. However, currently psa_import_key() does not
+ * support compressed points. In case that support was explicitly requested,
+ * this fallback uses ECP functions to get the job done. This is the reason
+ * why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT.
+ *
+ * [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group().
+ * out: will have the public key set.
+ * [in] pub, pub_len: the public key as an ECPoint,
+ * in any format supported by ECP.
+ *
+ * Return:
+ * - 0 on success;
+ * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
+ * but not supported;
+ * - another error code otherwise.
+ */
+static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk,
+ const unsigned char *pub,
+ size_t pub_len)
+{
+#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
+ (void) pk;
+ (void) pub;
+ (void) pub_len;
+ return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
+ mbedtls_ecp_keypair ecp_key;
+ mbedtls_ecp_group_id ecp_group_id;
+ int ret;
+
+ ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
+
+ mbedtls_ecp_keypair_init(&ecp_key);
+ ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
+ if (ret != 0) {
+ goto exit;
+ }
+ ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
+ pub, pub_len);
+ if (ret != 0) {
+ goto exit;
+ }
+ ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
+ MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &pk->pub_raw_len, pk->pub_raw,
+ sizeof(pk->pub_raw));
+
+exit:
+ mbedtls_ecp_keypair_free(&ecp_key);
+ return ret;
+#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len)
+{
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+
+ /* Load the key */
+ if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) {
+ /* Format directly supported by PSA:
+ * - non-Weierstrass curves that only have one format;
+ * - uncompressed format for Weierstrass curves. */
+ if (pub_len > sizeof(pk->pub_raw)) {
+ return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
+ }
+ memcpy(pk->pub_raw, pub, pub_len);
+ pk->pub_raw_len = pub_len;
+ } else {
+ /* Other format, try the fallback */
+ int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ /* Validate the key by trying to import it */
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
+
+ psa_set_key_usage_flags(&key_attrs, 0);
+ psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
+ psa_set_key_bits(&key_attrs, pk->ec_bits);
+
+ if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
+ &key_id) != PSA_SUCCESS) ||
+ (psa_destroy_key(key_id) != PSA_SUCCESS)) {
+ return MBEDTLS_ERR_PK_INVALID_PUBKEY;
+ }
+
+ return 0;
+
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+ int ret;
+ mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
+ ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len);
+ if (ret != 0) {
+ return ret;
+ }
+ return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
+
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+}
+
+#endif /* MBEDTLS_PK_C && MBEDTLS_PK_HAVE_ECC_KEYS */
diff --git a/library/pk_internal.h b/library/pk_internal.h
index f5924ad..e86a3a0 100644
--- a/library/pk_internal.h
+++ b/library/pk_internal.h
@@ -127,6 +127,62 @@
return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id);
}
+
+/*
+ * Set the group used by this key.
+ *
+ * [in/out] pk: in: must have been pk_setup() to an ECC type
+ * out: will have group (curve) information set
+ * [in] grp_in: a supported group ID (not NONE)
+ */
+int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id);
+
+/*
+ * Set the private key material
+ *
+ * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group().
+ * out: will have the private key set.
+ * [in] key, key_len: the raw private key (no ASN.1 wrapping).
+ */
+int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len);
+
+/*
+ * Set the public key.
+ *
+ * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group().
+ * out: will have the public key set.
+ * [in] pub, pub_len: the raw public key (an ECPoint).
+ *
+ * Return:
+ * - 0 on success;
+ * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
+ * but not supported;
+ * - another error code otherwise.
+ */
+int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len);
+
+/*
+ * Derive a public key from its private counterpart.
+ * Computationally intensive, only use when public key is not available.
+ *
+ * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key().
+ * out: will have the public key set.
+ * [in] prv, prv_len: the raw private key (see note below).
+ * [in] f_rng, p_rng: RNG function and context.
+ *
+ * Note: the private key information is always available from pk,
+ * however for convenience the serialized version is also passed,
+ * as it's available at each calling site, and useful in some configs
+ * (as otherwise we would have to re-serialize it from the pk context).
+ *
+ * There are three implementations of this function:
+ * 1. MBEDTLS_PK_USE_PSA_EC_DATA,
+ * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA,
+ * 3. not MBEDTLS_USE_PSA_CRYPTO.
+ */
+int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
+ const unsigned char *prv, size_t prv_len,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
/* Helper for (deterministic) ECDSA */
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 846175e..256863a 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -368,7 +368,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
- psa_algorithm_t psa_md_alg;
+ psa_algorithm_t psa_md_alg, psa_encrypt_alg;
psa_status_t status;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
@@ -389,10 +389,11 @@
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
- psa_set_key_algorithm(&attributes, PSA_ALG_RSA_OAEP(psa_md_alg));
+ psa_encrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
} else {
- psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
+ psa_encrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
}
+ psa_set_key_algorithm(&attributes, psa_encrypt_alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
status = psa_import_key(&attributes,
@@ -403,7 +404,7 @@
goto cleanup;
}
- status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
+ status = psa_asymmetric_encrypt(key_id, psa_encrypt_alg,
input, ilen,
NULL, 0,
output, osize, olen);
diff --git a/library/pkparse.c b/library/pkparse.c
index 5a3d3b2..4f6ee13 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -46,302 +46,6 @@
/***********************************************************************
*
- * ECC setters
- *
- * 1. This is an abstraction layer around MBEDTLS_PK_USE_PSA_EC_DATA:
- * this macro will not appear outside this section.
- * 2. All inputs are raw: no metadata, no ASN.1 until the next section.
- *
- **********************************************************************/
-
-/*
- * Set the group used by this key.
- *
- * [in/out] pk: in: must have been pk_setup() to an ECC type
- * out: will have group (curve) information set
- * [in] grp_in: a supported group ID (not NONE)
- */
-static int pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
-{
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
- size_t ec_bits;
- psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits);
-
- /* group may already be initialized; if so, make sure IDs match */
- if ((pk->ec_family != 0 && pk->ec_family != ec_family) ||
- (pk->ec_bits != 0 && pk->ec_bits != ec_bits)) {
- return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
- }
-
- /* set group */
- pk->ec_family = ec_family;
- pk->ec_bits = ec_bits;
-
- return 0;
-#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
- mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
-
- /* grp may already be initialized; if so, make sure IDs match */
- if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
- mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
- return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
- }
-
- /* set group */
- return mbedtls_ecp_group_load(&(ecp->grp), grp_id);
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
-}
-
-/*
- * Set the private key material
- *
- * [in/out] pk: in: must have the group set already, see pk_ecc_set_group().
- * out: will have the private key set.
- * [in] key, key_len: the raw private key (no ASN.1 wrapping).
- */
-static int pk_ecc_set_key(mbedtls_pk_context *pk,
- unsigned char *key, size_t key_len)
-{
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_usage_t flags;
- psa_status_t status;
-
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
- if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) {
- /* Do not set algorithm here because Montgomery keys cannot do ECDSA and
- * the PK module cannot do ECDH. When the key will be used in TLS for
- * ECDH, it will be exported and then re-imported with proper flags
- * and algorithm. */
- flags = PSA_KEY_USAGE_EXPORT;
- } else {
- psa_set_key_algorithm(&attributes,
- MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH));
- flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE |
- PSA_KEY_USAGE_EXPORT;
- }
- psa_set_key_usage_flags(&attributes, flags);
-
- status = psa_import_key(&attributes, key, key_len, &pk->priv_id);
- return psa_pk_status_to_mbedtls(status);
-
-#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
-
- mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
- int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len);
- if (ret != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
- }
- return 0;
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
-}
-
-/*
- * Derive a public key from its private counterpart.
- * Computationally intensive, only use when public key is not available.
- *
- * [in/out] pk: in: must have the private key set, see pk_ecc_set_key().
- * out: will have the public key set.
- * [in] prv, prv_len: the raw private key (see note below).
- * [in] f_rng, p_rng: RNG function and context.
- *
- * Note: the private key information is always available from pk,
- * however for convenience the serialized version is also passed,
- * as it's available at each calling site, and useful in some configs
- * (as otherwise we would have to re-serialize it from the pk context).
- *
- * There are three implementations of this function:
- * 1. MBEDTLS_PK_USE_PSA_EC_DATA,
- * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA,
- * 3. not MBEDTLS_USE_PSA_CRYPTO.
- */
-static int pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
- const unsigned char *prv, size_t prv_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
-{
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
-
- (void) f_rng;
- (void) p_rng;
- (void) prv;
- (void) prv_len;
- psa_status_t status;
-
- status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
- &pk->pub_raw_len);
- return psa_pk_status_to_mbedtls(status);
-
-#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */
-
- (void) f_rng;
- (void) p_rng;
- psa_status_t status;
-
- mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
- size_t curve_bits;
- psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
-
- /* Import private key into PSA, from serialized input */
- mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
- psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
- psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
- psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
- status = psa_import_key(&key_attr, prv, prv_len, &key_id);
- if (status != PSA_SUCCESS) {
- return psa_pk_status_to_mbedtls(status);
- }
-
- /* Export public key from PSA */
- unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
- size_t pub_len;
- status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len);
- psa_status_t destruction_status = psa_destroy_key(key_id);
- if (status != PSA_SUCCESS) {
- return psa_pk_status_to_mbedtls(status);
- } else if (destruction_status != PSA_SUCCESS) {
- return psa_pk_status_to_mbedtls(destruction_status);
- }
-
- /* Load serialized public key into ecp_keypair structure */
- return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len);
-
-#else /* MBEDTLS_USE_PSA_CRYPTO */
-
- (void) prv;
- (void) prv_len;
-
- mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
- return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng);
-
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-}
-
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
-/*
- * Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case.
- *
- * Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA
- * functions to handle keys. However, currently psa_import_key() does not
- * support compressed points. In case that support was explicitly requested,
- * this fallback uses ECP functions to get the job done. This is the reason
- * why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT.
- *
- * [in/out] pk: in: must have the group set, see pk_ecc_set_group().
- * out: will have the public key set.
- * [in] pub, pub_len: the public key as an ECPoint,
- * in any format supported by ECP.
- *
- * Return:
- * - 0 on success;
- * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
- * but not supported;
- * - another error code otherwise.
- */
-static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk,
- const unsigned char *pub,
- size_t pub_len)
-{
-#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
- (void) pk;
- (void) pub;
- (void) pub_len;
- return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
-#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
- mbedtls_ecp_keypair ecp_key;
- mbedtls_ecp_group_id ecp_group_id;
- int ret;
-
- ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
-
- mbedtls_ecp_keypair_init(&ecp_key);
- ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
- if (ret != 0) {
- goto exit;
- }
- ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
- pub, pub_len);
- if (ret != 0) {
- goto exit;
- }
- ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
- MBEDTLS_ECP_PF_UNCOMPRESSED,
- &pk->pub_raw_len, pk->pub_raw,
- sizeof(pk->pub_raw));
-
-exit:
- mbedtls_ecp_keypair_free(&ecp_key);
- return ret;
-#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
-}
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
-
-/*
- * Set the public key.
- *
- * [in/out] pk: in: must have its group set, see pk_ecc_set_group().
- * out: will have the public key set.
- * [in] pub, pub_len: the raw public key (an ECPoint).
- *
- * Return:
- * - 0 on success;
- * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
- * but not supported;
- * - another error code otherwise.
- */
-static int pk_ecc_set_pubkey(mbedtls_pk_context *pk,
- const unsigned char *pub, size_t pub_len)
-{
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
-
- /* Load the key */
- if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) {
- /* Format directly supported by PSA:
- * - non-Weierstrass curves that only have one format;
- * - uncompressed format for Weierstrass curves. */
- if (pub_len > sizeof(pk->pub_raw)) {
- return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
- }
- memcpy(pk->pub_raw, pub, pub_len);
- pk->pub_raw_len = pub_len;
- } else {
- /* Other format, try the fallback */
- int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len);
- if (ret != 0) {
- return ret;
- }
- }
-
- /* Validate the key by trying to import it */
- mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
- psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
-
- psa_set_key_usage_flags(&key_attrs, 0);
- psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
- psa_set_key_bits(&key_attrs, pk->ec_bits);
-
- if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
- &key_id) != PSA_SUCCESS) ||
- (psa_destroy_key(key_id) != PSA_SUCCESS)) {
- return MBEDTLS_ERR_PK_INVALID_PUBKEY;
- }
-
- return 0;
-
-#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
-
- int ret;
- mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
- ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len);
- if (ret != 0) {
- return ret;
- }
- return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
-
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
-}
-
-/***********************************************************************
- *
* Low-level ECC parsing: optional support for SpecifiedECDomain
*
* There are two functions here that are used by the rest of the code:
@@ -698,7 +402,7 @@
}
}
- return pk_ecc_set_group(pk, grp_id);
+ return mbedtls_pk_ecc_set_group(pk, grp_id);
}
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
@@ -714,7 +418,7 @@
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
- return pk_ecc_set_group(pk, grp_id);
+ return mbedtls_pk_ecc_set_group(pk, grp_id);
}
/*
@@ -740,7 +444,7 @@
/*
* Load the private key
*/
- ret = pk_ecc_set_key(pk, key, len);
+ ret = mbedtls_pk_ecc_set_key(pk, key, len);
if (ret != 0) {
return ret;
}
@@ -748,7 +452,7 @@
/* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
* which never contain a public key. As such, derive the public key
* unconditionally. */
- if ((ret = pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) {
+ if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) {
return ret;
}
@@ -874,7 +578,7 @@
ret = pk_use_ecparams(&alg_params, pk);
}
if (ret == 0) {
- ret = pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p));
+ ret = mbedtls_pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p));
*p += end - *p;
}
} else
@@ -966,7 +670,7 @@
/*
* Load the private key
*/
- ret = pk_ecc_set_key(pk, d, d_len);
+ ret = mbedtls_pk_ecc_set_key(pk, d, d_len);
if (ret != 0) {
return ret;
}
@@ -990,11 +694,11 @@
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
- if ((ret = pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) {
+ if ((ret = mbedtls_pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) {
pubkey_done = 1;
} else {
/*
- * The only acceptable failure mode of pk_ecc_set_pubkey() above
+ * The only acceptable failure mode of mbedtls_pk_ecc_set_pubkey() above
* is if the point format is not recognized.
*/
if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) {
@@ -1007,7 +711,7 @@
}
if (!pubkey_done) {
- if ((ret = pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) {
+ if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) {
return ret;
}
}
diff --git a/library/pkwrite.c b/library/pkwrite.c
index b9ddcf1..5e009c5 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -202,7 +202,7 @@
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
byte_length = (ec->grp.pbits + 7) / 8;
- ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
+ ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp));
if (ret != 0) {
goto exit;
}
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index ca01e76..a0a002a 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -71,6 +71,7 @@
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/psa_util.h"
+#include "mbedtls/threading.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \
@@ -92,35 +93,93 @@
#define RNG_INITIALIZED 1
#define RNG_SEEDED 2
+/* IDs for PSA crypto subsystems. Starts at 1 to catch potential uninitialized
+ * variables as arguments. */
+typedef enum {
+ PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 1,
+ PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS,
+ PSA_CRYPTO_SUBSYSTEM_RNG,
+ PSA_CRYPTO_SUBSYSTEM_TRANSACTION,
+} mbedtls_psa_crypto_subsystem;
+
+/* Initialization flags for global_data::initialized */
+#define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED 0x01
+#define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED 0x02
+#define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED 0x04
+
+#define PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED ( \
+ PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED | \
+ PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED | \
+ PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)
+
typedef struct {
uint8_t initialized;
uint8_t rng_state;
- uint8_t drivers_initialized;
mbedtls_psa_random_context_t rng;
} psa_global_data_t;
static psa_global_data_t global_data;
-#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
-mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
- &global_data.rng.drbg;
-#endif
+static uint8_t psa_get_initialized(void)
+{
+ uint8_t initialized;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ initialized = global_data.rng_state == RNG_SEEDED;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ initialized =
+ (initialized && (global_data.initialized == PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED));
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ return initialized;
+}
+
+static uint8_t psa_get_drivers_initialized(void)
+{
+ uint8_t initialized;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ initialized = (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) != 0;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ return initialized;
+}
#define GUARD_MODULE_INITIALIZED \
- if (global_data.initialized == 0) \
+ if (psa_get_initialized() == 0) \
return PSA_ERROR_BAD_STATE;
int psa_can_do_hash(psa_algorithm_t hash_alg)
{
(void) hash_alg;
- return global_data.drivers_initialized;
+ return psa_get_drivers_initialized();
}
int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg)
{
(void) key_type;
(void) cipher_alg;
- return global_data.drivers_initialized;
+ return psa_get_drivers_initialized();
}
@@ -568,7 +627,7 @@
size_t *key_buffer_length, size_t *bits)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
/* zero-length keys are never supported. */
if (data_length == 0) {
@@ -578,7 +637,7 @@
if (key_type_is_raw_bytes(type)) {
*bits = PSA_BYTES_TO_BITS(data_length);
- status = psa_validate_unstructured_key_bit_size(attributes->core.type,
+ status = psa_validate_unstructured_key_bit_size(attributes->type,
*bits);
if (status != PSA_SUCCESS) {
return status;
@@ -1106,6 +1165,17 @@
* fully destroyed. */
PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(
&mbedtls_threading_key_slot_mutex));
+
+ if (slot->state == PSA_SLOT_PENDING_DELETION) {
+ /* Another thread has destroyed the key between us locking the slot
+ * and us gaining the mutex. Unregister from the slot,
+ * and report that the key does not exist. */
+ status = psa_unregister_read(slot);
+
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+ return (status == PSA_SUCCESS) ? PSA_ERROR_INVALID_HANDLE : status;
+ }
#endif
/* Set the key slot containing the key description's state to
* PENDING_DELETION. This stops new operations from registering
@@ -1115,10 +1185,10 @@
* 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. */
- status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
- PSA_SLOT_PENDING_DELETION);
+ overall_status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
+ PSA_SLOT_PENDING_DELETION);
- if (status != PSA_SUCCESS) {
+ if (overall_status != PSA_SUCCESS) {
goto exit;
}
@@ -1226,9 +1296,7 @@
return status;
}
- attributes->core = slot->attr;
- attributes->core.flags &= (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
- MBEDTLS_PSA_KA_MASK_DUAL_USE);
+ *attributes = slot->attr;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) {
@@ -1245,7 +1313,7 @@
const psa_key_attributes_t *attributes,
psa_key_slot_number_t *slot_number)
{
- if (attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) {
+ if (attributes->has_slot_number) {
*slot_number = attributes->slot_number;
return PSA_SUCCESS;
} else {
@@ -1275,7 +1343,7 @@
const uint8_t *key_buffer, size_t key_buffer_size,
uint8_t *data, size_t data_size, size_t *data_length)
{
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
if (key_type_is_raw_bytes(type) ||
PSA_KEY_TYPE_IS_RSA(type) ||
@@ -1324,10 +1392,7 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
- status = psa_driver_wrapper_export_key(&attributes,
+ status = psa_driver_wrapper_export_key(&slot->attr,
slot->key.data, slot->key.bytes,
data, data_size, data_length);
@@ -1344,7 +1409,7 @@
size_t data_size,
size_t *data_length)
{
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
(PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) ||
@@ -1411,7 +1476,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
/* Reject a zero-length output buffer now, since this can never be a
* valid key representation. This way we know that data must be a valid
@@ -1437,11 +1501,8 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
status = psa_driver_wrapper_export_public_key(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
data, data_size, data_length);
exit:
@@ -1450,16 +1511,6 @@
return (status == PSA_SUCCESS) ? unlock_status : status;
}
-MBEDTLS_STATIC_ASSERT(
- (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
- "One or more key attribute flag is listed as both external-only and dual-use")
-MBEDTLS_STATIC_ASSERT(
- (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
- "One or more key attribute flag is listed as both internal-only and dual-use")
-MBEDTLS_STATIC_ASSERT(
- (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0,
- "One or more key attribute flag is listed as both internal-only and external-only")
-
/** Validate that a key policy is internally well-formed.
*
* This function only rejects invalid policies. It does not validate the
@@ -1525,7 +1576,7 @@
}
}
- status = psa_validate_key_policy(&attributes->core.policy);
+ status = psa_validate_key_policy(&attributes->policy);
if (status != PSA_SUCCESS) {
return status;
}
@@ -1538,12 +1589,6 @@
return PSA_ERROR_NOT_SUPPORTED;
}
- /* Reject invalid flags. These should not be reachable through the API. */
- if (attributes->core.flags & ~(MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
- MBEDTLS_PSA_KA_MASK_DUAL_USE)) {
- return PSA_ERROR_INVALID_ARGUMENT;
- }
-
return PSA_SUCCESS;
}
@@ -1617,7 +1662,7 @@
* volatile key identifier associated to the slot returned to contain its
* definition. */
- slot->attr = attributes->core;
+ slot->attr = *attributes;
if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
slot->attr.id = volatile_key_id;
@@ -1626,13 +1671,6 @@
#endif
}
- /* 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_reserve_free_key_slot()
- * may have set. */
- slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
-
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* For a key in a secure element, we need to do three things
* when creating or registering a persistent key:
@@ -1659,7 +1697,7 @@
return status;
}
- if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->core.lifetime)) {
+ if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime)) {
psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY);
psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
psa_crypto_transaction.key.slot = slot_number;
@@ -1859,14 +1897,14 @@
const psa_key_slot_t *slot,
const psa_key_attributes_t *attributes)
{
- if (attributes->core.type != 0) {
- if (attributes->core.type != slot->attr.type) {
+ if (attributes->type != 0) {
+ if (attributes->type != slot->attr.type) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
- if (attributes->core.bits != 0) {
- if (attributes->core.bits != slot->attr.bits) {
+ if (attributes->bits != 0) {
+ if (attributes->bits != slot->attr.bits) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
@@ -1910,7 +1948,7 @@
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the imported key material. */
if (slot->key.data == NULL) {
- if (psa_key_lifetime_is_external(attributes->core.lifetime)) {
+ if (psa_key_lifetime_is_external(attributes->lifetime)) {
status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
attributes, data, data_length, &storage_size);
if (status != PSA_SUCCESS) {
@@ -2030,12 +2068,12 @@
* equal to the ones of the source key. So it is safe to inherit
* them from the source key now."
* */
- actual_attributes.core.bits = source_slot->attr.bits;
- actual_attributes.core.type = source_slot->attr.type;
+ actual_attributes.bits = source_slot->attr.bits;
+ actual_attributes.type = source_slot->attr.type;
status = psa_restrict_key_policy(source_slot->attr.type,
- &actual_attributes.core.policy,
+ &actual_attributes.policy,
&source_slot->attr.policy);
if (status != PSA_SUCCESS) {
goto exit;
@@ -2064,7 +2102,7 @@
* - For opaque keys this translates to an invocation of the drivers'
* copy_key entry point through the dispatch layer.
* */
- if (psa_key_lifetime_is_external(actual_attributes.core.lifetime)) {
+ if (psa_key_lifetime_is_external(actual_attributes.lifetime)) {
status = psa_driver_wrapper_get_key_buffer_size(&actual_attributes,
&storage_size);
if (status != PSA_SUCCESS) {
@@ -2372,7 +2410,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
- psa_key_attributes_t attributes;
/* A context must be freshly initialized before it can be set up. */
if (operation->id != 0) {
@@ -2389,11 +2426,7 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
- status = psa_mac_finalize_alg_and_key_validation(alg, &attributes,
+ status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr,
&operation->mac_size);
if (status != PSA_SUCCESS) {
goto exit;
@@ -2403,13 +2436,13 @@
/* Dispatch the MAC setup call with validated input */
if (is_sign) {
status = psa_driver_wrapper_mac_sign_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
} else {
status = psa_driver_wrapper_mac_verify_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
@@ -2559,7 +2592,6 @@
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
uint8_t operation_mac_size = 0;
- psa_key_attributes_t attributes;
status = psa_get_and_lock_key_slot_with_policy(
key,
@@ -2570,11 +2602,7 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
- status = psa_mac_finalize_alg_and_key_validation(alg, &attributes,
+ status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr,
&operation_mac_size);
if (status != PSA_SUCCESS) {
goto exit;
@@ -2586,7 +2614,7 @@
}
status = psa_driver_wrapper_mac_compute(
- &attributes,
+ &slot->attr,
slot->key.data, slot->key.bytes,
alg,
input, input_length,
@@ -2696,7 +2724,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
*signature_length = 0;
@@ -2728,19 +2755,15 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
if (input_is_message) {
status = psa_driver_wrapper_sign_message(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_size, signature_length);
} else {
status = psa_driver_wrapper_sign_hash(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_size, signature_length);
}
@@ -2782,18 +2805,14 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
if (input_is_message) {
status = psa_driver_wrapper_verify_message(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_length);
} else {
status = psa_driver_wrapper_verify_hash(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_length);
}
@@ -2904,7 +2923,7 @@
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size, size_t *signature_length)
{
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
@@ -2919,7 +2938,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
@@ -2965,7 +2984,7 @@
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length)
{
- if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
@@ -2980,7 +2999,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
@@ -3031,7 +3050,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
(void) input;
(void) input_length;
@@ -3056,12 +3074,8 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
status = psa_driver_wrapper_asymmetric_encrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
exit:
@@ -3083,7 +3097,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
(void) input;
(void) input_length;
@@ -3107,12 +3120,8 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
status = psa_driver_wrapper_asymmetric_decrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
@@ -3181,7 +3190,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
/* Check that start has not been previously called, or operation has not
* previously errored. */
@@ -3208,14 +3216,10 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
/* Ensure ops count gets reset, in case of operation re-use. */
operation->num_ops = 0;
- status = psa_driver_wrapper_sign_hash_start(operation, &attributes,
+ status = psa_driver_wrapper_sign_hash_start(operation, &slot->attr,
slot->key.data,
slot->key.bytes, alg,
hash, hash_length);
@@ -3353,14 +3357,10 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
/* Ensure ops count gets reset, in case of operation re-use. */
operation->num_ops = 0;
- status = psa_driver_wrapper_verify_hash_start(operation, &attributes,
+ status = psa_driver_wrapper_verify_hash_start(operation, &slot->attr,
slot->key.data,
slot->key.bytes,
alg, hash, hash_length,
@@ -3495,7 +3495,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t required_hash_length;
- if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -3512,8 +3512,8 @@
/* Ensure num_ops is zero'ed in case of context re-use. */
operation->num_ops = 0;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&operation->ctx);
@@ -3711,7 +3711,7 @@
size_t coordinate_bytes = 0;
size_t required_hash_length = 0;
- if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -3730,8 +3730,8 @@
/* Ensure num_ops is zero'ed in case of context re-use. */
operation->num_ops = 0;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&operation->ctx);
@@ -3889,7 +3889,6 @@
psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ?
PSA_KEY_USAGE_ENCRYPT :
PSA_KEY_USAGE_DECRYPT);
- psa_key_attributes_t attributes;
/* A context must be freshly initialized before it can be set up. */
if (operation->id != 0) {
@@ -3919,20 +3918,16 @@
}
operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
/* Try doing the operation through a driver before using software fallback. */
if (cipher_operation == MBEDTLS_ENCRYPT) {
status = psa_driver_wrapper_cipher_encrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
} else {
status = psa_driver_wrapper_cipher_decrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
@@ -4145,7 +4140,6 @@
psa_key_slot_t *slot = NULL;
uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE];
size_t default_iv_length = 0;
- psa_key_attributes_t attributes;
if (!PSA_ALG_IS_CIPHER(alg)) {
status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4159,10 +4153,6 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) {
status = PSA_ERROR_GENERIC_ERROR;
@@ -4182,7 +4172,7 @@
}
status = psa_driver_wrapper_cipher_encrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, local_iv, default_iv_length, input, input_length,
psa_crypto_buffer_offset(output, default_iv_length),
output_size - default_iv_length, output_length);
@@ -4216,7 +4206,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
- psa_key_attributes_t attributes;
if (!PSA_ALG_IS_CIPHER(alg)) {
status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4230,10 +4219,6 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
if (alg == PSA_ALG_CCM_STAR_NO_TAG &&
input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH(slot->attr.type)) {
status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4244,7 +4229,7 @@
}
status = psa_driver_wrapper_cipher_decrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
output, output_size, output_length);
@@ -4353,17 +4338,13 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
status = psa_aead_check_nonce_length(alg, nonce_length);
if (status != PSA_SUCCESS) {
goto exit;
}
status = psa_driver_wrapper_aead_encrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg,
nonce, nonce_length,
additional_data, additional_data_length,
@@ -4408,17 +4389,13 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
status = psa_aead_check_nonce_length(alg, nonce_length);
if (status != PSA_SUCCESS) {
goto exit;
}
status = psa_driver_wrapper_aead_decrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg,
nonce, nonce_length,
additional_data, additional_data_length,
@@ -4484,7 +4461,6 @@
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
psa_key_usage_t key_usage = 0;
- psa_key_attributes_t attributes;
status = psa_aead_check_algorithm(alg);
if (status != PSA_SUCCESS) {
@@ -4514,23 +4490,19 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) {
goto exit;
}
if (is_encrypt) {
status = psa_driver_wrapper_aead_encrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
} else {
status = psa_driver_wrapper_aead_decrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
@@ -4539,7 +4511,7 @@
goto exit;
}
- operation->key_type = psa_get_key_type(&attributes);
+ operation->key_type = psa_get_key_type(&slot->attr);
exit:
unlock_status = psa_unregister_read_under_mutex(slot);
@@ -5842,7 +5814,6 @@
size_t bytes = PSA_BITS_TO_BYTES(bits);
size_t storage_size = bytes;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_key_attributes_t attributes;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) {
return PSA_ERROR_INVALID_ARGUMENT;
@@ -5891,12 +5862,9 @@
}
slot->attr.bits = (psa_key_bits_t) bits;
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
- if (psa_key_lifetime_is_external(attributes.core.lifetime)) {
- status = psa_driver_wrapper_get_key_buffer_size(&attributes,
+ if (psa_key_lifetime_is_external(slot->attr.lifetime)) {
+ status = psa_driver_wrapper_get_key_buffer_size(&slot->attr,
&storage_size);
if (status != PSA_SUCCESS) {
goto exit;
@@ -5907,7 +5875,7 @@
goto exit;
}
- status = psa_driver_wrapper_import_key(&attributes,
+ status = psa_driver_wrapper_import_key(&slot->attr,
data, bytes,
slot->key.data,
slot->key.bytes,
@@ -5978,7 +5946,7 @@
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
if (status == PSA_SUCCESS) {
status = psa_generate_derived_key_internal(slot,
- attributes->core.bits,
+ attributes->bits,
operation);
}
if (status == PSA_SUCCESS) {
@@ -7023,11 +6991,7 @@
return PSA_ERROR_NOT_SUPPORTED;
}
- psa_key_attributes_t attributes = {
- .core = private_key->attr
- };
-
- return psa_driver_wrapper_key_agreement(&attributes,
+ return psa_driver_wrapper_key_agreement(&private_key->attr,
private_key->key.data,
private_key->key.bytes, alg,
peer_key, peer_key_length,
@@ -7046,7 +7010,7 @@
size_t peer_key_length)
{
psa_status_t status;
- uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
+ uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE] = { 0 };
size_t shared_secret_length = 0;
psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg);
@@ -7182,6 +7146,9 @@
#endif
/** Initialize the PSA random generator.
+ *
+ * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling
+ * this function if mutexes are enabled.
*/
static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng)
{
@@ -7209,18 +7176,21 @@
MBEDTLS_ENTROPY_SOURCE_STRONG);
#endif
- mbedtls_psa_drbg_init(MBEDTLS_PSA_RANDOM_STATE);
+ mbedtls_psa_drbg_init(&rng->drbg);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
/** Deinitialize the PSA random generator.
+ *
+ * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling
+ * this function if mutexes are enabled.
*/
static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng)
{
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
memset(rng, 0, sizeof(*rng));
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
- mbedtls_psa_drbg_free(MBEDTLS_PSA_RANDOM_STATE);
+ mbedtls_psa_drbg_free(&rng->drbg);
rng->entropy_free(&rng->entropy);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
@@ -7235,7 +7205,7 @@
return PSA_SUCCESS;
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
const unsigned char drbg_seed[] = "PSA";
- int ret = mbedtls_psa_drbg_seed(&rng->entropy,
+ int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy,
drbg_seed, sizeof(drbg_seed) - 1);
return mbedtls_to_psa_error(ret);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
@@ -7265,12 +7235,16 @@
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
while (output_size > 0) {
+ int ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
size_t request_size =
(output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
MBEDTLS_PSA_RANDOM_MAX_REQUEST :
output_size);
- int ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
- output, request_size);
+#if defined(MBEDTLS_CTR_DRBG_C)
+ ret = mbedtls_ctr_drbg_random(&global_data.rng.drbg, output, request_size);
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ ret = mbedtls_hmac_drbg_random(&global_data.rng.drbg, output, request_size);
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
if (ret != 0) {
return mbedtls_to_psa_error(ret);
}
@@ -7281,44 +7255,11 @@
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
-/* Wrapper function allowing the classic API to use the PSA RNG.
- *
- * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
- * `psa_generate_random(...)`. The state parameter is ignored since the
- * PSA API doesn't support passing an explicit state.
- *
- * In the non-external case, psa_generate_random() calls an
- * `mbedtls_xxx_drbg_random` function which has exactly the same signature
- * and semantics as mbedtls_psa_get_random(). As an optimization,
- * instead of doing this back-and-forth between the PSA API and the
- * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
- * as a constant function pointer to `mbedtls_xxx_drbg_random`.
- */
-#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
-int mbedtls_psa_get_random(void *p_rng,
- unsigned char *output,
- size_t output_size)
-{
- /* This function takes a pointer to the RNG state because that's what
- * classic mbedtls functions using an RNG expect. The PSA RNG manages
- * its own state internally and doesn't let the caller access that state.
- * So we just ignore the state parameter, and in practice we'll pass
- * NULL. */
- (void) p_rng;
- psa_status_t status = psa_generate_random(output, output_size);
- if (status == PSA_SUCCESS) {
- return 0;
- } else {
- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
- }
-}
-#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
-
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
size_t seed_size)
{
- if (global_data.initialized) {
+ if (psa_get_initialized()) {
return PSA_ERROR_NOT_PERMITTED;
}
@@ -7400,7 +7341,7 @@
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
/* Only used for RSA */
(void) params;
@@ -7473,12 +7414,12 @@
}
/* Reject any attempt to create a public key. */
- if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->type)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
if (params->flags != 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -7499,17 +7440,17 @@
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the generated key material. */
if (slot->key.data == NULL) {
- if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime) ==
+ if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) ==
PSA_KEY_LOCATION_LOCAL_STORAGE) {
status = psa_validate_key_type_and_size_for_key_generation(
- attributes->core.type, attributes->core.bits);
+ attributes->type, attributes->bits);
if (status != PSA_SUCCESS) {
goto exit;
}
key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
- attributes->core.type,
- attributes->core.bits);
+ attributes->type,
+ attributes->bits);
} else {
status = psa_driver_wrapper_get_key_buffer_size(
attributes, &key_buffer_size);
@@ -7560,28 +7501,77 @@
void (* entropy_init)(mbedtls_entropy_context *ctx),
void (* entropy_free)(mbedtls_entropy_context *ctx))
{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
if (global_data.rng_state != RNG_NOT_INITIALIZED) {
- return PSA_ERROR_BAD_STATE;
+ status = PSA_ERROR_BAD_STATE;
+ } else {
+ global_data.rng.entropy_init = entropy_init;
+ global_data.rng.entropy_free = entropy_free;
+ status = PSA_SUCCESS;
}
- global_data.rng.entropy_init = entropy_init;
- global_data.rng.entropy_free = entropy_free;
- return PSA_SUCCESS;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ return status;
}
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
void mbedtls_psa_crypto_free(void)
{
- psa_wipe_all_key_slots();
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ /* Nothing to do to free transaction. */
+ if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) {
+ global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
+ }
+
+ if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED) {
+ psa_wipe_all_key_slots();
+ global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED;
+ }
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
if (global_data.rng_state != RNG_NOT_INITIALIZED) {
mbedtls_psa_random_free(&global_data.rng);
}
- /* Wipe all remaining data, including configuration.
- * In particular, this sets all state indicator to the value
- * indicating "uninitialized". */
- mbedtls_platform_zeroize(&global_data, sizeof(global_data));
+ global_data.rng_state = RNG_NOT_INITIALIZED;
+ mbedtls_platform_zeroize(&global_data.rng, sizeof(global_data.rng));
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
/* Terminate drivers */
- psa_driver_wrapper_free();
+ if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) {
+ psa_driver_wrapper_free();
+ global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED;
+ }
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
}
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
@@ -7609,57 +7599,171 @@
}
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
+static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsystem subsystem)
+{
+ psa_status_t status = PSA_SUCCESS;
+ uint8_t driver_wrappers_initialized = 0;
+
+ switch (subsystem) {
+ case PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS:
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED)) {
+ /* Init drivers */
+ status = psa_driver_wrapper_init();
+
+ /* Drivers need shutdown regardless of startup errors. */
+ global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED;
+
+
+ }
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
+ &mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ break;
+
+ case PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS:
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED)) {
+ status = psa_initialize_key_slots();
+
+ /* Need to wipe keys even if initialization fails. */
+ global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED;
+
+ }
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
+ &mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ break;
+
+ case PSA_CRYPTO_SUBSYSTEM_RNG:
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ driver_wrappers_initialized =
+ (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED);
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
+ &mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ /* Need to use separate mutex here, as initialisation can require
+ * testing of init flags, which requires locking the global data
+ * mutex. */
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ /* Initialize and seed the random generator. */
+ if (global_data.rng_state == RNG_NOT_INITIALIZED && driver_wrappers_initialized) {
+ mbedtls_psa_random_init(&global_data.rng);
+ global_data.rng_state = RNG_INITIALIZED;
+
+ status = mbedtls_psa_random_seed(&global_data.rng);
+ if (status == PSA_SUCCESS) {
+ global_data.rng_state = RNG_SEEDED;
+ }
+ }
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
+ &mbedtls_threading_psa_rngdata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ break;
+
+ case PSA_CRYPTO_SUBSYSTEM_TRANSACTION:
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)) {
+#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
+ status = psa_crypto_load_transaction();
+ if (status == PSA_SUCCESS) {
+ status = psa_crypto_recover_transaction(&psa_crypto_transaction);
+ if (status == PSA_SUCCESS) {
+ global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
+ }
+ status = psa_crypto_stop_transaction();
+ } else if (status == PSA_ERROR_DOES_NOT_EXIST) {
+ /* There's no transaction to complete. It's all good. */
+ global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
+ status = PSA_SUCCESS;
+ }
+#else /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */
+ global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED;
+ status = PSA_SUCCESS;
+#endif /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */
+ }
+
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock(
+ &mbedtls_threading_psa_globaldata_mutex));
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ break;
+
+ default:
+ status = PSA_ERROR_CORRUPTION_DETECTED;
+ }
+
+ /* Exit label only required when using threading macros. */
+#if defined(MBEDTLS_THREADING_C)
+exit:
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ return status;
+}
+
psa_status_t psa_crypto_init(void)
{
psa_status_t status;
- /* Double initialization is explicitly allowed. */
- if (global_data.initialized != 0) {
+ /* Double initialization is explicitly allowed. Early out if everything is
+ * done. */
+ if (psa_get_initialized()) {
return PSA_SUCCESS;
}
- /* Init drivers */
- status = psa_driver_wrapper_init();
- if (status != PSA_SUCCESS) {
- goto exit;
- }
- global_data.drivers_initialized = 1;
-
- status = psa_initialize_key_slots();
+ status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS);
if (status != PSA_SUCCESS) {
goto exit;
}
- /* Initialize and seed the random generator. */
- mbedtls_psa_random_init(&global_data.rng);
- global_data.rng_state = RNG_INITIALIZED;
- status = mbedtls_psa_random_seed(&global_data.rng);
+ status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS);
if (status != PSA_SUCCESS) {
goto exit;
}
- global_data.rng_state = RNG_SEEDED;
-#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
- status = psa_crypto_load_transaction();
- if (status == PSA_SUCCESS) {
- status = psa_crypto_recover_transaction(&psa_crypto_transaction);
- if (status != PSA_SUCCESS) {
- goto exit;
- }
- status = psa_crypto_stop_transaction();
- } else if (status == PSA_ERROR_DOES_NOT_EXIST) {
- /* There's no transaction to complete. It's all good. */
- status = PSA_SUCCESS;
+ status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_RNG);
+ if (status != PSA_SUCCESS) {
+ goto exit;
}
-#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
- /* All done. */
- global_data.initialized = 1;
+ status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_TRANSACTION);
exit:
+
if (status != PSA_SUCCESS) {
mbedtls_psa_crypto_free();
}
+
return status;
}
@@ -7823,7 +7927,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
- psa_key_attributes_t attributes;
psa_key_type_t type;
if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
@@ -7838,11 +7941,7 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
- type = psa_get_key_type(&attributes);
+ type = psa_get_key_type(&slot->attr);
if (type != PSA_KEY_TYPE_PASSWORD &&
type != PSA_KEY_TYPE_PASSWORD_HASH) {
@@ -7858,7 +7957,8 @@
memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes);
operation->data.inputs.password_len = slot->key.bytes;
- operation->data.inputs.attributes = attributes;
+ operation->data.inputs.attributes = slot->attr;
+
exit:
if (status != PSA_SUCCESS) {
psa_pake_abort(operation);
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index 49aa961..a201985 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -33,10 +33,10 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_cipher_id_t cipher_id;
mbedtls_cipher_mode_t mode;
- size_t key_bits = attributes->core.bits;
+ size_t key_bits = attributes->bits;
(void) key_buffer_size;
- status = mbedtls_cipher_values_from_psa(alg, attributes->core.type,
+ status = mbedtls_cipher_values_from_psa(alg, attributes->type,
&key_bits, &mode, &cipher_id);
if (status != PSA_SUCCESS) {
return status;
@@ -49,7 +49,7 @@
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
* The call to mbedtls_ccm_encrypt_and_tag or
* mbedtls_ccm_auth_decrypt will validate the tag length. */
- if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
+ if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -69,7 +69,7 @@
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
* The call to mbedtls_gcm_crypt_and_tag or
* mbedtls_gcm_auth_decrypt will validate the tag length. */
- if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
+ if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index 3132854..a45fb0f 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -289,14 +289,14 @@
int ret = 0;
size_t key_bits;
const mbedtls_cipher_info_t *cipher_info = NULL;
- psa_key_type_t key_type = attributes->core.type;
+ psa_key_type_t key_type = attributes->type;
(void) key_buffer_size;
mbedtls_cipher_init(&operation->ctx.cipher);
operation->alg = alg;
- key_bits = attributes->core.bits;
+ key_bits = attributes->bits;
cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
key_bits, NULL);
if (cipher_info == NULL) {
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index afa8659..d4bdf92 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -59,7 +59,7 @@
* and metadata for one key.
*/
typedef struct {
- psa_core_key_attributes_t attr;
+ psa_key_attributes_t attr;
/*
* The current state of the key slot, as described in
@@ -159,11 +159,6 @@
} while (0);
#endif
-/* A mask of key attribute flags used only internally.
- * Currently there aren't any. */
-#define PSA_KA_MASK_INTERNAL_ONLY ( \
- 0)
-
/** Test whether a key slot has any registered readers.
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
@@ -177,56 +172,6 @@
return slot->registered_readers > 0;
}
-/** Retrieve flags from psa_key_slot_t::attr::core::flags.
- *
- * \param[in] slot The key slot to query.
- * \param mask The mask of bits to extract.
- *
- * \return The key attribute flags in the given slot,
- * bitwise-anded with \p mask.
- */
-static inline uint16_t psa_key_slot_get_flags(const psa_key_slot_t *slot,
- uint16_t mask)
-{
- return slot->attr.flags & mask;
-}
-
-/** Set flags in psa_key_slot_t::attr::core::flags.
- *
- * \param[in,out] slot The key slot to modify.
- * \param mask The mask of bits to modify.
- * \param value The new value of the selected bits.
- */
-static inline void psa_key_slot_set_flags(psa_key_slot_t *slot,
- uint16_t mask,
- uint16_t value)
-{
- slot->attr.flags = ((~mask & slot->attr.flags) |
- (mask & value));
-}
-
-/** Turn on flags in psa_key_slot_t::attr::core::flags.
- *
- * \param[in,out] slot The key slot to modify.
- * \param mask The mask of bits to set.
- */
-static inline void psa_key_slot_set_bits_in_flags(psa_key_slot_t *slot,
- uint16_t mask)
-{
- slot->attr.flags |= mask;
-}
-
-/** Turn off flags in psa_key_slot_t::attr::core::flags.
- *
- * \param[in,out] slot The key slot to modify.
- * \param mask The mask of bits to clear.
- */
-static inline void psa_key_slot_clear_bits(psa_key_slot_t *slot,
- uint16_t mask)
-{
- slot->attr.flags &= ~mask;
-}
-
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** Get the SE slot number of a key from the key slot storing its description.
*
diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c
index 7edea81..95baff6 100644
--- a/library/psa_crypto_ecp.c
+++ b/library/psa_crypto_ecp.c
@@ -216,8 +216,8 @@
mbedtls_ecp_keypair *ecp = NULL;
/* Parse input */
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
data,
data_length,
&ecp);
@@ -225,7 +225,7 @@
goto exit;
}
- if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) ==
+ if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) ==
PSA_ECC_FAMILY_MONTGOMERY) {
*bits = ecp->grp.nbits + 1;
} else {
@@ -235,7 +235,7 @@
/* Re-export the data to PSA export format. There is currently no support
* for other input formats then the export format, so this is a 1-1
* copy operation. */
- status = mbedtls_psa_ecp_export_key(attributes->core.type,
+ status = mbedtls_psa_ecp_export_key(attributes->type,
ecp,
key_buffer,
key_buffer_size,
@@ -281,20 +281,8 @@
return status;
} else {
- if (data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits)) {
- return PSA_ERROR_BUFFER_TOO_SMALL;
- }
-
status = mbedtls_to_psa_error(
- mbedtls_ecp_write_key(ecp,
- data,
- PSA_BITS_TO_BYTES(ecp->grp.nbits)));
- if (status == PSA_SUCCESS) {
- *data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits);
- } else {
- memset(data, 0, data_size);
- }
-
+ mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size));
return status;
}
}
@@ -308,7 +296,7 @@
mbedtls_ecp_keypair *ecp = NULL;
status = mbedtls_psa_ecp_load_representation(
- attributes->core.type, attributes->core.bits,
+ attributes->type, attributes->bits,
key_buffer, key_buffer_size, &ecp);
if (status != PSA_SUCCESS) {
return status;
@@ -316,7 +304,7 @@
status = mbedtls_psa_ecp_export_key(
PSA_KEY_TYPE_ECC_PUBLIC_KEY(
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type)),
+ PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)),
ecp, data, data_size, data_length);
mbedtls_ecp_keypair_free(ecp);
@@ -337,9 +325,9 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
- attributes->core.type);
+ attributes->type);
mbedtls_ecp_group_id grp_id =
- mbedtls_ecc_group_from_psa(curve, attributes->core.bits);
+ mbedtls_ecc_group_from_psa(curve, attributes->bits);
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(grp_id);
@@ -359,14 +347,11 @@
}
status = mbedtls_to_psa_error(
- mbedtls_ecp_write_key(&ecp, key_buffer, key_buffer_size));
+ mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
+ key_buffer, key_buffer_size));
mbedtls_ecp_keypair_free(&ecp);
- if (status == PSA_SUCCESS) {
- *key_buffer_length = key_buffer_size;
- }
-
return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
@@ -389,8 +374,8 @@
size_t curve_bytes;
mbedtls_mpi r, s;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&ecp);
@@ -476,8 +461,8 @@
(void) alg;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&ecp);
@@ -541,14 +526,14 @@
size_t *shared_secret_length)
{
psa_status_t status;
- if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->core.type) ||
+ if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) ||
!PSA_ALG_IS_ECDH(alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
mbedtls_ecp_keypair *ecp = NULL;
status = mbedtls_psa_ecp_load_representation(
- attributes->core.type,
- attributes->core.bits,
+ attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&ecp);
diff --git a/library/psa_crypto_ffdh.c b/library/psa_crypto_ffdh.c
index 0099d5f..ae38f6d 100644
--- a/library/psa_crypto_ffdh.c
+++ b/library/psa_crypto_ffdh.c
@@ -151,7 +151,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi GX, G, X, P;
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
if (key_buffer_size > data_size) {
@@ -167,7 +167,7 @@
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
- size_t key_len = PSA_BITS_TO_BYTES(attributes->core.bits);
+ size_t key_len = PSA_BITS_TO_BYTES(attributes->bits);
status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G);
@@ -283,7 +283,7 @@
mbedtls_mpi_init(&K);
status = mbedtls_psa_ffdh_set_prime_generator(
- PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
+ PSA_BITS_TO_BYTES(attributes->bits), &P, &G);
if (status != PSA_SUCCESS) {
goto cleanup;
diff --git a/library/psa_crypto_random_impl.h b/library/psa_crypto_random_impl.h
index 64b8949..533fb2e 100644
--- a/library/psa_crypto_random_impl.h
+++ b/library/psa_crypto_random_impl.h
@@ -1,14 +1,6 @@
/** \file psa_crypto_random_impl.h
*
* \brief PSA crypto random generator implementation abstraction.
- *
- * The definitions here need to be consistent with the declarations
- * in include/psa_util_internal.h. This file contains some redundant
- * declarations to increase the chance that a compiler will detect
- * inconsistencies if one file is changed without updating the other,
- * but not all potential inconsistencies can be enforced, so make sure
- * to check the public declarations and contracts in
- * include/psa_util_internal.h if you modify this file.
*/
/*
* Copyright The Mbed TLS Contributors
@@ -22,22 +14,12 @@
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
-#include <string.h>
-#include <mbedtls/entropy.h> // only for error codes
-#include <psa/crypto.h>
-
typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
-/* Trivial wrapper around psa_generate_random(). */
-int mbedtls_psa_get_random(void *p_rng,
- unsigned char *output,
- size_t output_size);
-
-/* The PSA RNG API doesn't need any externally maintained state. */
-#define MBEDTLS_PSA_RANDOM_STATE NULL
-
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+#include "mbedtls/entropy.h"
+
/* Choose a DRBG based on configuration and availability */
#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
@@ -67,11 +49,37 @@
#error "No hash algorithm available for HMAC_DBRG."
#endif
-#else
+#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
+
#error "No DRBG module available for the psa_crypto module."
+
+#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+#include "mbedtls/ctr_drbg.h"
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+#include "mbedtls/hmac_drbg.h"
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
+
+/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
+#if defined(MBEDTLS_CTR_DRBG_C)
+#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
#endif
-#include "mbedtls/entropy.h"
+#if defined(MBEDTLS_CTR_DRBG_C)
+typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
+
+typedef struct {
+ void (* entropy_init)(mbedtls_entropy_context *ctx);
+ void (* entropy_free)(mbedtls_entropy_context *ctx);
+ mbedtls_entropy_context entropy;
+ mbedtls_psa_drbg_context_t drbg;
+} mbedtls_psa_random_context_t;
/** Initialize the PSA DRBG.
*
@@ -99,63 +107,6 @@
#endif
}
-/** The type of the PSA random generator context.
- *
- * The random generator context is composed of an entropy context and
- * a DRBG context.
- */
-typedef struct {
- void (* entropy_init)(mbedtls_entropy_context *ctx);
- void (* entropy_free)(mbedtls_entropy_context *ctx);
- mbedtls_entropy_context entropy;
- mbedtls_psa_drbg_context_t drbg;
-} mbedtls_psa_random_context_t;
-
-/* Defined in include/psa_util_internal.h so that it's visible to
- * application code. The declaration here is redundant, but included
- * as a safety net to make it more likely that a future change that
- * accidentally causes the implementation to diverge from the interface
- * will be noticed. */
-/* Do not include the declaration under MSVC because it doesn't accept it
- * ("error C2370: 'mbedtls_psa_get_random' : redefinition; different storage class").
- * Observed with Visual Studio 2013. A known bug apparently:
- * https://stackoverflow.com/questions/8146541/duplicate-external-static-declarations-not-allowed-in-visual-studio
- */
-#if !defined(_MSC_VER)
-static mbedtls_f_rng_t *const mbedtls_psa_get_random;
-#endif
-
-/** The maximum number of bytes that mbedtls_psa_get_random() is expected to
- * return.
- */
-#if defined(MBEDTLS_CTR_DRBG_C)
-#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
-#elif defined(MBEDTLS_HMAC_DRBG_C)
-#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
-#endif
-
-/** A pointer to the PSA DRBG state.
- *
- * This variable is only intended to be used through the macro
- * #MBEDTLS_PSA_RANDOM_STATE.
- */
-/* psa_crypto.c sets this variable to a pointer to the DRBG state in the
- * global PSA crypto state. */
-/* The type `mbedtls_psa_drbg_context_t` is defined in
- * include/psa_util_internal.h so that `mbedtls_psa_random_state` can be
- * declared there and be visible to application code. */
-extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
-
-/** A pointer to the PSA DRBG state.
- *
- * This macro expands to an expression that is suitable as the \c p_rng
- * parameter to pass to mbedtls_psa_get_random().
- *
- * This macro exists in all configurations where the psa_crypto module is
- * enabled. Its expansion depends on the configuration.
- */
-#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
-
/** Seed the PSA DRBG.
*
* \param entropy An entropy context to read the seed from.
@@ -167,23 +118,15 @@
* \return \c 0 on success.
* \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
*/
-static inline int mbedtls_psa_drbg_seed(
- mbedtls_entropy_context *entropy,
- const unsigned char *custom, size_t len)
+static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx,
+ mbedtls_entropy_context *entropy,
+ const unsigned char *custom, size_t len)
{
#if defined(MBEDTLS_CTR_DRBG_C)
- return mbedtls_ctr_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
- mbedtls_entropy_func,
- entropy,
- custom, len);
+ return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len);
#elif defined(MBEDTLS_HMAC_DRBG_C)
- const mbedtls_md_info_t *md_info =
- mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
- return mbedtls_hmac_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
- md_info,
- mbedtls_entropy_func,
- entropy,
- custom, len);
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
+ return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len);
#endif
}
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 84a8667..2f613b3 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -116,7 +116,7 @@
mbedtls_rsa_context *rsa = NULL;
/* Parse input */
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
data,
data_length,
&rsa);
@@ -130,7 +130,7 @@
* representation in the key slot. Export representation in case of RSA is
* the smallest representation that's allowed as input, so a straight-up
* allocation of the same size as the input buffer will be large enough. */
- status = mbedtls_psa_rsa_export_key(attributes->core.type,
+ status = mbedtls_psa_rsa_export_key(attributes->type,
rsa,
key_buffer,
key_buffer_size,
@@ -196,7 +196,7 @@
mbedtls_rsa_context *rsa = NULL;
status = mbedtls_psa_rsa_load_representation(
- attributes->core.type, key_buffer, key_buffer_size, &rsa);
+ attributes->type, key_buffer, key_buffer_size, &rsa);
if (status != PSA_SUCCESS) {
return status;
}
@@ -261,13 +261,13 @@
ret = mbedtls_rsa_gen_key(&rsa,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE,
- (unsigned int) attributes->core.bits,
+ (unsigned int) attributes->bits,
exponent);
if (ret != 0) {
return mbedtls_to_psa_error(ret);
}
- status = mbedtls_psa_rsa_export_key(attributes->core.type,
+ status = mbedtls_psa_rsa_export_key(attributes->type,
&rsa, key_buffer, key_buffer_size,
key_buffer_length);
mbedtls_rsa_free(&rsa);
@@ -325,7 +325,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_alg;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
@@ -424,7 +424,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_alg;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
@@ -536,11 +536,11 @@
(void) output_size;
(void) output_length;
- if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
mbedtls_rsa_context *rsa = NULL;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
@@ -632,11 +632,11 @@
*output_length = 0;
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
mbedtls_rsa_context *rsa = NULL;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index b2a3c7e..b184ed0 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -34,6 +34,23 @@
static psa_global_data_t global_data;
+static uint8_t psa_get_key_slots_initialized(void)
+{
+ uint8_t initialized;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ initialized = global_data.key_slots_initialized;
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex);
+#endif /* defined(MBEDTLS_THREADING_C) */
+
+ return initialized;
+}
+
int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok)
{
psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
@@ -136,7 +153,9 @@
{
/* Nothing to do: program startup and psa_wipe_all_key_slots() both
* guarantee that the key slots are initialized to all-zero, which
- * means that all the key slots are in a valid, empty state. */
+ * means that all the key slots are in a valid, empty state. The global
+ * data mutex is already held when calling this function, so no need to
+ * lock it here, to set the flag. */
global_data.key_slots_initialized = 1;
return PSA_SUCCESS;
}
@@ -151,6 +170,7 @@
slot->state = PSA_SLOT_PENDING_DELETION;
(void) psa_wipe_key_slot(slot);
}
+ /* The global data mutex is already held when calling this function. */
global_data.key_slots_initialized = 0;
}
@@ -161,7 +181,7 @@
size_t slot_idx;
psa_key_slot_t *selected_slot, *unused_persistent_key_slot;
- if (!global_data.key_slots_initialized) {
+ if (!psa_get_key_slots_initialized()) {
status = PSA_ERROR_BAD_STATE;
goto error;
}
@@ -329,7 +349,7 @@
/* Copy actual key length and core attributes into the slot on success */
slot->key.bytes = key_buffer_length;
- slot->attr = attributes.core;
+ slot->attr = attributes;
exit:
if (status != PSA_SUCCESS) {
psa_remove_key_data_from_memory(slot);
@@ -344,7 +364,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
*p_slot = NULL;
- if (!global_data.key_slots_initialized) {
+ if (!psa_get_key_slots_initialized()) {
return PSA_ERROR_BAD_STATE;
}
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 13a3c8a..7d1317b 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -235,7 +235,7 @@
void psa_format_key_data_for_storage(const uint8_t *data,
const size_t data_length,
- const psa_core_key_attributes_t *attr,
+ const psa_key_attributes_t *attr,
uint8_t *storage_data)
{
psa_persistent_key_storage_format *storage_format =
@@ -267,7 +267,7 @@
size_t storage_data_length,
uint8_t **key_data,
size_t *key_data_length,
- psa_core_key_attributes_t *attr)
+ psa_key_attributes_t *attr)
{
psa_status_t status;
const psa_persistent_key_storage_format *storage_format =
@@ -314,7 +314,7 @@
return PSA_SUCCESS;
}
-psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
+psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
const uint8_t *data,
const size_t data_length)
{
@@ -352,7 +352,7 @@
mbedtls_zeroize_and_free(key_data, key_data_length);
}
-psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
+psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
uint8_t **data,
size_t *data_length)
{
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index b6b5e15..d7f5b18 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -93,7 +93,7 @@
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
*/
-psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
+psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
const uint8_t *data,
const size_t data_length);
@@ -123,7 +123,7 @@
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
*/
-psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
+psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
uint8_t **data,
size_t *data_length);
@@ -163,7 +163,7 @@
*/
void psa_format_key_data_for_storage(const uint8_t *data,
const size_t data_length,
- const psa_core_key_attributes_t *attr,
+ const psa_key_attributes_t *attr,
uint8_t *storage_data);
/**
@@ -186,7 +186,7 @@
size_t storage_data_length,
uint8_t **key_data,
size_t *key_data_length,
- psa_core_key_attributes_t *attr);
+ psa_key_attributes_t *attr);
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** This symbol is defined if transaction support is required. */
@@ -231,8 +231,9 @@
* This type is designed to be serialized by writing the memory representation
* and reading it back on the same device.
*
- * \note The transaction mechanism is designed for a single active transaction
- * at a time. The transaction object is #psa_crypto_transaction.
+ * \note The transaction mechanism is not thread-safe. There can only be one
+ * single active transaction at a time.
+ * The transaction object is #psa_crypto_transaction.
*
* \note If an API call starts a transaction, it must complete this transaction
* before returning to the application.
diff --git a/library/psa_util.c b/library/psa_util.c
index 125b173..4ccc5b0 100644
--- a/library/psa_util.c
+++ b/library/psa_util.c
@@ -18,7 +18,7 @@
#include "psa_util_internal.h"
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include <psa/crypto.h>
@@ -46,6 +46,7 @@
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
#include <mbedtls/cipher.h>
#endif
+#include <mbedtls/entropy.h>
/* PSA_SUCCESS is kept at the top of each error table since
* it's the most common status when everything functions properly. */
@@ -338,7 +339,31 @@
}
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+/* Wrapper function allowing the classic API to use the PSA RNG.
+ *
+ * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
+ * `psa_generate_random(...)`. The state parameter is ignored since the
+ * PSA API doesn't support passing an explicit state.
+ */
+int mbedtls_psa_get_random(void *p_rng,
+ unsigned char *output,
+ size_t output_size)
+{
+ /* This function takes a pointer to the RNG state because that's what
+ * classic mbedtls functions using an RNG expect. The PSA RNG manages
+ * its own state internally and doesn't let the caller access that state.
+ * So we just ignore the state parameter, and in practice we'll pass
+ * NULL. */
+ (void) p_rng;
+ psa_status_t status = psa_generate_random(output, output_size);
+ if (status == PSA_SUCCESS) {
+ return 0;
+ } else {
+ return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+ }
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
diff --git a/library/psa_util_internal.h b/library/psa_util_internal.h
index 3e62d5f..70a08a0 100644
--- a/library/psa_util_internal.h
+++ b/library/psa_util_internal.h
@@ -16,7 +16,7 @@
#include "psa/crypto.h"
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/*************************************************************************
* FFDH
@@ -96,5 +96,5 @@
sizeof(error_list)/sizeof(error_list[0]), \
fallback_f)
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#endif /* MBEDTLS_PSA_UTIL_INTERNAL_H */
diff --git a/library/rsa.c b/library/rsa.c
index 5debc69..7eb4a25 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -2231,7 +2231,7 @@
if (ctx->padding != MBEDTLS_RSA_PKCS_V21) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
- if (ctx->hash_id == MBEDTLS_MD_NONE) {
+ if ((ctx->hash_id == MBEDTLS_MD_NONE) && (md_alg == MBEDTLS_MD_NONE)) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen,
diff --git a/library/sha3.c b/library/sha3.c
index 27d495f..5738559 100644
--- a/library/sha3.c
+++ b/library/sha3.c
@@ -14,6 +14,33 @@
#if defined(MBEDTLS_SHA3_C)
+/*
+ * These macros select manually unrolled implementations of parts of the main permutation function.
+ *
+ * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
+ * from manually unrolling at higher optimisation levels.
+ *
+ * Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust
+ * these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and
+ * x86-64.
+ */
+#if !defined(MBEDTLS_SHA3_THETA_UNROLL)
+ #define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names
+#endif
+#if !defined(MBEDTLS_SHA3_CHI_UNROLL)
+ #if defined(__OPTIMIZE_SIZE__)
+ #define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names
+ #else
+ #define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names
+ #endif
+#endif
+#if !defined(MBEDTLS_SHA3_PI_UNROLL)
+ #define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names
+#endif
+#if !defined(MBEDTLS_SHA3_RHO_UNROLL)
+ #define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names
+#endif
+
#include "mbedtls/sha3.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@@ -56,18 +83,15 @@
};
#undef H
-static const uint8_t rho[24] = {
- 1, 62, 28, 27, 36, 44, 6, 55, 20,
- 3, 10, 43, 25, 39, 41, 45, 15,
- 21, 8, 18, 2, 61, 56, 14
+static const uint32_t rho[6] = {
+ 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
};
-static const uint8_t pi[24] = {
- 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
- 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
+static const uint32_t pi[6] = {
+ 0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916
};
-#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
+#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
} while (0)
#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
@@ -84,39 +108,97 @@
uint64_t t;
/* Theta */
+#if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
+ for (i = 0; i < 5; i++) {
+ lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
+ }
+ for (i = 0; i < 5; i++) {
+ t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
+ s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
+ }
+#else
lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
- t = lane[4] ^ ROT64(lane[1], 1);
+ t = lane[4] ^ ROTR64(lane[1], 63);
s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
- t = lane[0] ^ ROT64(lane[2], 1);
+ t = lane[0] ^ ROTR64(lane[2], 63);
s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
- t = lane[1] ^ ROT64(lane[3], 1);
+ t = lane[1] ^ ROTR64(lane[3], 63);
s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
- t = lane[2] ^ ROT64(lane[4], 1);
+ t = lane[2] ^ ROTR64(lane[4], 63);
s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
- t = lane[3] ^ ROT64(lane[0], 1);
+ t = lane[3] ^ ROTR64(lane[0], 63);
s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
+#endif
/* Rho */
- for (i = 1; i < 25; i++) {
- s[i] = ROT64(s[i], rho[i-1]);
+ for (i = 1; i < 25; i += 4) {
+ uint32_t r = rho[(i - 1) >> 2];
+#if MBEDTLS_SHA3_RHO_UNROLL == 0
+ for (int j = i; j < i + 4; j++) {
+ uint8_t r8 = (uint8_t) (r >> 24);
+ r <<= 8;
+ s[j] = ROTR64(s[j], r8);
+ }
+#else
+ s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
+ s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
+ s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
+ s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
+#endif
}
/* Pi */
t = s[1];
- for (i = 0; i < 24; i++) {
- SWAP(s[pi[i]], t);
+#if MBEDTLS_SHA3_PI_UNROLL == 0
+ for (i = 0; i < 24; i += 4) {
+ uint32_t p = pi[i >> 2];
+ for (unsigned j = 0; j < 4; j++) {
+ SWAP(s[p & 0xff], t);
+ p >>= 8;
+ }
}
+#else
+ uint32_t p = pi[0];
+ SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
+ SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
+ p = pi[1];
+ SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
+ SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
+ p = pi[2];
+ SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
+ SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
+ p = pi[3];
+ SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
+ SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
+ p = pi[4];
+ SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
+ SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
+ p = pi[5];
+ SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
+ SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
+#endif
/* Chi */
+#if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names
+ for (i = 0; i <= 20; i += 5) {
+ lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2];
+ lane[3] = s[i + 3]; lane[4] = s[i + 4];
+ s[i + 0] ^= (~lane[1]) & lane[2];
+ s[i + 1] ^= (~lane[2]) & lane[3];
+ s[i + 2] ^= (~lane[3]) & lane[4];
+ s[i + 3] ^= (~lane[4]) & lane[0];
+ s[i + 4] ^= (~lane[0]) & lane[1];
+ }
+#else
lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
s[0] ^= (~lane[1]) & lane[2];
s[1] ^= (~lane[2]) & lane[3];
@@ -151,6 +233,7 @@
s[22] ^= (~lane[3]) & lane[4];
s[23] ^= (~lane[4]) & lane[0];
s[24] ^= (~lane[0]) & lane[1];
+#endif
/* Iota */
/* Decompress the round masks (see definition of rc) */
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 6d988a8..345e608 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -765,11 +765,6 @@
MBEDTLS_SSL_SESSION_TICKETS &&
MBEDTLS_HAVE_TIME */
- if (ssl->conf->f_rng == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
- return MBEDTLS_ERR_SSL_NO_RNG;
- }
-
/* Bet on the highest configured version if we are not in a TLS 1.2
* renegotiation or session resumption.
*/
@@ -797,10 +792,15 @@
(ssl->handshake->cookie == NULL))
#endif
{
- ret = ssl_generate_random(ssl);
- if (ret != 0) {
- MBEDTLS_SSL_DEBUG_RET(1, "Random bytes generation failed", ret);
- return ret;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ if (!ssl->handshake->hello_retry_request_flag)
+#endif
+ {
+ ret = ssl_generate_random(ssl);
+ if (ret != 0) {
+ MBEDTLS_SSL_DEBUG_RET(1, "Random bytes generation failed", ret);
+ return ret;
+ }
}
}
diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h
index 2b0e737..4889e77 100644
--- a/library/ssl_debug_helpers.h
+++ b/library/ssl_debug_helpers.h
@@ -21,6 +21,11 @@
const char *mbedtls_ssl_states_str(mbedtls_ssl_states in);
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
+const char *mbedtls_ssl_early_data_status_str(mbedtls_ssl_early_data_status in);
+const char *mbedtls_ssl_early_data_state_str(mbedtls_ssl_early_data_state in);
+#endif
+
const char *mbedtls_ssl_protocol_version_str(mbedtls_ssl_protocol_version in);
const char *mbedtls_tls_prf_types_str(mbedtls_tls_prf_types in);
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 942d4ad..a8807f6 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -665,21 +665,21 @@
#if defined(MBEDTLS_SSL_CLI_C)
/** Minimum TLS version to be negotiated.
*
- * It is set up in the ClientHello writing preparation stage and used
- * throughout the ClientHello writing. Not relevant anymore as soon as
- * the protocol version has been negotiated thus as soon as the
- * ServerHello is received.
- * For a fresh handshake not linked to any previous handshake, it is
- * equal to the configured minimum minor version to be negotiated. When
- * renegotiating or resuming a session, it is equal to the previously
- * negotiated minor version.
+ * It is set up in the ClientHello writing preparation stage and used
+ * throughout the ClientHello writing. Not relevant anymore as soon as
+ * the protocol version has been negotiated thus as soon as the
+ * ServerHello is received.
+ * For a fresh handshake not linked to any previous handshake, it is
+ * equal to the configured minimum minor version to be negotiated. When
+ * renegotiating or resuming a session, it is equal to the previously
+ * negotiated minor version.
*
- * There is no maximum TLS version field in this handshake context.
- * From the start of the handshake, we need to define a current protocol
- * version for the record layer which we define as the maximum TLS
- * version to be negotiated. The `tls_version` field of the SSL context is
- * used to store this maximum value until it contains the actual
- * negotiated value.
+ * There is no maximum TLS version field in this handshake context.
+ * From the start of the handshake, we need to define a current protocol
+ * version for the record layer which we define as the maximum TLS
+ * version to be negotiated. The `tls_version` field of the SSL context is
+ * used to store this maximum value until it contains the actual
+ * negotiated value.
*/
mbedtls_ssl_protocol_version min_tls_version;
#endif
@@ -730,16 +730,21 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
uint8_t key_exchange_mode; /*!< Selected key exchange mode */
- /** Number of HelloRetryRequest messages received/sent from/to the server. */
- uint8_t hello_retry_request_count;
+ /**
+ * Flag indicating if, in the course of the current handshake, an
+ * HelloRetryRequest message has been sent by the server or received by
+ * the client (<> 0) or not (0).
+ */
+ uint8_t hello_retry_request_flag;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
/**
- * Number of dummy change_cipher_spec (CCS) record sent. Used to send only
- * one CCS per handshake without having to complicate the handshake state
- * transitions.
+ * Flag indicating if, in the course of the current handshake, a dummy
+ * change_cipher_spec (CCS) record has already been sent. Used to send only
+ * one CCS per handshake while not complicating the handshake state
+ * transitions for that purpose.
*/
- uint8_t ccs_count;
+ uint8_t ccs_sent;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
@@ -2146,20 +2151,30 @@
const unsigned char *end,
size_t *out_len);
-#if defined(MBEDTLS_SSL_CLI_C)
+int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
+ size_t early_data_len);
+
+typedef enum {
/*
- * The client has not sent the first ClientHello yet, it is unknown if the
- * client will send an early data indication extension or not.
+ * The client has not sent the first ClientHello yet, the negotiation of early
+ * data has not started yet.
*/
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0
+ MBEDTLS_SSL_EARLY_DATA_STATE_IDLE,
+
+/*
+ * In its ClientHello, the client has not included an early data indication
+ * extension.
+ */
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT,
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
- * is not set and early data cannot be sent yet.
+ * is not set either as for middlebox compatibility a dummy CCS may have to be
+ * sent in clear. Early data cannot be sent to the server yet.
*/
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_SENT 4
+ MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT,
/*
* The client has sent an early data indication extension in its first
@@ -2167,16 +2182,28 @@
* HelloRetryRequest) from the server yet. The transform to protect early data
* has been set and early data can be written now.
*/
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE 5
+ MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE,
+
+/*
+ * The client has indicated the use of early data and the server has accepted
+ * it.
+ */
+ MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED,
+
+/*
+ * The client has indicated the use of early data but the server has rejected
+ * it.
+ */
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED,
/*
* The client has sent an early data indication extension in its first
* ClientHello, the server has accepted them and the client has received the
* server Finished message. It cannot send early data to the server anymore.
*/
-#define MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED 6
-#endif /* MBEDTLS_SSL_CLI_C */
+ MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED,
+} mbedtls_ssl_early_data_state;
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
@@ -2825,6 +2852,13 @@
const char *hostname);
#endif
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \
+ defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
+int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session,
+ const char *alpn);
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
#define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800)
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index c2e64c6..b07cd96 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -4005,7 +4005,11 @@
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
MBEDTLS_SSL_DEBUG_MSG(
3, ("EarlyData: deprotect and discard app data records."));
- /* TODO: Add max_early_data_size check here, see issue 6347 */
+
+ ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
+ if (ret != 0) {
+ return ret;
+ }
ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
}
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
@@ -4129,9 +4133,15 @@
*/
if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
+
+ ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
+ if (ret != 0) {
+ return ret;
+ }
+
MBEDTLS_SSL_DEBUG_MSG(
3, ("EarlyData: Ignore application message before 2nd ClientHello"));
- /* TODO: Add max_early_data_size check here, see issue 6347 */
+
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
} else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
@@ -6058,6 +6068,111 @@
return ret;
}
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
+int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
+ const unsigned char *buf, size_t len)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const struct mbedtls_ssl_config *conf;
+ uint32_t remaining;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data"));
+
+ if (ssl == NULL || (conf = ssl->conf) == NULL) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) ||
+ (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
+ (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) {
+ return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
+ }
+
+ if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
+ return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
+ }
+
+ /*
+ * If we are at the beginning of the handshake, the early data state being
+ * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or
+ * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just
+ * enough to be able to send early data if possible. That way, we can
+ * guarantee that when starting the handshake with this function we will
+ * send at least one record of early data. Note that when the state is
+ * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet
+ * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data
+ * as the early data outbound transform has not been set as we may have to
+ * first send a dummy CCS in clear.
+ */
+ if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
+ (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
+ while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
+ (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
+ ret = mbedtls_ssl_handshake_step(ssl);
+ if (ret != 0) {
+ MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret);
+ return ret;
+ }
+
+ ret = mbedtls_ssl_flush_output(ssl);
+ if (ret != 0) {
+ MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
+ return ret;
+ }
+ }
+ remaining = ssl->session_negotiate->max_early_data_size;
+ } else {
+ /*
+ * If we are past the point where we can send early data or we have
+ * already reached the maximum early data size, return immediatly.
+ * Otherwise, progress the handshake as much as possible to not delay
+ * it too much. If we reach a point where we can still send early data,
+ * then we will send some.
+ */
+ if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
+ (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) {
+ return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
+ }
+
+ remaining = ssl->session_negotiate->max_early_data_size -
+ ssl->total_early_data_size;
+
+ if (remaining == 0) {
+ return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
+ }
+
+ ret = mbedtls_ssl_handshake(ssl);
+ if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) {
+ MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
+ return ret;
+ }
+ }
+
+ if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
+ (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED))
+ || (remaining == 0)) {
+ return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
+ }
+
+ if (len > remaining) {
+ len = remaining;
+ }
+
+ ret = ssl_write_real(ssl, buf, len);
+ if (ret >= 0) {
+ ssl->total_early_data_size += ret;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret));
+
+ return ret;
+}
+#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
+
/*
* Notify the peer that the connection is being closed
*/
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 5da3887..6a31b0b 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -504,7 +504,7 @@
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_ms_time_t ticket_creation_time, ticket_age;
mbedtls_ms_time_t ticket_lifetime =
- (mbedtls_ms_time_t) ctx->ticket_lifetime * 1000;
+ (mbedtls_ms_time_t) key->lifetime * 1000;
ret = mbedtls_ssl_session_get_ticket_creation_time(session,
&ticket_creation_time);
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5b0a4b9..ac53853 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -238,6 +238,11 @@
#endif
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN) && \
+ defined(MBEDTLS_SSL_EARLY_DATA)
+ dst->ticket_alpn = NULL;
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@@ -275,6 +280,16 @@
#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN) && \
+ defined(MBEDTLS_SSL_EARLY_DATA)
+ {
+ int ret = mbedtls_ssl_session_set_ticket_alpn(dst, src->ticket_alpn);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_ALPN && MBEDTLS_SSL_EARLY_DATA */
+
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
if (src->ticket != NULL) {
dst->ticket = mbedtls_calloc(1, src->ticket_len);
@@ -432,10 +447,6 @@
static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
#endif /* MBEDTLS_MD_CAN_SHA384*/
-static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len);
-
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_session_load(mbedtls_ssl_session *session,
const unsigned char *buf,
@@ -1100,11 +1111,12 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_CLI_C)
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN;
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IDLE;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
#endif
+ ssl->total_early_data_size = 0;
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Initialize structures */
@@ -1365,6 +1377,11 @@
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+ if (ssl->conf->f_rng == NULL) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
+ return MBEDTLS_ERR_SSL_NO_RNG;
+ }
+
/* Space for further checks */
return 0;
@@ -2448,282 +2465,6 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-/* Serialization of TLS 1.3 sessions:
- *
- * struct {
- * opaque hostname<0..2^16-1>;
- * uint64 ticket_reception_time;
- * uint32 ticket_lifetime;
- * opaque ticket<1..2^16-1>;
- * } ClientOnlyData;
- *
- * struct {
- * uint32 ticket_age_add;
- * 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;
- * };
- * } serialized_session_tls13;
- *
- */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len,
- size_t *olen)
-{
- unsigned char *p = buf;
-#if defined(MBEDTLS_SSL_CLI_C) && \
- defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- size_t hostname_len = (session->hostname == NULL) ?
- 0 : strlen(session->hostname) + 1;
-#endif
- size_t needed = 4 /* ticket_age_add */
- + 1 /* ticket_flags */
- + 1; /* resumption_key length */
- *olen = 0;
-
- if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- needed += session->resumption_key_len; /* resumption_key */
-
-#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 */
-#endif
-
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- needed += 2 /* hostname_len */
- + hostname_len; /* hostname */
-#endif
-
- needed += 4 /* ticket_lifetime */
- + 2; /* ticket_len */
-
- /* Check size_t overflow */
- if (session->ticket_len > SIZE_MAX - needed) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- needed += session->ticket_len; /* ticket */
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-
- *olen = needed;
- if (needed > buf_len) {
- return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
- }
-
- MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0);
- p[4] = session->ticket_flags;
-
- /* save resumption_key */
- p[5] = session->resumption_key_len;
- p += 6;
- memcpy(p, session->resumption_key, session->resumption_key_len);
- p += session->resumption_key_len;
-
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- 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) {
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME */
-
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
- p += 2;
- if (hostname_len > 0) {
- /* save host name */
- memcpy(p, session->hostname, hostname_len);
- p += hostname_len;
- }
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-
-#if defined(MBEDTLS_HAVE_TIME)
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
- p += 8;
-#endif
- MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
- p += 4;
-
- MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0);
- p += 2;
-
- if (session->ticket != NULL && session->ticket_len > 0) {
- memcpy(p, session->ticket, session->ticket_len);
- p += session->ticket_len;
- }
- }
-#endif /* MBEDTLS_SSL_CLI_C */
- return 0;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_session_load(mbedtls_ssl_session *session,
- const unsigned char *buf,
- size_t len)
-{
- const unsigned char *p = buf;
- const unsigned char *end = buf + len;
-
- if (end - p < 6) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0);
- session->ticket_flags = p[4];
-
- /* load resumption_key */
- session->resumption_key_len = p[5];
- p += 6;
-
- if (end - p < session->resumption_key_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- if (sizeof(session->resumption_key) < session->resumption_key_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- memcpy(session->resumption_key, p, session->resumption_key_len);
- p += session->resumption_key_len;
-
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (end - p < 4) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- 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) {
- if (end - p < 8) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME */
-
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- size_t hostname_len;
- /* load host name */
- if (end - p < 2) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- hostname_len = MBEDTLS_GET_UINT16_BE(p, 0);
- p += 2;
-
- if (end - p < (long int) hostname_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- if (hostname_len > 0) {
- session->hostname = mbedtls_calloc(1, hostname_len);
- if (session->hostname == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
- memcpy(session->hostname, p, hostname_len);
- p += hostname_len;
- }
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-
-#if defined(MBEDTLS_HAVE_TIME)
- if (end - p < 8) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
-#endif
- if (end - p < 4) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
-
- if (end - p < 2) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0);
- p += 2;
-
- if (end - p < (long int) session->ticket_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- if (session->ticket_len > 0) {
- session->ticket = mbedtls_calloc(1, session->ticket_len);
- if (session->ticket == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
- memcpy(session->ticket, p, session->ticket_len);
- p += session->ticket_len;
- }
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-
- return 0;
-
-}
-#else /* MBEDTLS_SSL_SESSION_TICKETS */
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len,
- size_t *olen)
-{
- ((void) session);
- ((void) buf);
- ((void) buf_len);
- *olen = 0;
- return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-}
-
-static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len)
-{
- ((void) session);
- ((void) buf);
- ((void) buf_len);
- return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-}
-#endif /* !MBEDTLS_SSL_SESSION_TICKETS */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
-
psa_status_t mbedtls_ssl_cipher_to_psa(mbedtls_cipher_type_t mbedtls_cipher_type,
size_t taglen,
psa_algorithm_t *alg,
@@ -3640,6 +3381,684 @@
}
#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
+/* Serialization of TLS 1.2 sessions
+ *
+ * For more detail, see the description of ssl_session_save().
+ */
+static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len)
+{
+ unsigned char *p = buf;
+ size_t used = 0;
+
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ used += 8;
+
+ if (used <= buf_len) {
+ start = (uint64_t) session->start;
+
+ MBEDTLS_PUT_UINT64_BE(start, p, 0);
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ used += 1 /* id_len */
+ + sizeof(session->id)
+ + sizeof(session->master)
+ + 4; /* verify_result */
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_0(session->id_len);
+ memcpy(p, session->id, 32);
+ p += 32;
+
+ memcpy(p, session->master, 48);
+ p += 48;
+
+ MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0);
+ p += 4;
+ }
+
+ /*
+ * Peer's end-entity certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if (session->peer_cert == NULL) {
+ cert_len = 0;
+ } else {
+ cert_len = session->peer_cert->raw.len;
+ }
+
+ used += 3 + cert_len;
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_2(cert_len);
+ *p++ = MBEDTLS_BYTE_1(cert_len);
+ *p++ = MBEDTLS_BYTE_0(cert_len);
+
+ if (session->peer_cert != NULL) {
+ memcpy(p, session->peer_cert->raw.p, cert_len);
+ p += cert_len;
+ }
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if (session->peer_cert_digest != NULL) {
+ used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
+ if (used <= buf_len) {
+ *p++ = (unsigned char) session->peer_cert_digest_type;
+ *p++ = (unsigned char) session->peer_cert_digest_len;
+ memcpy(p, session->peer_cert_digest,
+ session->peer_cert_digest_len);
+ p += session->peer_cert_digest_len;
+ }
+ } else {
+ used += 2;
+ if (used <= buf_len) {
+ *p++ = (unsigned char) MBEDTLS_MD_NONE;
+ *p++ = 0;
+ }
+ }
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket if any, plus associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+ used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_2(session->ticket_len);
+ *p++ = MBEDTLS_BYTE_1(session->ticket_len);
+ *p++ = MBEDTLS_BYTE_0(session->ticket_len);
+
+ if (session->ticket != NULL) {
+ memcpy(p, session->ticket, session->ticket_len);
+ p += session->ticket_len;
+ }
+
+ MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
+ p += 4;
+ }
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ used += 8;
+
+ if (used <= buf_len) {
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
+ p += 8;
+ }
+ }
+#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ used += 1;
+
+ if (used <= buf_len) {
+ *p++ = session->mfl_code;
+ }
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ used += 1;
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac);
+ }
+#endif
+
+ return used;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls12_session_load(mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len)
+{
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ const unsigned char *p = buf;
+ const unsigned char * const end = buf + len;
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ if (8 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ start = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+
+ session->start = (time_t) start;
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ if (1 + 32 + 48 + 4 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->id_len = *p++;
+ memcpy(session->id, p, 32);
+ p += 32;
+
+ memcpy(session->master, p, 48);
+ p += 48;
+
+ session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+
+ /* Immediately clear invalid pointer values that have been read, in case
+ * we exit early before we replaced them with valid ones. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ session->peer_cert = NULL;
+#else
+ session->peer_cert_digest = NULL;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ session->ticket = NULL;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Peer certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* Deserialize CRT from the end of the ticket. */
+ if (3 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ cert_len = MBEDTLS_GET_UINT24_BE(p, 0);
+ p += 3;
+
+ if (cert_len != 0) {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if (cert_len > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
+
+ if (session->peer_cert == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+
+ mbedtls_x509_crt_init(session->peer_cert);
+
+ if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert,
+ p, cert_len)) != 0) {
+ mbedtls_x509_crt_free(session->peer_cert);
+ mbedtls_free(session->peer_cert);
+ session->peer_cert = NULL;
+ return ret;
+ }
+
+ p += cert_len;
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* Deserialize CRT digest from the end of the ticket. */
+ if (2 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
+ session->peer_cert_digest_len = (size_t) *p++;
+
+ if (session->peer_cert_digest_len != 0) {
+ const mbedtls_md_info_t *md_info =
+ mbedtls_md_info_from_type(session->peer_cert_digest_type);
+ if (md_info == NULL) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if (session->peer_cert_digest_len > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->peer_cert_digest =
+ mbedtls_calloc(1, session->peer_cert_digest_len);
+ if (session->peer_cert_digest == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+
+ memcpy(session->peer_cert_digest, p,
+ session->peer_cert_digest_len);
+ p += session->peer_cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket and associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+ if (3 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0);
+ p += 3;
+
+ if (session->ticket_len != 0) {
+ if (session->ticket_len > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->ticket = mbedtls_calloc(1, session->ticket_len);
+ if (session->ticket == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+
+ memcpy(session->ticket, p, session->ticket_len);
+ p += session->ticket_len;
+ }
+
+ if (4 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ if (8 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ if (1 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->mfl_code = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if (1 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->encrypt_then_mac = *p++;
+#endif
+
+ /* Done, should have consumed entire buffer */
+ if (p != end) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ return 0;
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/* Serialization of TLS 1.3 sessions:
+ *
+ * For more detail, see the description of ssl_session_save().
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen)
+{
+ unsigned char *p = buf;
+#if defined(MBEDTLS_SSL_CLI_C) && \
+ defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ size_t hostname_len = (session->hostname == NULL) ?
+ 0 : strlen(session->hostname) + 1;
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C) && \
+ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ const size_t alpn_len = (session->ticket_alpn == NULL) ?
+ 0 : strlen(session->ticket_alpn) + 1;
+#endif
+ size_t needed = 4 /* ticket_age_add */
+ + 1 /* ticket_flags */
+ + 1; /* resumption_key length */
+
+ *olen = 0;
+
+ if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ needed += session->resumption_key_len; /* resumption_key */
+
+#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 */
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ needed += 2 /* alpn_len */
+ + alpn_len; /* alpn */
+#endif
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ needed += 2 /* hostname_len */
+ + hostname_len; /* hostname */
+#endif
+
+ needed += 4 /* ticket_lifetime */
+ + 2; /* ticket_len */
+
+ /* Check size_t overflow */
+ if (session->ticket_len > SIZE_MAX - needed) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ needed += session->ticket_len; /* ticket */
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+ *olen = needed;
+ if (needed > buf_len) {
+ return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+ }
+
+ MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0);
+ p[4] = session->ticket_flags;
+
+ /* save resumption_key */
+ p[5] = session->resumption_key_len;
+ p += 6;
+ memcpy(p, session->resumption_key, session->resumption_key_len);
+ p += session->resumption_key_len;
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ 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_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+#if defined(MBEDTLS_HAVE_TIME)
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
+ p += 8;
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ MBEDTLS_PUT_UINT16_BE(alpn_len, p, 0);
+ p += 2;
+
+ if (alpn_len > 0) {
+ /* save chosen alpn */
+ memcpy(p, session->ticket_alpn, alpn_len);
+ p += alpn_len;
+ }
+#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
+ p += 2;
+ if (hostname_len > 0) {
+ /* save host name */
+ memcpy(p, session->hostname, hostname_len);
+ p += hostname_len;
+ }
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_HAVE_TIME)
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
+ p += 8;
+#endif
+ MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
+ p += 4;
+
+ MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0);
+ p += 2;
+
+ if (session->ticket != NULL && session->ticket_len > 0) {
+ memcpy(p, session->ticket, session->ticket_len);
+ p += session->ticket_len;
+ }
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+ return 0;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_session_load(mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len)
+{
+ const unsigned char *p = buf;
+ const unsigned char *end = buf + len;
+
+ if (end - p < 6) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0);
+ session->ticket_flags = p[4];
+
+ /* load resumption_key */
+ session->resumption_key_len = p[5];
+ p += 6;
+
+ if (end - p < session->resumption_key_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if (sizeof(session->resumption_key) < session->resumption_key_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ memcpy(session->resumption_key, p, session->resumption_key_len);
+ p += session->resumption_key_len;
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ if (end - p < 4) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ 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_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+#if defined(MBEDTLS_HAVE_TIME)
+ if (end - p < 8) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ size_t alpn_len;
+
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ alpn_len = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+
+ if (end - p < (long int) alpn_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if (alpn_len > 0) {
+ int ret = mbedtls_ssl_session_set_ticket_alpn(session, (char *) p);
+ if (ret != 0) {
+ return ret;
+ }
+ p += alpn_len;
+ }
+#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ size_t hostname_len;
+ /* load host name */
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ hostname_len = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+
+ if (end - p < (long int) hostname_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (hostname_len > 0) {
+ session->hostname = mbedtls_calloc(1, hostname_len);
+ if (session->hostname == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(session->hostname, p, hostname_len);
+ p += hostname_len;
+ }
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_HAVE_TIME)
+ if (end - p < 8) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+#endif
+ if (end - p < 4) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+
+ if (end - p < (long int) session->ticket_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (session->ticket_len > 0) {
+ session->ticket = mbedtls_calloc(1, session->ticket_len);
+ if (session->ticket == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(session->ticket, p, session->ticket_len);
+ p += session->ticket_len;
+ }
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+ return 0;
+
+}
+#else /* MBEDTLS_SSL_SESSION_TICKETS */
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen)
+{
+ ((void) session);
+ ((void) buf);
+ ((void) buf_len);
+ *olen = 0;
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+}
+
+static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len)
+{
+ ((void) session);
+ ((void) buf);
+ ((void) buf_len);
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+}
+#endif /* !MBEDTLS_SSL_SESSION_TICKETS */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
/*
* Define ticket header determining Mbed TLS version
* and structure of the ticket.
@@ -3662,6 +4081,12 @@
#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0
#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 0
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1
#else
@@ -3686,12 +4111,42 @@
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+#define SSL_SERIALIZED_SESSION_CONFIG_SNI 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_SNI 0
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 0
+#endif /* MBEDTLS_SSL_EARLY_DATA */
+
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 0
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
+#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) && \
+ defined(MBEDTLS_SSL_EARLY_DATA)
+#define SSL_SERIALIZED_SESSION_CONFIG_ALPN 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_ALPN 0
+#endif /* MBEDTLS_SSL_ALPN */
+
#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0
#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5
+#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT 6
+#define SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT 7
+#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT 8
+#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT 9
+#define SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT 10
#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
((uint16_t) ( \
@@ -3701,7 +4156,16 @@
SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT) | \
(SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \
(SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \
- (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT)))
+ (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << \
+ SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_SNI << SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA << \
+ SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE << \
+ SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_ALPN << \
+ SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT)))
static const unsigned char ssl_serialized_session_header[] = {
MBEDTLS_VERSION_MAJOR,
@@ -3715,7 +4179,81 @@
* Serialize a session in the following format:
* (in the presentation language of TLS, RFC 8446 section 3)
*
- * struct {
+ * TLS 1.2 session:
+ *
+ * struct {
+ * #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ * opaque ticket<0..2^24-1>; // length 0 means no ticket
+ * uint32 ticket_lifetime;
+ * #endif
+ * } ClientOnlyData;
+ *
+ * struct {
+ * #if defined(MBEDTLS_HAVE_TIME)
+ * uint64 start_time;
+ * #endif
+ * uint8 session_id_len; // at most 32
+ * opaque session_id[32];
+ * opaque master[48]; // fixed length in the standard
+ * uint32 verify_result;
+ * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+ * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
+ * #else
+ * uint8 peer_cert_digest_type;
+ * opaque peer_cert_digest<0..2^8-1>
+ * #endif
+ * select (endpoint) {
+ * case client: ClientOnlyData;
+ * case server: uint64 ticket_creation_time;
+ * };
+ * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ * uint8 mfl_code; // up to 255 according to standard
+ * #endif
+ * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ * uint8 encrypt_then_mac; // 0 or 1
+ * #endif
+ * } serialized_session_tls12;
+ *
+ *
+ * TLS 1.3 Session:
+ *
+ * struct {
+ * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ * opaque hostname<0..2^16-1>;
+ * #endif
+ * #if defined(MBEDTLS_HAVE_TIME)
+ * uint64 ticket_reception_time;
+ * #endif
+ * uint32 ticket_lifetime;
+ * opaque ticket<1..2^16-1>;
+ * } ClientOnlyData;
+ *
+ * struct {
+ * uint32 ticket_age_add;
+ * uint8 ticket_flags;
+ * opaque resumption_key<0..255>;
+ * #if defined(MBEDTLS_SSL_EARLY_DATA)
+ * uint32 max_early_data_size;
+ * #endif
+ * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ * uint16 record_size_limit;
+ * #endif
+ * select ( endpoint ) {
+ * case client: ClientOnlyData;
+ * case server:
+ * #if defined(MBEDTLS_HAVE_TIME)
+ * uint64 ticket_creation_time;
+ * #endif
+ * #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ * opaque ticket_alpn<0..256>;
+ * #endif
+ * };
+ * } serialized_session_tls13;
+ *
+ *
+ * SSL session:
+ *
+ * struct {
*
* opaque mbedtls_version[3]; // library version: major, minor, patch
* opaque session_format[2]; // library-version specific 16-bit field
@@ -3733,6 +4271,8 @@
* uint8_t minor_ver; // Protocol minor version. Possible values:
* // - TLS 1.2 (0x0303)
* // - TLS 1.3 (0x0304)
+ * uint8_t endpoint;
+ * uint16_t ciphersuite;
*
* select (serialized_session.tls_version) {
*
@@ -4395,6 +4935,11 @@
mbedtls_free(session->ticket);
#endif
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && \
+ defined(MBEDTLS_SSL_SRV_C)
+ mbedtls_free(session->ticket_alpn);
+#endif
+
mbedtls_platform_zeroize(session, sizeof(mbedtls_ssl_session));
}
@@ -4893,7 +5438,7 @@
/* alpn_chosen should point to an item in the configured list */
for (cur = ssl->conf->alpn_list; *cur != NULL; cur++) {
if (strlen(*cur) == alpn_len &&
- memcmp(p, cur, alpn_len) == 0) {
+ memcmp(p, *cur, alpn_len) == 0) {
ssl->alpn_chosen = *cur;
break;
}
@@ -8948,385 +9493,6 @@
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-/* Serialization of TLS 1.2 sessions:
- *
- * struct {
- * opaque ticket<0..2^24-1>; // length 0 means no ticket
- * uint32 ticket_lifetime;
- * } ClientOnlyData;
- *
- * struct {
- * uint64 start_time;
- * uint8 session_id_len; // at most 32
- * opaque session_id[32];
- * opaque master[48]; // fixed length in the standard
- * uint32 verify_result;
- * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
- * select (endpoint) {
- * case client: ClientOnlyData;
- * case server: uint64 ticket_creation_time;
- * };
- * uint8 mfl_code; // up to 255 according to standard
- * uint8 encrypt_then_mac; // 0 or 1
- * } serialized_session_tls12;
- */
-static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len)
-{
- unsigned char *p = buf;
- size_t used = 0;
-
-#if defined(MBEDTLS_HAVE_TIME)
- uint64_t start;
-#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- size_t cert_len;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- /*
- * Time
- */
-#if defined(MBEDTLS_HAVE_TIME)
- used += 8;
-
- if (used <= buf_len) {
- start = (uint64_t) session->start;
-
- MBEDTLS_PUT_UINT64_BE(start, p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME */
-
- /*
- * Basic mandatory fields
- */
- used += 1 /* id_len */
- + sizeof(session->id)
- + sizeof(session->master)
- + 4; /* verify_result */
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_0(session->id_len);
- memcpy(p, session->id, 32);
- p += 32;
-
- memcpy(p, session->master, 48);
- p += 48;
-
- MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0);
- p += 4;
- }
-
- /*
- * Peer's end-entity certificate
- */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- if (session->peer_cert == NULL) {
- cert_len = 0;
- } else {
- cert_len = session->peer_cert->raw.len;
- }
-
- used += 3 + cert_len;
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_2(cert_len);
- *p++ = MBEDTLS_BYTE_1(cert_len);
- *p++ = MBEDTLS_BYTE_0(cert_len);
-
- if (session->peer_cert != NULL) {
- memcpy(p, session->peer_cert->raw.p, cert_len);
- p += cert_len;
- }
- }
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if (session->peer_cert_digest != NULL) {
- used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
- if (used <= buf_len) {
- *p++ = (unsigned char) session->peer_cert_digest_type;
- *p++ = (unsigned char) session->peer_cert_digest_len;
- memcpy(p, session->peer_cert_digest,
- session->peer_cert_digest_len);
- p += session->peer_cert_digest_len;
- }
- } else {
- used += 2;
- if (used <= buf_len) {
- *p++ = (unsigned char) MBEDTLS_MD_NONE;
- *p++ = 0;
- }
- }
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- /*
- * Session ticket if any, plus associated data
- */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
- used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_2(session->ticket_len);
- *p++ = MBEDTLS_BYTE_1(session->ticket_len);
- *p++ = MBEDTLS_BYTE_0(session->ticket_len);
-
- if (session->ticket != NULL) {
- memcpy(p, session->ticket, session->ticket_len);
- p += session->ticket_len;
- }
-
- MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
- p += 4;
- }
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
- if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- used += 8;
-
- if (used <= buf_len) {
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
- p += 8;
- }
- }
-#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
-#endif /* MBEDTLS_SSL_SESSION_TICKETS */
-
- /*
- * Misc extension-related info
- */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- used += 1;
-
- if (used <= buf_len) {
- *p++ = session->mfl_code;
- }
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- used += 1;
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac);
- }
-#endif
-
- return used;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls12_session_load(mbedtls_ssl_session *session,
- const unsigned char *buf,
- size_t len)
-{
-#if defined(MBEDTLS_HAVE_TIME)
- uint64_t start;
-#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- size_t cert_len;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- const unsigned char *p = buf;
- const unsigned char * const end = buf + len;
-
- /*
- * Time
- */
-#if defined(MBEDTLS_HAVE_TIME)
- if (8 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- start = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
-
- session->start = (time_t) start;
-#endif /* MBEDTLS_HAVE_TIME */
-
- /*
- * Basic mandatory fields
- */
- if (1 + 32 + 48 + 4 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->id_len = *p++;
- memcpy(session->id, p, 32);
- p += 32;
-
- memcpy(session->master, p, 48);
- p += 48;
-
- session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
-
- /* Immediately clear invalid pointer values that have been read, in case
- * we exit early before we replaced them with valid ones. */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- session->peer_cert = NULL;
-#else
- session->peer_cert_digest = NULL;
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
- session->ticket = NULL;
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
-
- /*
- * Peer certificate
- */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- /* Deserialize CRT from the end of the ticket. */
- if (3 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- cert_len = MBEDTLS_GET_UINT24_BE(p, 0);
- p += 3;
-
- if (cert_len != 0) {
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
- if (cert_len > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
-
- if (session->peer_cert == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
-
- mbedtls_x509_crt_init(session->peer_cert);
-
- if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert,
- p, cert_len)) != 0) {
- mbedtls_x509_crt_free(session->peer_cert);
- mbedtls_free(session->peer_cert);
- session->peer_cert = NULL;
- return ret;
- }
-
- p += cert_len;
- }
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- /* Deserialize CRT digest from the end of the ticket. */
- if (2 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
- session->peer_cert_digest_len = (size_t) *p++;
-
- if (session->peer_cert_digest_len != 0) {
- const mbedtls_md_info_t *md_info =
- mbedtls_md_info_from_type(session->peer_cert_digest_type);
- if (md_info == NULL) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- if (session->peer_cert_digest_len > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->peer_cert_digest =
- mbedtls_calloc(1, session->peer_cert_digest_len);
- if (session->peer_cert_digest == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
-
- memcpy(session->peer_cert_digest, p,
- session->peer_cert_digest_len);
- p += session->peer_cert_digest_len;
- }
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- /*
- * Session ticket and associated data
- */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
- if (3 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0);
- p += 3;
-
- if (session->ticket_len != 0) {
- if (session->ticket_len > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->ticket = mbedtls_calloc(1, session->ticket_len);
- if (session->ticket == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
-
- memcpy(session->ticket, p, session->ticket_len);
- p += session->ticket_len;
- }
-
- if (4 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
- if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- if (8 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
-#endif /* MBEDTLS_SSL_SESSION_TICKETS */
-
- /*
- * Misc extension-related info
- */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- if (1 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->mfl_code = *p++;
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if (1 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->encrypt_then_mac = *p++;
-#endif
-
- /* Done, should have consumed entire buffer */
- if (p != end) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- return 0;
-}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
int mbedtls_ssl_validate_ciphersuite(
@@ -9720,4 +9886,36 @@
MBEDTLS_SSL_SERVER_NAME_INDICATION &&
MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \
+ defined(MBEDTLS_SSL_ALPN)
+int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session,
+ const char *alpn)
+{
+ size_t alpn_len = 0;
+
+ if (alpn != NULL) {
+ alpn_len = strlen(alpn);
+
+ if (alpn_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ }
+
+ if (session->ticket_alpn != NULL) {
+ mbedtls_zeroize_and_free(session->ticket_alpn,
+ strlen(session->ticket_alpn));
+ session->ticket_alpn = NULL;
+ }
+
+ if (alpn != NULL) {
+ session->ticket_alpn = mbedtls_calloc(alpn_len + 1, 1);
+ if (session->ticket_alpn == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(session->ticket_alpn, alpn, alpn_len);
+ }
+
+ return 0;
+}
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 53a9ce2..b49a8ae 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -2178,11 +2178,6 @@
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- if (ssl->conf->f_rng == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
- return MBEDTLS_ERR_SSL_NO_RNG;
- }
-
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
@@ -2703,8 +2698,7 @@
PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
- key_len = PSA_BITS_TO_BYTES(key->grp.pbits);
- ret = mbedtls_ecp_write_key(key, buf, key_len);
+ ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf));
if (ret != 0) {
mbedtls_platform_zeroize(buf, sizeof(buf));
break;
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 1e8df1b..7fcc394 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -1180,7 +1180,15 @@
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (ssl->handshake->hello_retry_request_count == 0) {
+ /* In the first ClientHello, write the early data indication extension if
+ * necessary and update the early data state.
+ * If an HRR has been received and thus we are currently writing the
+ * second ClientHello, the second ClientHello must not contain an early
+ * data extension and the early data state must stay as it is:
+ * MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT or
+ * MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED.
+ */
+ if (!ssl->handshake->hello_retry_request_flag) {
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) {
@@ -1191,9 +1199,9 @@
}
p += ext_len;
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SENT;
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT;
} else {
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT;
}
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -1231,7 +1239,7 @@
size_t psk_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT) {
+ if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk"));
@@ -1294,7 +1302,7 @@
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
#endif
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -1495,7 +1503,7 @@
* to a HelloRetryRequest), it MUST abort the handshake with an
* "unexpected_message" alert.
*/
- if (handshake->hello_retry_request_count > 0) {
+ if (handshake->hello_retry_request_flag) {
MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
@@ -1517,7 +1525,7 @@
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
- handshake->hello_retry_request_count++;
+ handshake->hello_retry_request_flag = 1;
break;
}
@@ -1672,7 +1680,7 @@
* proposed in the HRR, we abort the handshake and send an
* "illegal_parameter" alert.
*/
- else if ((!is_hrr) && (handshake->hello_retry_request_count > 0) &&
+ else if ((!is_hrr) && handshake->hello_retry_request_flag &&
(cipher_suite != ssl->session_negotiate->ciphersuite)) {
fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
}
@@ -1911,7 +1919,7 @@
* cases we compute it here.
*/
#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT ||
+ if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT ||
handshake->key_exchange_mode ==
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
#endif
@@ -1967,8 +1975,8 @@
ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
+ if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
}
#endif
@@ -2230,9 +2238,10 @@
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
- } else if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED;
+ } else if (ssl->early_data_state !=
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
}
#endif
@@ -2270,6 +2279,7 @@
}
+#if defined(MBEDTLS_SSL_EARLY_DATA)
/*
* Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
*
@@ -2308,6 +2318,32 @@
return ret;
}
+int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl)
+{
+ if ((ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) ||
+ (!mbedtls_ssl_is_handshake_over(ssl))) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ switch (ssl->early_data_state) {
+ case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT:
+ return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED;
+ break;
+
+ case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED:
+ return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
+ break;
+
+ case MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED:
+ return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
+ break;
+
+ default:
+ return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ }
+}
+#endif /* MBEDTLS_SSL_EARLY_DATA */
+
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
/*
* STATE HANDLING: CertificateRequest
@@ -2569,8 +2605,8 @@
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED;
+ if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED) {
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
} else
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -2881,12 +2917,17 @@
return ret;
}
- /* session has been updated, allow export */
- session->exported = 0;
-
return 0;
}
+/* Non negative return values for ssl_tls13_postprocess_new_session_ticket().
+ * - POSTPROCESS_NEW_SESSION_TICKET_SIGNAL, all good, we have to signal the
+ * application that a valid ticket has been received.
+ * - POSTPROCESS_NEW_SESSION_TICKET_DISCARD, no fatal error, we keep the
+ * connection alive but we do not signal the ticket to the application.
+ */
+#define POSTPROCESS_NEW_SESSION_TICKET_SIGNAL 0
+#define POSTPROCESS_NEW_SESSION_TICKET_DISCARD 1
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl,
unsigned char *ticket_nonce,
@@ -2898,6 +2939,10 @@
psa_algorithm_t psa_hash_alg;
int hash_length;
+ if (session->ticket_lifetime == 0) {
+ return POSTPROCESS_NEW_SESSION_TICKET_DISCARD;
+ }
+
#if defined(MBEDTLS_HAVE_TIME)
/* Store ticket creation time */
session->ticket_reception_time = mbedtls_ms_time();
@@ -2954,7 +2999,7 @@
session, ssl->conf->tls13_kex_modes);
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
- return 0;
+ return POSTPROCESS_NEW_SESSION_TICKET_SIGNAL;
}
/*
@@ -2975,12 +3020,37 @@
ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
&buf, &buf_len));
+ /*
+ * We are about to update (maybe only partially) ticket data thus block
+ * any session export for the time being.
+ */
+ ssl->session->exported = 1;
+
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_new_session_ticket(
ssl, buf, buf + buf_len,
&ticket_nonce, &ticket_nonce_len));
- MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_new_session_ticket(
- ssl, ticket_nonce, ticket_nonce_len));
+ MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_postprocess_new_session_ticket(
+ ssl, ticket_nonce, ticket_nonce_len));
+
+ switch (ret) {
+ case POSTPROCESS_NEW_SESSION_TICKET_SIGNAL:
+ /*
+ * All good, we have received a new valid ticket, session data can
+ * be exported now and we signal the ticket to the application.
+ */
+ ssl->session->exported = 0;
+ ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET;
+ break;
+
+ case POSTPROCESS_NEW_SESSION_TICKET_DISCARD:
+ ret = 0;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("Discard new session ticket"));
+ break;
+
+ default:
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ }
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
@@ -3030,9 +3100,11 @@
ret = ssl_tls13_process_server_finished(ssl);
break;
+#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_SSL_END_OF_EARLY_DATA:
ret = ssl_tls13_write_end_of_early_data(ssl);
break;
+#endif
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
ret = ssl_tls13_write_client_certificate(ssl);
@@ -3061,23 +3133,17 @@
*/
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
- ret = 0;
- if (ssl->handshake->ccs_count == 0) {
- ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
- if (ret != 0) {
- break;
- }
+ ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
+ if (ret != 0) {
+ break;
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
break;
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
- ret = 0;
- if (ssl->handshake->ccs_count == 0) {
- ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
- if (ret != 0) {
- break;
- }
+ ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
+ if (ret != 0) {
+ break;
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
break;
@@ -3092,7 +3158,7 @@
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
- ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
+ ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -3101,10 +3167,6 @@
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET:
ret = ssl_tls13_process_new_session_ticket(ssl);
- if (ret != 0) {
- break;
- }
- ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET;
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 064f616..d448a05 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -1379,6 +1379,12 @@
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
+ /* Only one CCS to send. */
+ if (ssl->handshake->ccs_sent) {
+ ret = 0;
+ goto cleanup;
+ }
+
/* Write CCS message */
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_change_cipher_spec_body(
ssl, ssl->out_msg,
@@ -1390,7 +1396,7 @@
/* Dispatch message */
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_record(ssl, 0));
- ssl->handshake->ccs_count++;
+ ssl->handshake->ccs_sent = 1;
cleanup:
@@ -1448,6 +1454,54 @@
return 0;
}
+
+#if defined(MBEDTLS_SSL_SRV_C)
+int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
+ size_t early_data_len)
+{
+ /*
+ * This function should be called only while an handshake is in progress
+ * and thus a session under negotiation. Add a sanity check to detect a
+ * misuse.
+ */
+ if (ssl->session_negotiate == NULL) {
+ return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ }
+
+ /* RFC 8446 section 4.6.1
+ *
+ * A server receiving more than max_early_data_size bytes of 0-RTT data
+ * SHOULD terminate the connection with an "unexpected_message" alert.
+ * Note that if it is still possible to send early_data_len bytes of early
+ * data, it means that early_data_len is smaller than max_early_data_size
+ * (type uint32_t) and can fit in an uint32_t. We use this further
+ * down.
+ */
+ if (early_data_len >
+ (ssl->session_negotiate->max_early_data_size -
+ ssl->total_early_data_size)) {
+
+ MBEDTLS_SSL_DEBUG_MSG(
+ 2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u",
+ ssl->total_early_data_size, early_data_len,
+ ssl->session_negotiate->max_early_data_size));
+
+ MBEDTLS_SSL_PEND_FATAL_ALERT(
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
+ MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
+ return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+ }
+
+ /*
+ * early_data_len has been checked to be less than max_early_data_size
+ * that is uint32_t. Its cast to an uint32_t below is thus safe. We need
+ * the cast to appease some compilers.
+ */
+ ssl->total_early_data_size += (uint32_t) early_data_len;
+
+ return 0;
+}
+#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Reset SSL context and update hash for handling HRR.
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 1411446..e8afe45 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -39,6 +39,63 @@
return ciphersuite_info;
}
+static void ssl_tls13_select_ciphersuite(
+ mbedtls_ssl_context *ssl,
+ const unsigned char *cipher_suites,
+ const unsigned char *cipher_suites_end,
+ int psk_ciphersuite_id,
+ psa_algorithm_t psk_hash_alg,
+ const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
+{
+ *selected_ciphersuite_info = NULL;
+
+ /*
+ * In a compliant ClientHello the byte-length of the list of ciphersuites
+ * is even and this function relies on this fact. This should have been
+ * checked in the main ClientHello parsing function. Double check here.
+ */
+ if ((cipher_suites_end - cipher_suites) & 1) {
+ return;
+ }
+
+ for (const unsigned char *p = cipher_suites;
+ p < cipher_suites_end; p += 2) {
+ /*
+ * "cipher_suites_end - p is even" is an invariant of the loop. As
+ * cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and it
+ * is thus safe to read two bytes.
+ */
+ uint16_t id = MBEDTLS_GET_UINT16_BE(p, 0);
+
+ const mbedtls_ssl_ciphersuite_t *info =
+ ssl_tls13_validate_peer_ciphersuite(ssl, id);
+ if (info == NULL) {
+ continue;
+ }
+
+ /*
+ * If a valid PSK ciphersuite identifier has been passed in, we want
+ * an exact match.
+ */
+ if (psk_ciphersuite_id != 0) {
+ if (id != psk_ciphersuite_id) {
+ continue;
+ }
+ } else if (psk_hash_alg != PSA_ALG_NONE) {
+ if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac) !=
+ psk_hash_alg) {
+ continue;
+ }
+ }
+
+ *selected_ciphersuite_info = info;
+ return;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%x",
+ (unsigned) psk_ciphersuite_id, psk_hash_alg));
+}
+
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* From RFC 8446:
*
@@ -90,8 +147,30 @@
return 0;
}
-#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 1
-#define SSL_TLS1_3_OFFERED_PSK_MATCH 0
+/*
+ * Non-error return values of
+ * ssl_tls13_offered_psks_check_identity_match_ticket() and
+ * ssl_tls13_offered_psks_check_identity_match(). They are positive to
+ * not collide with error codes that are negative. Zero
+ * (SSL_TLS1_3_PSK_IDENTITY_MATCH) in case of success as it may be propagated
+ * up by the callers of this function as a generic success condition.
+ *
+ * The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means
+ * that the pre-shared-key identity matches that of a ticket or an externally-
+ * provisioned pre-shared-key. We have thus been able to retrieve the
+ * attributes of the pre-shared-key but at least one of them does not meet
+ * some criteria and the pre-shared-key cannot be used. For example, a ticket
+ * is expired or its version is not TLS 1.3. Note eventually that the return
+ * value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE does not have
+ * anything to do with binder check. A binder check is done only when a
+ * suitable pre-shared-key has been selected and only for that selected
+ * pre-shared-key: if the binder check fails, we fail the handshake and we do
+ * not try to find another pre-shared-key for which the binder check would
+ * succeed as recommended by the specification.
+ */
+#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH 2
+#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1
+#define SSL_TLS1_3_PSK_IDENTITY_MATCH 0
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
@@ -109,7 +188,6 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *ticket_buffer;
- unsigned int key_exchanges;
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_ms_time_t now;
mbedtls_ms_time_t server_age;
@@ -123,7 +201,7 @@
/* Ticket parser is not configured, Skip */
if (ssl->conf->f_ticket_parse == NULL || identity_len == 0) {
- return 0;
+ return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
/* We create a copy of the encrypted ticket since the ticket parsing
@@ -133,63 +211,51 @@
*/
ticket_buffer = mbedtls_calloc(1, identity_len);
if (ticket_buffer == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
memcpy(ticket_buffer, identity, identity_len);
- if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket,
- session,
- ticket_buffer, identity_len)) != 0) {
- if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
- } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) {
+ ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket,
+ session,
+ ticket_buffer, identity_len);
+ switch (ret) {
+ case 0:
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH;
+ break;
+
+ case MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED:
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired"));
- } else {
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
+ break;
+
+ case MBEDTLS_ERR_SSL_INVALID_MAC:
+ MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
+ ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
+ break;
+
+ default:
MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret);
- }
+ ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
/* We delete the temporary buffer */
mbedtls_free(ticket_buffer);
- if (ret == 0 && session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
- /* TODO: Define new return value for this case. */
- ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
- }
-
- if (ret != 0) {
+ if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
goto exit;
}
- /* RFC 8446 section 4.2.9
- *
- * Servers SHOULD NOT send NewSessionTicket with tickets that are not
- * compatible with the advertised modes; however, if a server does so,
- * the impact will just be that the client's attempts at resumption fail.
- *
- * We regard the ticket with incompatible key exchange modes as not match.
+ /*
+ * The identity matches that of a ticket. Now check that it has suitable
+ * attributes and bet it will not be the case.
*/
- ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR;
- MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
- key_exchanges = 0;
- 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_tls13_session_ticket_allow_psk(session) &&
- ssl_tls13_key_exchange_is_psk_available(ssl)) {
- key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
- }
-
- if (key_exchanges == 0) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode"));
+ if (session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
goto exit;
}
- ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
#if defined(MBEDTLS_HAVE_TIME)
now = mbedtls_ms_time();
@@ -242,13 +308,15 @@
age_diff));
goto exit;
}
-
- ret = 0;
-
#endif /* MBEDTLS_HAVE_TIME */
+ /*
+ * All good, we have found a suitable ticket.
+ */
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH;
+
exit:
- if (ret != 0) {
+ if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
mbedtls_ssl_session_free(session);
}
@@ -273,13 +341,11 @@
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
MBEDTLS_SSL_DEBUG_BUF(4, "identity", identity, identity_len);
- ssl->handshake->resume = 0;
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if (ssl_tls13_offered_psks_check_identity_match_ticket(
- ssl, identity, identity_len, obfuscated_ticket_age,
- session) == SSL_TLS1_3_OFFERED_PSK_MATCH) {
- ssl->handshake->resume = 1;
+ ret = ssl_tls13_offered_psks_check_identity_match_ticket(
+ ssl, identity, identity_len, obfuscated_ticket_age, session);
+ if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH) {
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION;
ret = mbedtls_ssl_set_hs_psk(ssl,
session->resumption_key,
@@ -294,7 +360,9 @@
session->resumption_key_len);
MBEDTLS_SSL_DEBUG_MSG(4, ("ticket: obfuscated_ticket_age: %u",
(unsigned) obfuscated_ticket_age));
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH;
+ } else if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE) {
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
@@ -302,9 +370,9 @@
if (ssl->conf->f_psk != NULL) {
if (ssl->conf->f_psk(
ssl->conf->p_psk, ssl, identity, identity_len) == 0) {
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH;
}
- return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
MBEDTLS_SSL_DEBUG_BUF(5, "identity", identity, identity_len);
@@ -318,12 +386,20 @@
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
return ret;
}
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH;
}
- return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
+/*
+ * Non-error return values of ssl_tls13_offered_psks_check_binder_match().
+ * They are positive to not collide with error codes that are negative. Zero
+ * (SSL_TLS1_3_BINDER_MATCH) in case of success as it may be propagated up
+ * by the callers of this function as a generic success condition.
+ */
+#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1
+#define SSL_TLS1_3_BINDER_MATCH 0
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_binder_match(
mbedtls_ssl_context *ssl,
@@ -368,100 +444,16 @@
MBEDTLS_SSL_DEBUG_BUF(3, "psk binder ( received ): ", binder, binder_len);
if (mbedtls_ct_memcmp(server_computed_binder, binder, binder_len) == 0) {
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_BINDER_MATCH;
}
mbedtls_platform_zeroize(server_computed_binder,
sizeof(server_computed_binder));
- return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_select_ciphersuite_for_psk(
- mbedtls_ssl_context *ssl,
- const unsigned char *cipher_suites,
- const unsigned char *cipher_suites_end,
- uint16_t *selected_ciphersuite,
- const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
-{
- psa_algorithm_t psk_hash_alg = PSA_ALG_SHA_256;
-
- *selected_ciphersuite = 0;
- *selected_ciphersuite_info = NULL;
-
- /* RFC 8446, page 55.
- *
- * For externally established PSKs, the Hash algorithm MUST be set when the
- * PSK is established or default to SHA-256 if no such algorithm is defined.
- *
- */
-
- /*
- * Search for a matching ciphersuite
- */
- for (const unsigned char *p = cipher_suites;
- p < cipher_suites_end; p += 2) {
- uint16_t cipher_suite;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
-
- cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
- ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl,
- cipher_suite);
- if (ciphersuite_info == NULL) {
- continue;
- }
-
- /* MAC of selected ciphersuite MUST be same with PSK binder if exist.
- * Otherwise, client should reject.
- */
- if (psk_hash_alg ==
- mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)) {
- *selected_ciphersuite = cipher_suite;
- *selected_ciphersuite_info = ciphersuite_info;
- return 0;
- }
- }
- MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite"));
- return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
+ return SSL_TLS1_3_BINDER_DOES_NOT_MATCH;
}
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_select_ciphersuite_for_resumption(
- mbedtls_ssl_context *ssl,
- const unsigned char *cipher_suites,
- const unsigned char *cipher_suites_end,
- mbedtls_ssl_session *session,
- uint16_t *selected_ciphersuite,
- const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
-{
-
- *selected_ciphersuite = 0;
- *selected_ciphersuite_info = NULL;
- for (const unsigned char *p = cipher_suites; p < cipher_suites_end; p += 2) {
- uint16_t cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
-
- if (cipher_suite != session->ciphersuite) {
- continue;
- }
-
- ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl,
- cipher_suite);
- if (ciphersuite_info == NULL) {
- continue;
- }
-
- *selected_ciphersuite = cipher_suite;
- *selected_ciphersuite_info = ciphersuite_info;
-
- return 0;
- }
-
- return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
const mbedtls_ssl_session *src)
{
@@ -475,12 +467,26 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
dst->max_early_data_size = src->max_early_data_size;
-#endif
+
+#if defined(MBEDTLS_SSL_ALPN)
+ int ret = mbedtls_ssl_session_set_ticket_alpn(dst, src->ticket_alpn);
+ if (ret != 0) {
+ return ret;
+ }
+#endif /* MBEDTLS_SSL_ALPN */
+#endif /* MBEDTLS_SSL_EARLY_DATA*/
return 0;
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+struct psk_attributes {
+ int type;
+ int key_exchange_mode;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+};
+#define PSK_ATTRIBUTES_INIT { 0, 0, NULL }
+
/* Parser for pre_shared_key extension in client hello
* struct {
* opaque identity<1..2^16-1>;
@@ -507,7 +513,8 @@
const unsigned char *pre_shared_key_ext,
const unsigned char *pre_shared_key_ext_end,
const unsigned char *ciphersuites,
- const unsigned char *ciphersuites_end)
+ const unsigned char *ciphersuites_end,
+ struct psk_attributes *psk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *identities = pre_shared_key_ext;
@@ -558,9 +565,10 @@
uint32_t obfuscated_ticket_age;
const unsigned char *binder;
size_t binder_len;
- int psk_type;
- uint16_t cipher_suite;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+ int psk_ciphersuite_id;
+ psa_algorithm_t psk_hash_alg;
+ int allowed_key_exchange_modes;
+
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
mbedtls_ssl_session session;
mbedtls_ssl_session_init(&session);
@@ -586,47 +594,74 @@
ret = ssl_tls13_offered_psks_check_identity_match(
ssl, identity, identity_len, obfuscated_ticket_age,
- &psk_type, &session);
- if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
+ &psk->type, &session);
+ if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
continue;
}
MBEDTLS_SSL_DEBUG_MSG(4, ("found matched identity"));
- switch (psk_type) {
+
+ switch (psk->type) {
case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL:
- ret = ssl_tls13_select_ciphersuite_for_psk(
- ssl, ciphersuites, ciphersuites_end,
- &cipher_suite, &ciphersuite_info);
+ psk_ciphersuite_id = 0;
+ psk_hash_alg = PSA_ALG_SHA_256;
+ allowed_key_exchange_modes =
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
break;
- case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ret = ssl_tls13_select_ciphersuite_for_resumption(
- ssl, ciphersuites, ciphersuites_end, &session,
- &cipher_suite, &ciphersuite_info);
- if (ret != 0) {
- mbedtls_ssl_session_free(&session);
- }
-#else
- ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-#endif
+ case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
+ psk_ciphersuite_id = session.ciphersuite;
+ psk_hash_alg = PSA_ALG_NONE;
+ ssl->session_negotiate->ticket_flags = session.ticket_flags;
+ allowed_key_exchange_modes =
+ session.ticket_flags &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
break;
+#endif
default:
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
- if (ret != 0) {
- /* See below, no cipher_suite available, abort handshake */
+
+ psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
+
+ if ((allowed_key_exchange_modes &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
+ ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
+ psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+ } else if ((allowed_key_exchange_modes &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
+ ssl_tls13_key_exchange_is_psk_available(ssl)) {
+ psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+ }
+
+ if (psk->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable PSK key exchange mode"));
+ continue;
+ }
+
+ ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end,
+ psk_ciphersuite_id, psk_hash_alg,
+ &psk->ciphersuite_info);
+
+ if (psk->ciphersuite_info == NULL) {
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ mbedtls_ssl_session_free(&session);
+#endif
+ /*
+ * We consider finding a ciphersuite suitable for the PSK as part
+ * of the validation of its binder. Thus if we do not find one, we
+ * abort the handshake with a decrypt_error alert.
+ */
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
- MBEDTLS_SSL_DEBUG_RET(
- 2, "ssl_tls13_select_ciphersuite", ret);
- return ret;
+ return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
ret = ssl_tls13_offered_psks_check_binder_match(
- ssl, binder, binder_len, psk_type,
- mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac));
- if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
+ ssl, binder, binder_len, psk->type,
+ mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) psk->ciphersuite_info->mac));
+ if (ret != SSL_TLS1_3_BINDER_MATCH) {
/* For security reasons, the handshake should be aborted when we
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
* and appendix E.6. */
@@ -644,13 +679,8 @@
matched_identity = identity_id;
- /* Update handshake parameters */
- ssl->handshake->ciphersuite_info = ciphersuite_info;
- ssl->session_negotiate->ciphersuite = cipher_suite;
- MBEDTLS_SSL_DEBUG_MSG(2, ("overwrite ciphersuite: %04x - %s",
- cipher_suite, ciphersuite_info->name));
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
+ if (psk->type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate,
&session);
mbedtls_ssl_session_free(&session);
@@ -676,7 +706,7 @@
return ret;
}
if (matched_identity == -1) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("No matched PSK or ticket."));
+ MBEDTLS_SSL_DEBUG_MSG(3, ("No usable PSK or ticket."));
return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
}
@@ -1003,21 +1033,29 @@
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_ticket_is_kex_mode_permitted(mbedtls_ssl_context *ssl,
- unsigned int kex_mode)
+static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
{
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if (ssl->handshake->resume) {
- if (!mbedtls_ssl_tls13_session_ticket_has_flags(
- ssl->session_negotiate, kex_mode)) {
- return 0;
- }
- }
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
+ return 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);
- ((void) kex_mode);
+ return 0;
#endif
- return 1;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+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 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);
+ return 0;
+#endif
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
@@ -1033,83 +1071,6 @@
#endif
}
-MBEDTLS_CHECK_RETURN_CRITICAL
-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_is_kex_mode_permitted(
- ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
- 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);
- return 0;
-#endif
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-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_is_kex_mode_permitted(
- ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
- 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);
- return 0;
-#endif
-}
-
-static int ssl_tls13_determine_key_exchange_mode(mbedtls_ssl_context *ssl)
-{
- /*
- * Determine the key exchange algorithm to use.
- * There are three types of key exchanges supported in TLS 1.3:
- * - (EC)DH with ECDSA,
- * - (EC)DH with PSK,
- * - plain PSK.
- *
- * The PSK-based key exchanges may additionally be used with 0-RTT.
- *
- * Our built-in order of preference is
- * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral )
- * 2 ) Certificate Mode ( ephemeral )
- * 3 ) Plain PSK Mode ( psk )
- */
-
- ssl->handshake->key_exchange_mode =
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
-
- 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_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_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"));
- } else {
- MBEDTLS_SSL_DEBUG_MSG(
- 1,
- ("ClientHello message misses mandatory extensions."));
- MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION,
- MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
- return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
- }
-
- return 0;
-
-}
-
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
@@ -1301,6 +1262,8 @@
int no_usable_share_for_key_agreement = 0;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ int got_psk = 0;
+ struct psk_attributes psk = PSK_ATTRIBUTES_INIT;
const unsigned char *pre_shared_key_ext = NULL;
const unsigned char *pre_shared_key_ext_end = NULL;
#endif
@@ -1464,37 +1427,20 @@
*/
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, list of cipher suites",
cipher_suites, cipher_suites_len);
- for (const unsigned char *cipher_suites_p = cipher_suites;
- cipher_suites_p < cipher_suites_end; cipher_suites_p += 2) {
- uint16_t cipher_suite;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- /*
- * "cipher_suites_end - cipher_suites_p is even" is an invariant of the
- * loop. As cipher_suites_end - cipher_suites_p > 0, we have
- * cipher_suites_end - cipher_suites_p >= 2 and it is thus safe to read
- * two bytes.
- */
- cipher_suite = MBEDTLS_GET_UINT16_BE(cipher_suites_p, 0);
- ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(
- ssl, cipher_suite);
- if (ciphersuite_info == NULL) {
- continue;
- }
-
- ssl->session_negotiate->ciphersuite = cipher_suite;
- handshake->ciphersuite_info = ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
- cipher_suite,
- ciphersuite_info->name));
- break;
- }
+ ssl_tls13_select_ciphersuite(ssl, cipher_suites, cipher_suites_end,
+ 0, PSA_ALG_NONE, &handshake->ciphersuite_info);
if (handshake->ciphersuite_info == NULL) {
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
+ ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
+ ((unsigned) handshake->ciphersuite_info->id),
+ handshake->ciphersuite_info->name));
/* ...
* opaque legacy_compression_methods<1..2^8-1>;
@@ -1531,7 +1477,7 @@
const unsigned char *extension_data_end;
uint32_t allowed_exts = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH;
- if (ssl->handshake->hello_retry_request_count > 0) {
+ if (ssl->handshake->hello_retry_request_flag) {
/* Do not accept early data extension in 2nd ClientHello */
allowed_exts &= ~MBEDTLS_SSL_EXT_MASK(EARLY_DATA);
}
@@ -1734,10 +1680,11 @@
/* Update checksum with either
* - The entire content of the CH message, if no PSK extension is present
* - The content up to but excluding the PSK extension, if present.
+ * Always parse the pre-shared-key extension when present in the
+ * ClientHello even if some pre-requisites for PSK key exchange modes are
+ * not met. That way we always validate the syntax of the extension.
*/
- /* If we've settled on a PSK-based exchange, parse PSK identity ext */
- if (ssl_tls13_key_exchange_is_psk_available(ssl) ||
- ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
+ if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY)) {
ret = handshake->update_checksum(ssl, buf,
pre_shared_key_ext - buf);
if (0 != ret) {
@@ -1748,10 +1695,11 @@
pre_shared_key_ext,
pre_shared_key_ext_end,
cipher_suites,
- cipher_suites_end);
- if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
- handshake->received_extensions &= ~MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY);
- } else if (ret != 0) {
+ cipher_suites_end,
+ &psk);
+ if (ret == 0) {
+ got_psk = 1;
+ } else if (ret != MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
MBEDTLS_SSL_DEBUG_RET(
1, "ssl_tls13_parse_pre_shared_key_ext", ret);
return ret;
@@ -1766,12 +1714,68 @@
}
}
- ret = ssl_tls13_determine_key_exchange_mode(ssl);
- if (ret < 0) {
- return ret;
+ /*
+ * Determine the key exchange algorithm to use.
+ * There are three types of key exchanges supported in TLS 1.3:
+ * - (EC)DH with ECDSA,
+ * - (EC)DH with PSK,
+ * - plain PSK.
+ *
+ * The PSK-based key exchanges may additionally be used with 0-RTT.
+ *
+ * Our built-in order of preference is
+ * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral )
+ * 2 ) Certificate Mode ( ephemeral )
+ * 3 ) Plain PSK Mode ( psk )
+ */
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ if (got_psk && (psk.key_exchange_mode ==
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL)) {
+ handshake->key_exchange_mode =
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral"));
+
+ } else
+#endif
+ if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) {
+ handshake->key_exchange_mode =
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral"));
+
+ }
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ else if (got_psk && (psk.key_exchange_mode ==
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK)) {
+ handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk"));
+ }
+#endif
+ else {
+ MBEDTLS_SSL_DEBUG_MSG(
+ 1,
+ ("ClientHello message misses mandatory extensions."));
+ MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION,
+ MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
+ return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
- if (ssl->handshake->key_exchange_mode !=
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ if (handshake->key_exchange_mode &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) {
+ handshake->ciphersuite_info = psk.ciphersuite_info;
+ ssl->session_negotiate->ciphersuite = psk.ciphersuite_info->id;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("Select PSK ciphersuite: %04x - %s",
+ ((unsigned) psk.ciphersuite_info->id),
+ psk.ciphersuite_info->name));
+
+ if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
+ handshake->resume = 1;
+ }
+ }
+#endif
+
+ if (handshake->key_exchange_mode !=
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) {
hrr_required = (no_usable_share_for_key_agreement != 0);
}
@@ -1815,7 +1819,6 @@
* NOTE:
* - The TLS version number is checked in
* ssl_tls13_offered_psks_check_identity_match_ticket().
- * - ALPN is not checked for the time being (TODO).
*/
if (handshake->selected_identity != 0) {
@@ -1842,6 +1845,28 @@
return -1;
}
+#if defined(MBEDTLS_SSL_ALPN)
+ const char *alpn = mbedtls_ssl_get_alpn_protocol(ssl);
+ size_t alpn_len;
+
+ if (alpn == NULL && ssl->session_negotiate->ticket_alpn == NULL) {
+ return 0;
+ }
+
+ if (alpn != NULL) {
+ alpn_len = strlen(alpn);
+ }
+
+ if (alpn == NULL ||
+ ssl->session_negotiate->ticket_alpn == NULL ||
+ alpn_len != strlen(ssl->session_negotiate->ticket_alpn) ||
+ (memcmp(alpn, ssl->session_negotiate->ticket_alpn, alpn_len) != 0)) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, the selected ALPN is different "
+ "from the one associated with the pre-shared key."));
+ return -1;
+ }
+#endif
+
return 0;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -1973,10 +1998,6 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *server_randbytes =
ssl->handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
- if (ssl->conf->f_rng == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
- return MBEDTLS_ERR_SSL_NO_RNG;
- }
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, server_randbytes,
MBEDTLS_SERVER_HELLO_RANDOM_LEN)) != 0) {
@@ -2427,7 +2448,7 @@
static int ssl_tls13_prepare_hello_retry_request(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if (ssl->handshake->hello_retry_request_count > 0) {
+ if (ssl->handshake->hello_retry_request_flag) {
MBEDTLS_SSL_DEBUG_MSG(1, ("Too many HRRs"));
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
@@ -2474,7 +2495,7 @@
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, buf_len,
msg_len));
- ssl->handshake->hello_retry_request_count++;
+ ssl->handshake->hello_retry_request_flag = 1;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
/* The server sends a dummy change_cipher_spec record immediately
@@ -2913,17 +2934,14 @@
}
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
- /* RFC 8446 section 4.6.1
- *
- * A server receiving more than max_early_data_size bytes of 0-RTT data
- * SHOULD terminate the connection with an "unexpected_message" alert.
- *
- * TODO: Add received data size check here.
- */
if (ssl->in_offt == NULL) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
+ ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen);
+ if (ret != 0) {
+ return ret;
+ }
}
return SSL_GOT_EARLY_DATA;
}
@@ -3141,11 +3159,21 @@
ssl->conf->max_early_data_size > 0) {
mbedtls_ssl_tls13_session_set_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
+ session->max_early_data_size = ssl->conf->max_early_data_size;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ if (session->ticket_alpn == NULL) {
+ ret = mbedtls_ssl_session_set_ticket_alpn(session, ssl->alpn_chosen);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+#endif
+
/* Generate ticket_age_add */
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng,
(unsigned char *) &session->ticket_age_add,
@@ -3275,20 +3303,21 @@
MBEDTLS_SSL_DEBUG_RET(1, "write_ticket", ret);
return ret;
}
- /* RFC 8446 4.6.1
+
+ /* RFC 8446 section 4.6.1
+ *
* ticket_lifetime: Indicates the lifetime in seconds as a 32-bit
- * unsigned integer in network byte order from the time of ticket
- * issuance. Servers MUST NOT use any value greater than
- * 604800 seconds (7 days). The value of zero indicates that the
- * ticket should be discarded immediately. Clients MUST NOT cache
- * tickets for longer than 7 days, regardless of the ticket_lifetime,
- * and MAY delete tickets earlier based on local policy. A server
- * MAY treat a ticket as valid for a shorter period of time than what
- * is stated in the ticket_lifetime.
+ * unsigned integer in network byte order from the time of ticket
+ * issuance. Servers MUST NOT use any value greater than
+ * 604800 seconds (7 days) ...
*/
if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
- ticket_lifetime = MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME;
+ MBEDTLS_SSL_DEBUG_MSG(
+ 1, ("Ticket lifetime (%u) is greater than 7 days.",
+ (unsigned int) ticket_lifetime));
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
+
MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0);
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u",
(unsigned int) ticket_lifetime));
@@ -3477,12 +3506,9 @@
break;
case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO:
- ret = 0;
- if (ssl->handshake->ccs_count == 0) {
- ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
- if (ret != 0) {
- break;
- }
+ ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
+ if (ret != 0) {
+ break;
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
break;
diff --git a/library/threading.c b/library/threading.c
index c28290f..85db243 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -150,6 +150,8 @@
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex);
+ mbedtls_mutex_init(&mbedtls_threading_psa_globaldata_mutex);
+ mbedtls_mutex_init(&mbedtls_threading_psa_rngdata_mutex);
#endif
}
@@ -166,6 +168,8 @@
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_mutex_free(&mbedtls_threading_key_slot_mutex);
+ mbedtls_mutex_free(&mbedtls_threading_psa_globaldata_mutex);
+ mbedtls_mutex_free(&mbedtls_threading_psa_rngdata_mutex);
#endif
}
#endif /* MBEDTLS_THREADING_ALT */
@@ -184,6 +188,8 @@
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex MUTEX_INIT;
+mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex MUTEX_INIT;
+mbedtls_threading_mutex_t mbedtls_threading_psa_rngdata_mutex MUTEX_INIT;
#endif
#endif /* MBEDTLS_THREADING_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 7f0160a..2fd56fb 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -3290,4 +3290,12 @@
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt)
+{
+ if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) {
+ return crt->MBEDTLS_PRIVATE(ca_istrue);
+ }
+ return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
+}
+
#endif /* MBEDTLS_X509_CRT_PARSE_C */
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 05bb2ff..43133d9 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -52,7 +52,7 @@
#define DFL_KEY_OPAQUE 0
#define DFL_KEY_PWD ""
#define DFL_PSK ""
-#define DFL_EARLY_DATA ""
+#define DFL_EARLY_DATA -1
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
@@ -347,9 +347,8 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \
- " early_data=%%s The file path to read early data from\n" \
- " default: \"\" (do nothing)\n" \
- " option: a file path\n"
+ " early_data=%%d default: library default\n" \
+ " options: 0 (disabled), 1 (enabled)\n"
#else
#define USAGE_EARLY_DATA ""
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_PROTO_TLS1_3 */
@@ -544,7 +543,7 @@
int reproducible; /* make communication reproducible */
int skip_close_notify; /* skip sending the close_notify alert */
#if defined(MBEDTLS_SSL_EARLY_DATA)
- const char *early_data; /* the path of the file to read early data from */
+ int early_data; /* early data enablement flag */
#endif
int query_config_mode; /* whether to read config */
int use_srtp; /* Support SRTP */
@@ -717,9 +716,64 @@
return ret;
}
+/*
+ * Build HTTP request
+ */
+static int build_http_request(unsigned char *buf, size_t buf_size, size_t *request_len)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len, tail_len, request_size;
+
+ ret = mbedtls_snprintf((char *) buf, buf_size, GET_REQUEST, opt.request_page);
+ if (ret < 0) {
+ return ret;
+ }
+
+ len = (size_t) ret;
+ tail_len = strlen(GET_REQUEST_END);
+ if (opt.request_size != DFL_REQUEST_SIZE) {
+ request_size = (size_t) opt.request_size;
+ } else {
+ request_size = len + tail_len;
+ }
+
+ if (request_size > buf_size) {
+ return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+ }
+
+ /* Add padding to GET request to reach opt.request_size in length */
+ if (opt.request_size != DFL_REQUEST_SIZE &&
+ len + tail_len < request_size) {
+ memset(buf + len, 'A', request_size - len - tail_len);
+ len = request_size - tail_len;
+ }
+
+ strncpy((char *) buf + len, GET_REQUEST_END, buf_size - len);
+ len += tail_len;
+
+ /* Truncate if request size is smaller than the "natural" size */
+ if (opt.request_size != DFL_REQUEST_SIZE &&
+ len > request_size) {
+ len = request_size;
+
+ /* Still end with \r\n unless that's really not possible */
+ if (len >= 2) {
+ buf[len - 2] = '\r';
+ }
+ if (len >= 1) {
+ buf[len - 1] = '\n';
+ }
+ }
+
+ *request_len = len;
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
- int ret = 0, len, tail_len, i, written, frags, retry_left;
+ int ret = 0, i;
+ size_t len, written, frags, retry_left;
int query_config_ret = 0;
mbedtls_net_context server_fd;
io_ctx_t io_ctx;
@@ -742,10 +796,6 @@
size_t cid_renego_len = 0;
#endif
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- FILE *early_data_fp = NULL;
-#endif /* MBEDTLS_SSL_EARLY_DATA */
-
#if defined(MBEDTLS_SSL_ALPN)
const char *alpn_list[ALPN_LIST_SIZE];
#endif
@@ -1201,7 +1251,15 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_SSL_EARLY_DATA)
else if (strcmp(p, "early_data") == 0) {
- opt.early_data = q;
+ switch (atoi(q)) {
+ case 0:
+ opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ break;
+ case 1:
+ opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ break;
+ default: goto usage;
+ }
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -1711,11 +1769,10 @@
&psa_alg, &psa_alg2,
&usage,
mbedtls_pk_get_type(&pkey)) == 0) {
- ret = mbedtls_pk_wrap_as_opaque(&pkey, &key_slot, psa_alg,
- usage, psa_alg2);
+ ret = pk_wrap_as_opaque(&pkey, psa_alg, psa_alg2, usage, &key_slot);
if (ret != 0) {
mbedtls_printf(" failed\n ! "
- "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n",
+ "mbedtls_pk_get_psa_attributes returned -0x%x\n\n",
(unsigned int) -ret);
goto exit;
}
@@ -1968,16 +2025,9 @@
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
- int early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED;
- if (strlen(opt.early_data) > 0) {
- if ((early_data_fp = fopen(opt.early_data, "rb")) == NULL) {
- mbedtls_printf("failed\n ! Cannot open '%s' for reading.\n",
- opt.early_data);
- goto exit;
- }
- early_data_enabled = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ if (opt.early_data != DFL_EARLY_DATA) {
+ mbedtls_ssl_conf_early_data(&conf, opt.early_data);
}
- mbedtls_ssl_conf_early_data(&conf, early_data_enabled);
#endif /* MBEDTLS_SSL_EARLY_DATA */
if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
@@ -2448,32 +2498,9 @@
mbedtls_printf(" > Write to server:");
fflush(stdout);
- len = mbedtls_snprintf((char *) buf, sizeof(buf) - 1, GET_REQUEST,
- opt.request_page);
- tail_len = (int) strlen(GET_REQUEST_END);
-
- /* Add padding to GET request to reach opt.request_size in length */
- if (opt.request_size != DFL_REQUEST_SIZE &&
- len + tail_len < opt.request_size) {
- memset(buf + len, 'A', opt.request_size - len - tail_len);
- len += opt.request_size - len - tail_len;
- }
-
- strncpy((char *) buf + len, GET_REQUEST_END, sizeof(buf) - len - 1);
- len += tail_len;
-
- /* Truncate if request size is smaller than the "natural" size */
- if (opt.request_size != DFL_REQUEST_SIZE &&
- len > opt.request_size) {
- len = opt.request_size;
-
- /* Still end with \r\n unless that's really not possible */
- if (len >= 2) {
- buf[len - 2] = '\r';
- }
- if (len >= 1) {
- buf[len - 1] = '\n';
- }
+ ret = build_http_request(buf, sizeof(buf) - 1, &len);
+ if (ret != 0) {
+ goto exit;
}
if (opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
@@ -2545,8 +2572,11 @@
}
buf[written] = '\0';
- mbedtls_printf(" %d bytes written in %d fragments\n\n%s\n",
- written, frags, (char *) buf);
+ mbedtls_printf(
+ " %" MBEDTLS_PRINTF_SIZET " bytes written in %" MBEDTLS_PRINTF_SIZET " fragments\n\n%s\n",
+ written,
+ frags,
+ (char *) buf);
/* Send a non-empty request if request_size == 0 */
if (len == 0) {
@@ -2653,7 +2683,9 @@
len = ret;
buf[len] = '\0';
- mbedtls_printf(" < Read from server: %d bytes read\n\n%s", len, (char *) buf);
+ mbedtls_printf(" < Read from server: %" MBEDTLS_PRINTF_SIZET " bytes read\n\n%s",
+ len,
+ (char *) buf);
fflush(stdout);
/* End of message should be detected according to the syntax of the
* application protocol (eg HTTP), just use a dummy test here. */
@@ -2712,7 +2744,9 @@
len = ret;
buf[len] = '\0';
- mbedtls_printf(" < Read from server: %d bytes read\n\n%s", len, (char *) buf);
+ mbedtls_printf(" < Read from server: %" MBEDTLS_PRINTF_SIZET " bytes read\n\n%s",
+ len,
+ (char *) buf);
ret = 0;
}
@@ -3002,6 +3036,54 @@
goto exit;
}
+ ret = build_http_request(buf, sizeof(buf) - 1, &len);
+ if (ret != 0) {
+ goto exit;
+ }
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ if (ssl.conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
+ frags = 0;
+ written = 0;
+ do {
+ while ((ret = mbedtls_ssl_write_early_data(&ssl, buf + written,
+ len - written)) < 0) {
+ if (ret == MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) {
+ goto end_of_early_data;
+ }
+ if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
+ ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
+ ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
+ mbedtls_printf(" failed\n ! mbedtls_ssl_write returned -0x%x\n\n",
+ (unsigned int) -ret);
+ goto exit;
+ }
+
+ /* For event-driven IO, wait for socket to become available */
+ if (opt.event == 1 /* level triggered IO */) {
+#if defined(MBEDTLS_TIMING_C)
+ idle(&server_fd, &timer, ret);
+#else
+ idle(&server_fd, ret);
+#endif
+ }
+ }
+
+ frags++;
+ written += ret;
+ } while (written < len);
+
+end_of_early_data:
+
+ buf[written] = '\0';
+ mbedtls_printf(
+ " %" MBEDTLS_PRINTF_SIZET " bytes of early data written in %" MBEDTLS_PRINTF_SIZET " fragments\n\n%s\n",
+ written,
+ frags,
+ (char *) buf);
+ }
+#endif /* MBEDTLS_SSL_EARLY_DATA */
+
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
@@ -3035,12 +3117,6 @@
mbedtls_ssl_config_free(&conf);
mbedtls_ssl_session_free(&saved_session);
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (early_data_fp != NULL) {
- fclose(early_data_fp);
- }
-#endif
-
if (session_data != NULL) {
mbedtls_platform_zeroize(session_data, session_data_len);
}
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index abf33de..a5d2ed1 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -122,7 +122,8 @@
#define DFL_SNI NULL
#define DFL_ALPN_STRING NULL
#define DFL_GROUPS NULL
-#define DFL_MAX_EARLY_DATA_SIZE 0
+#define DFL_EARLY_DATA -1
+#define DFL_MAX_EARLY_DATA_SIZE ((uint32_t) -1)
#define DFL_SIG_ALGS NULL
#define DFL_DHM_FILE NULL
#define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM
@@ -429,9 +430,10 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \
- " max_early_data_size=%%d default: -1 (disabled)\n" \
- " options: -1 (disabled), " \
- " >= 0 (enabled, max amount of early data )\n"
+ " early_data=%%d default: library default\n" \
+ " options: 0 (disabled), 1 (enabled)\n" \
+ " max_early_data_size=%%d default: library default\n" \
+ " options: max amount of early data\n"
#else
#define USAGE_EARLY_DATA ""
#endif /* MBEDTLS_SSL_EARLY_DATA */
@@ -694,7 +696,10 @@
const char *cid_val_renego; /* the CID to use for incoming messages
* after renegotiation */
int reproducible; /* make communication reproducible */
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ int early_data; /* early data enablement flag */
uint32_t max_early_data_size; /* max amount of early data */
+#endif
int query_config_mode; /* whether to read config */
int use_srtp; /* Support SRTP */
int force_srtp_profile; /* SRTP protection profile to use or all */
@@ -1609,10 +1614,6 @@
};
#endif /* MBEDTLS_SSL_DTLS_SRTP */
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED;
-#endif
-
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
#if defined(MBEDTLS_MEMORY_DEBUG)
@@ -1747,7 +1748,10 @@
opt.sni = DFL_SNI;
opt.alpn_string = DFL_ALPN_STRING;
opt.groups = DFL_GROUPS;
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ opt.early_data = DFL_EARLY_DATA;
opt.max_early_data_size = DFL_MAX_EARLY_DATA_SIZE;
+#endif
opt.sig_algs = DFL_SIG_ALGS;
opt.dhm_file = DFL_DHM_FILE;
opt.transport = DFL_TRANSPORT;
@@ -1980,14 +1984,18 @@
}
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
- else if (strcmp(p, "max_early_data_size") == 0) {
- long long value = atoll(q);
- tls13_early_data_enabled =
- value >= 0 ? MBEDTLS_SSL_EARLY_DATA_ENABLED :
- MBEDTLS_SSL_EARLY_DATA_DISABLED;
- if (tls13_early_data_enabled) {
- opt.max_early_data_size = atoi(q);
+ else if (strcmp(p, "early_data") == 0) {
+ switch (atoi(q)) {
+ case 0:
+ opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ break;
+ case 1:
+ opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ break;
+ default: goto usage;
}
+ } else if (strcmp(p, "max_early_data_size") == 0) {
+ opt.max_early_data_size = (uint32_t) atoll(q);
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
else if (strcmp(p, "renegotiation") == 0) {
@@ -2708,12 +2716,10 @@
&psa_alg, &psa_alg2,
&psa_usage,
mbedtls_pk_get_type(&pkey)) == 0) {
- ret = mbedtls_pk_wrap_as_opaque(&pkey, &key_slot,
- psa_alg, psa_usage, psa_alg2);
-
+ ret = pk_wrap_as_opaque(&pkey, psa_alg, psa_alg2, psa_usage, &key_slot);
if (ret != 0) {
mbedtls_printf(" failed\n ! "
- "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n",
+ "pk_wrap_as_opaque returned -0x%x\n\n",
(unsigned int) -ret);
goto exit;
}
@@ -2727,12 +2733,10 @@
&psa_alg, &psa_alg2,
&psa_usage,
mbedtls_pk_get_type(&pkey2)) == 0) {
- ret = mbedtls_pk_wrap_as_opaque(&pkey2, &key_slot2,
- psa_alg, psa_usage, psa_alg2);
-
+ ret = pk_wrap_as_opaque(&pkey2, psa_alg, psa_alg2, psa_usage, &key_slot2);
if (ret != 0) {
mbedtls_printf(" failed\n ! "
- "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n",
+ "mbedtls_pk_get_psa_attributes returned -0x%x\n\n",
(unsigned int) -ret);
goto exit;
}
@@ -2809,8 +2813,10 @@
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
- mbedtls_ssl_conf_early_data(&conf, tls13_early_data_enabled);
- if (tls13_early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
+ if (opt.early_data != DFL_EARLY_DATA) {
+ mbedtls_ssl_conf_early_data(&conf, opt.early_data);
+ }
+ if (opt.max_early_data_size != DFL_MAX_EARLY_DATA_SIZE) {
mbedtls_ssl_conf_max_early_data_size(
&conf, opt.max_early_data_size);
}
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index d3ac526..17d36b7 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -274,6 +274,37 @@
return 0;
}
+
+#if defined(MBEDTLS_PK_C)
+int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algorithm_t psa_alg2,
+ psa_key_usage_t psa_usage, mbedtls_svc_key_id_t *key_id)
+{
+ int ret;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+
+ ret = mbedtls_pk_get_psa_attributes(pk, PSA_KEY_USAGE_SIGN_HASH, &key_attr);
+ if (ret != 0) {
+ return ret;
+ }
+ psa_set_key_usage_flags(&key_attr, psa_usage);
+ psa_set_key_algorithm(&key_attr, psa_alg);
+ if (psa_alg2 != PSA_ALG_NONE) {
+ psa_set_key_enrollment_algorithm(&key_attr, psa_alg2);
+ }
+ ret = mbedtls_pk_import_into_psa(pk, &key_attr, key_id);
+ if (ret != 0) {
+ return ret;
+ }
+ mbedtls_pk_free(pk);
+ mbedtls_pk_init(pk);
+ ret = mbedtls_pk_setup_opaque(pk, *key_id);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+}
+#endif /* MBEDTLS_PK_C */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index d06e099..1da2dfb 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -235,6 +235,31 @@
psa_algorithm_t *psa_alg2,
psa_key_usage_t *usage,
mbedtls_pk_type_t key_type);
+
+#if defined(MBEDTLS_PK_C)
+/** Turn a non-opaque PK context into an opaque one with folowing steps:
+ * - extract the key data and attributes from the PK context.
+ * - import the key material into PSA.
+ * - free the provided PK context and re-initilize it as an opaque PK context
+ * wrapping the PSA key imported in the above step.
+ *
+ * \param[in/out] pk On input the non-opaque PK context which contains the
+ * key to be wrapped. On output the re-initialized PK
+ * context which represents the opaque version of the one
+ * provided as input.
+ * \param[in] psa_alg The primary algorithm that will be associated to the
+ * PSA key.
+ * \param[in] psa_alg2 The enrollment algorithm that will be associated to the
+ * PSA key.
+ * \param[in] psa_usage The PSA key usage policy.
+ * \param[out] key_id The PSA key identifier of the imported key.
+ *
+ * \return \c 0 on sucess.
+ * \return \c -1 on failure.
+ */
+int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algorithm_t psa_alg2,
+ psa_key_usage_t psa_usage, mbedtls_svc_key_id_t *key_id);
+#endif /* MBEDTLS_PK_C */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
diff --git a/programs/test/metatest.c b/programs/test/metatest.c
index 5a45f71..5cd09bf 100644
--- a/programs/test/metatest.c
+++ b/programs/test/metatest.c
@@ -70,6 +70,41 @@
mbedtls_test_fail("Forced test failure", __LINE__, __FILE__);
}
+void meta_test_not_equal(const char *name)
+{
+ int left = 20;
+ int right = 10;
+
+ (void) name;
+
+ TEST_EQUAL(left, right);
+exit:
+ ;
+}
+
+void meta_test_not_le_s(const char *name)
+{
+ int left = 20;
+ int right = 10;
+
+ (void) name;
+
+ TEST_LE_S(left, right);
+exit:
+ ;
+}
+
+void meta_test_not_le_u(const char *name)
+{
+ size_t left = 20;
+ size_t right = 10;
+
+ (void) name;
+
+ TEST_LE_U(left, right);
+exit:
+ ;
+}
/****************************************************************/
/* Platform features */
@@ -285,6 +320,9 @@
*/
metatest_t metatests[] = {
{ "test_fail", "any", meta_test_fail },
+ { "test_not_equal", "any", meta_test_not_equal },
+ { "test_not_le_s", "any", meta_test_not_le_s },
+ { "test_not_le_u", "any", meta_test_not_le_u },
{ "null_dereference", "any", null_pointer_dereference },
{ "null_call", "any", null_pointer_call },
{ "read_after_free", "asan", read_after_free },
diff --git a/scripts/common.make b/scripts/common.make
index 2714bcd..9908a3c 100644
--- a/scripts/common.make
+++ b/scripts/common.make
@@ -4,6 +4,18 @@
MBEDTLS_PATH := ..
endif
+ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make))
+ # Use the define keyword to get a multi-line message.
+ # GNU make appends ". Stop.", so tweak the ending of our message accordingly.
+ define error_message
+$(MBEDTLS_PATH)/framework/exported.make not found.
+Run `git submodule update --init` to fetch the submodule contents.
+This is a fatal error
+ endef
+ $(error $(error_message))
+endif
+include $(MBEDTLS_PATH)/framework/exported.make
+
CFLAGS ?= -O2
WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
WARNING_CXXFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
index 4f9764d..8b91f0b 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
@@ -122,7 +122,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -196,7 +196,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -266,7 +266,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_sign == NULL )
@@ -283,7 +283,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -306,11 +306,11 @@
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_sign_hash( attributes,
key_buffer,
@@ -370,7 +370,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_verify == NULL )
@@ -387,7 +387,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -410,11 +410,11 @@
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_verify_hash( attributes,
key_buffer,
@@ -517,7 +517,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
- attributes->core.lifetime );
+ psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -609,7 +609,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
- attributes->core.lifetime );
+ psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -707,8 +707,8 @@
size_t *key_buffer_size )
{
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
- psa_key_type_t key_type = attributes->core.type;
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
+ psa_key_type_t key_type = psa_get_key_type(attributes);
*key_buffer_size = 0;
switch( location )
@@ -736,7 +736,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime);
+ PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
int is_default_production =
@@ -757,7 +757,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
size_t pubkey_length = 0; /* We don't support this feature yet */
if( drv->key_management == NULL ||
@@ -780,7 +780,7 @@
/* Transparent drivers are limited to generating asymmetric keys. */
/* We don't support passing custom production parameters
* to drivers yet. */
- if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type(attributes) ) &&
is_default_production )
{
/* Cycle through all known transparent accelerators */
@@ -793,9 +793,9 @@
break;
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
- attributes->core.type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) &&
- attributes->core.bits == 256 )
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
+ psa_get_key_type(attributes) == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_generate_key( attributes,
key_buffer,
@@ -862,7 +862,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( drv->key_management == NULL ||
drv->key_management->p_import == NULL )
@@ -939,7 +939,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( ( drv->key_management == NULL ) ||
( drv->key_management->p_export == NULL ) )
@@ -994,13 +994,13 @@
{% endmacro %}
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
/* Copying to a secure element is not implemented yet. */
return( PSA_ERROR_NOT_SUPPORTED );
@@ -1044,7 +1044,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1134,7 +1134,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1211,7 +1211,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1284,7 +1284,7 @@
{
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1684,7 +1684,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1736,7 +1736,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1785,7 +1785,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1833,7 +1833,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2169,7 +2169,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2233,7 +2233,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2305,7 +2305,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2505,7 +2505,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2563,7 +2563,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2627,7 +2627,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2645,10 +2645,10 @@
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDH(alg) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_key_agreement( attributes,
key_buffer,
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
index 2aae628..261cd2a 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
@@ -88,9 +88,9 @@
const psa_key_attributes_t *attributes,
size_t *key_buffer_size )
{
- psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
- psa_key_type_t key_type = attributes->core.type;
- size_t key_bits = attributes->core.bits;
+ psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ size_t key_bits = psa_get_key_bits(attributes);
*key_buffer_size = 0;
switch( location )
@@ -144,7 +144,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( ( drv->key_management == NULL ) ||
( drv->key_management->p_export_public == NULL ) )
@@ -203,7 +203,7 @@
key_buffer_size,
key_buffer_length
{% endmacro %}
- psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
#if defined(PSA_CRYPTO_DRIVER_TEST)
diff --git a/scripts/data_files/vs2013-app-template.vcxproj b/scripts/data_files/vs2017-app-template.vcxproj
similarity index 96%
rename from scripts/data_files/vs2013-app-template.vcxproj
rename to scripts/data_files/vs2017-app-template.vcxproj
index 2fe9cf3..36ca317 100644
--- a/scripts/data_files/vs2013-app-template.vcxproj
+++ b/scripts/data_files/vs2017-app-template.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -37,23 +37,27 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/scripts/data_files/vs2013-main-template.vcxproj b/scripts/data_files/vs2017-main-template.vcxproj
similarity index 96%
rename from scripts/data_files/vs2013-main-template.vcxproj
rename to scripts/data_files/vs2017-main-template.vcxproj
index 51861e1..448f9cd 100644
--- a/scripts/data_files/vs2013-main-template.vcxproj
+++ b/scripts/data_files/vs2017-main-template.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -28,23 +28,27 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/scripts/data_files/vs2013-sln-template.sln b/scripts/data_files/vs2017-sln-template.sln
similarity index 92%
rename from scripts/data_files/vs2013-sln-template.sln
rename to scripts/data_files/vs2017-sln-template.sln
index 615ce04..80efb10 100644
--- a/scripts/data_files/vs2013-sln-template.sln
+++ b/scripts/data_files/vs2017-sln-template.sln
@@ -1,8 +1,8 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
+# Visual Studio 2017
+VisualStudioVersion = 15.0.26228.4
+MinimumVisualStudioVersion = 15.0.26228.4
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbedTLS", "mbedTLS.vcxproj", "{46CF2D25-6A36-4189-B59C-E4815388E554}"
EndProject
APP_ENTRIES
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 96ade2f..a0dfc57 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
# Generate main file, individual apps and solution files for
-# MS Visual Studio 2013
+# MS Visual Studio 2017
#
# Must be run from Mbed TLS root or scripts directory.
# Takes no argument.
@@ -13,12 +13,12 @@
use strict;
use Digest::MD5 'md5_hex';
-my $vsx_dir = "visualc/VS2013";
+my $vsx_dir = "visualc/VS2017";
my $vsx_ext = "vcxproj";
-my $vsx_app_tpl_file = "scripts/data_files/vs2013-app-template.$vsx_ext";
-my $vsx_main_tpl_file = "scripts/data_files/vs2013-main-template.$vsx_ext";
+my $vsx_app_tpl_file = "scripts/data_files/vs2017-app-template.$vsx_ext";
+my $vsx_main_tpl_file = "scripts/data_files/vs2017-main-template.$vsx_ext";
my $vsx_main_file = "$vsx_dir/mbedTLS.$vsx_ext";
-my $vsx_sln_tpl_file = "scripts/data_files/vs2013-sln-template.sln";
+my $vsx_sln_tpl_file = "scripts/data_files/vs2017-sln-template.sln";
my $vsx_sln_file = "$vsx_dir/mbedTLS.sln";
my $programs_dir = 'programs';
diff --git a/scripts/lcov.sh b/scripts/lcov.sh
index 0584a0a..9a0c582 100755
--- a/scripts/lcov.sh
+++ b/scripts/lcov.sh
@@ -39,13 +39,19 @@
lcov_library_report () {
rm -rf Coverage
mkdir Coverage Coverage/tmp
- lcov --capture --initial --directory $library_dir -o Coverage/tmp/files.info
- lcov --rc lcov_branch_coverage=1 --capture --directory $library_dir -o Coverage/tmp/tests.info
- lcov --rc lcov_branch_coverage=1 --add-tracefile Coverage/tmp/files.info --add-tracefile Coverage/tmp/tests.info -o Coverage/tmp/all.info
- lcov --rc lcov_branch_coverage=1 --remove Coverage/tmp/all.info -o Coverage/tmp/final.info '*.h'
- gendesc tests/Descriptions.txt -o Coverage/tmp/descriptions
- genhtml --title "$title" --description-file Coverage/tmp/descriptions --keep-descriptions --legend --branch-coverage -o Coverage Coverage/tmp/final.info
- rm -f Coverage/tmp/*.info Coverage/tmp/descriptions
+ # Pass absolute paths as lcov output files. This works around a bug
+ # whereby lcov tries to create the output file in the root directory
+ # if it has emitted a warning. A fix was released in lcov 1.13 in 2016.
+ # Ubuntu 16.04 is affected, 18.04 and above are not.
+ # https://github.com/linux-test-project/lcov/commit/632c25a0d1f5e4d2f4fd5b28ce7c8b86d388c91f
+ COVTMP=$PWD/Coverage/tmp
+ lcov --capture --initial --directory $library_dir -o "$COVTMP/files.info"
+ lcov --rc lcov_branch_coverage=1 --capture --directory $library_dir -o "$COVTMP/tests.info"
+ lcov --rc lcov_branch_coverage=1 --add-tracefile "$COVTMP/files.info" --add-tracefile "$COVTMP/tests.info" -o "$COVTMP/all.info"
+ lcov --rc lcov_branch_coverage=1 --remove "$COVTMP/all.info" -o "$COVTMP/final.info" '*.h'
+ gendesc tests/Descriptions.txt -o "$COVTMP/descriptions"
+ genhtml --title "$title" --description-file "$COVTMP/descriptions" --keep-descriptions --legend --branch-coverage -o Coverage "$COVTMP/final.info"
+ rm -f "$COVTMP/"*.info "$COVTMP/descriptions"
echo "Coverage report in: Coverage/index.html"
}
diff --git a/scripts/windows_msbuild.bat b/scripts/windows_msbuild.bat
index ff2b9f2..2bc6a51 100644
--- a/scripts/windows_msbuild.bat
+++ b/scripts/windows_msbuild.bat
@@ -14,7 +14,7 @@
@rem vcvarsall.bat will silently change the directory to that directory.
@rem Setting the VSCMD_START_DIR environment variable causes it to change
@rem to that directory instead.
-set "VSCMD_START_DIR=%~dp0\..\visualc\VS2013"
+set "VSCMD_START_DIR=%~dp0\..\visualc\VS2017"
"%vcvarsall%" x64 && ^
msbuild /t:Rebuild /p:Configuration=%cfg%%retarget% /m mbedTLS.sln
diff --git a/tests/Makefile b/tests/Makefile
index f82c267..c2a0b84 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -208,6 +208,7 @@
s/\b(?=mbedtls_|psa_)/libtestdriver1_/g;
endef
+libtestdriver1.a: export MBEDTLS_PATH := $(patsubst ../..//%,/%,../../$(MBEDTLS_PATH))
libtestdriver1.a:
# Copy the library and fake a 3rdparty Makefile include.
rm -Rf ./libtestdriver1
diff --git a/tests/compat.sh b/tests/compat.sh
index ac29e50..a101ffd 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -125,7 +125,7 @@
print_test_case() {
for i in $3; do
uniform_title $1 $2 $i
- echo $TITLE
+ echo "compat;$TITLE"
done
}
diff --git a/tests/include/test/drivers/config_test_driver.h b/tests/include/test/drivers/config_test_driver.h
index 4eb27f0..ec8bcb6 100644
--- a/tests/include/test/drivers/config_test_driver.h
+++ b/tests/include/test/drivers/config_test_driver.h
@@ -40,5 +40,7 @@
//#define MBEDTLS_MD_C
//#define MBEDTLS_PEM_PARSE_C
//#define MBEDTLS_BASE64_C
+//#define MBEDTLS_THREADING_C
+//#define MBEDTLS_THREADING_PTHREAD
#endif /* MBEDTLS_CONFIG_H */
diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h
index 44f5c08..f6be307 100644
--- a/tests/include/test/psa_exercise_key.h
+++ b/tests/include/test/psa_exercise_key.h
@@ -123,6 +123,9 @@
* \param input2 The first input to pass.
* \param input2_length The length of \p input2 in bytes.
* \param capacity The capacity to set.
+ * \param key_destroyable If set to 1, a failure due to the key not existing
+ * or the key being destroyed mid-operation will only
+ * be reported if the error code is unexpected.
*
* \return \c 1 on success, \c 0 on failure.
*/
@@ -132,7 +135,7 @@
psa_algorithm_t alg,
const unsigned char *input1, size_t input1_length,
const unsigned char *input2, size_t input2_length,
- size_t capacity);
+ size_t capacity, int key_destroyable);
/** Perform a key agreement using the given key pair against its public key
* using psa_raw_key_agreement().
@@ -143,12 +146,15 @@
*
* \param alg A key agreement algorithm compatible with \p key.
* \param key A key that allows key agreement with \p alg.
+ * \param key_destroyable If set to 1, a failure due to the key not existing
+ * or the key being destroyed mid-operation will only
+ * be reported if the error code is unexpected.
*
* \return \c 1 on success, \c 0 on failure.
*/
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
psa_algorithm_t alg,
- mbedtls_svc_key_id_t key);
+ mbedtls_svc_key_id_t key, int key_destroyable);
/** Perform a key agreement using the given key pair against its public key
* using psa_key_derivation_raw_key().
@@ -162,12 +168,15 @@
* \p key.
* \param key A key pair object that is suitable for a key
* agreement with \p operation.
+ * \param key_destroyable If set to 1, a failure due to the key not existing
+ * or the key being destroyed mid-operation will only
+ * be reported if the error code is unexpected.
*
* \return \c 1 on success, \c 0 on failure.
*/
psa_status_t mbedtls_test_psa_key_agreement_with_self(
psa_key_derivation_operation_t *operation,
- mbedtls_svc_key_id_t key);
+ mbedtls_svc_key_id_t key, int key_destroyable);
/** Perform sanity checks on the given key representation.
*
@@ -209,18 +218,34 @@
* ```
* if( ! exercise_key( ... ) ) goto exit;
* ```
+ * To use this function for multi-threaded tests where the key
+ * may be destroyed at any point: call this function with key_destroyable set
+ * to 1, while another thread calls psa_destroy_key on the same key;
+ * this will test whether destroying the key in use leads to any corruption.
*
- * \param key The key to exercise. It should be capable of performing
- * \p alg.
- * \param usage The usage flags to assume.
- * \param alg The algorithm to exercise.
+ * There cannot be a set of concurrent calls:
+ * `mbedtls_test_psa_exercise_key(ki,...)` such that each ki is a unique
+ * persistent key not loaded into any key slot, and i is greater than the
+ * number of free key slots.
+ * This is because such scenarios can lead to unsupported
+ * `PSA_ERROR_INSUFFICIENT_MEMORY` return codes.
+ *
+ *
+ * \param key The key to exercise. It should be capable of performing
+ * \p alg.
+ * \param usage The usage flags to assume.
+ * \param alg The algorithm to exercise.
+ * \param key_destroyable If set to 1, a failure due to the key not existing
+ * or the key being destroyed mid-operation will only
+ * be reported if the error code is unexpected.
*
* \retval 0 The key failed the smoke tests.
* \retval 1 The key passed the smoke tests.
*/
int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg);
+ psa_algorithm_t alg,
+ int key_destroyable);
psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
psa_algorithm_t alg);
diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h
index 9a078f6..77f85c4 100644
--- a/tests/include/test/ssl_helpers.h
+++ b/tests/include/test/ssl_helpers.h
@@ -78,6 +78,10 @@
#undef MBEDTLS_SSL_TLS1_3_LABEL
};
+#if defined(MBEDTLS_SSL_ALPN)
+#define MBEDTLS_TEST_MAX_ALPN_LIST_SIZE 10
+#endif
+
typedef struct mbedtls_test_ssl_log_pattern {
const char *pattern;
size_t counter;
@@ -114,9 +118,13 @@
void (*cli_log_fun)(void *, int, const char *, int, const char *);
int resize_buffers;
int early_data;
+ int max_early_data_size;
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_context *cache;
#endif
+#if defined(MBEDTLS_SSL_ALPN)
+ const char *alpn_list[MBEDTLS_TEST_MAX_ALPN_LIST_SIZE];
+#endif
} mbedtls_test_handshake_test_options;
/*
@@ -196,6 +204,13 @@
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
/*
+ * Random number generator aimed for TLS unitary tests. Its main purpose is to
+ * simplify the set-up of a random number generator for TLS
+ * unitary tests: no need to set up a good entropy source for example.
+ */
+int mbedtls_test_random(void *p_rng, unsigned char *output, size_t output_len);
+
+/*
* This function can be passed to mbedtls to receive output logs from it. In
* this case, it will count the instances of a mbedtls_test_ssl_log_pattern
* in the received logged messages.
@@ -608,9 +623,7 @@
mbedtls_test_handshake_test_options *client_options,
mbedtls_test_handshake_test_options *server_options,
mbedtls_ssl_session *session);
-#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SRV_C &&
- MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS &&
- MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
+#endif
#define ECJPAKE_TEST_PWD "bla"
diff --git a/tests/opt-testcases/tls13-kex-modes.sh b/tests/opt-testcases/tls13-kex-modes.sh
index 4581bc5..49f06e0 100755
--- a/tests/opt-testcases/tls13-kex-modes.sh
+++ b/tests/opt-testcases/tls13-kex-modes.sh
@@ -23,7 +23,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -41,7 +41,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -78,7 +78,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -96,7 +96,7 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -133,7 +133,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -151,7 +151,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -188,7 +188,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -206,7 +206,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -261,7 +261,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -280,7 +280,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -319,7 +319,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -338,7 +338,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -377,7 +377,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -396,7 +396,7 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -435,7 +435,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -454,7 +454,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -493,7 +493,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -512,7 +512,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -550,8 +550,9 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
+ -s "No suitable PSK key exchange mode" \
-S "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -572,7 +573,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -592,7 +593,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -633,7 +634,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -653,7 +654,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -694,7 +695,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -733,8 +734,9 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
+ -s "No suitable PSK key exchange mode" \
-S "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -754,7 +756,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -793,7 +795,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -921,7 +923,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -938,7 +940,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -973,7 +975,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -990,7 +992,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1025,7 +1027,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1042,7 +1044,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1078,7 +1080,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1096,7 +1098,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1133,7 +1135,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1151,7 +1153,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1188,7 +1190,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1206,7 +1208,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1243,7 +1245,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1261,7 +1263,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1299,7 +1301,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1318,7 +1320,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1357,7 +1359,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1376,7 +1378,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1413,8 +1415,9 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
+ -s "No suitable PSK key exchange mode" \
-S "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1433,7 +1436,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1580,7 +1583,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -1665,7 +1668,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1711,7 +1714,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1769,7 +1772,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1827,7 +1830,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -1870,7 +1873,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1916,7 +1919,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2047,7 +2050,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2106,7 +2109,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "key exchange mode: ephemeral"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2152,7 +2155,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2199,7 +2202,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "key exchange mode: ephemeral"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2288,7 +2291,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2348,7 +2351,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2392,7 +2395,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2438,7 +2441,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2485,7 +2488,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2532,7 +2535,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2595,7 +2598,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-c "Selected key exchange mode: ephemeral" \
-c "HTTP/1.0 200 OK"
@@ -2643,7 +2646,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2690,7 +2693,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "key exchange mode: ephemeral"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index 4e6bf87..5e43921 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -71,120 +71,6 @@
-S "key exchange mode: ephemeral$" \
-s "ticket is not authentic"
-requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
- MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Session resumption failure, ticket authentication failed." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=1" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -s "ticket is not authentic" \
- -S "ticket is expired" \
- -S "Invalid ticket creation time" \
- -S "Ticket age exceeds limitation" \
- -S "Ticket age outside tolerance window"
-
-requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
- MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Session resumption failure, ticket expired." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=2" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -S "ticket is not authentic" \
- -s "ticket is expired" \
- -S "Invalid ticket creation time" \
- -S "Ticket age exceeds limitation" \
- -S "Ticket age outside tolerance window"
-
-requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
- MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Session resumption failure, invalid start time." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=3" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -S "ticket is not authentic" \
- -S "ticket is expired" \
- -s "Invalid ticket creation time" \
- -S "Ticket age exceeds limitation" \
- -S "Ticket age outside tolerance window"
-
-requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
- MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Session resumption failure, ticket expired. too old" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=4" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -S "ticket is not authentic" \
- -S "ticket is expired" \
- -S "Invalid ticket creation time" \
- -s "Ticket age exceeds limitation" \
- -S "Ticket age outside tolerance window"
-
-requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
- MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too young." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=5" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -S "ticket is not authentic" \
- -S "ticket is expired" \
- -S "Invalid ticket creation time" \
- -S "Ticket age exceeds limitation" \
- -s "Ticket age outside tolerance window"
-
-requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
- MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too old." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=6" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -S "ticket is not authentic" \
- -S "ticket is expired" \
- -S "Invalid ticket creation time" \
- -S "Ticket age exceeds limitation" \
- -s "Ticket age outside tolerance window"
-
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
@@ -252,261 +138,1053 @@
0 \
-s "key exchange mode: ephemeral$"
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 OK" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption with servername" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
+ "$P_CLI server_name=localhost reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 OK" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption with ticket max lifetime (7d)" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \
+ "$P_CLI reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 OK" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
+run_test "TLS 1.3 m->m: resumption with AES-256-GCM-SHA384 only" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 OK" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption with early data" \
+ "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -c "ClientHello: early_data(42) extension exists." \
+ -c "EncryptedExtensions: early_data(42) extension received." \
+ -c "bytes of early data written" \
+ -C "0 bytes of early data written" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -s "Sent max_early_data_size" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -s "ClientHello: early_data(42) extension exists." \
+ -s "EncryptedExtensions: early_data(42) extension exists." \
+ -s "early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
+run_test "TLS 1.3 m->m: resumption with early data, AES-256-GCM-SHA384 only" \
+ "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=3 force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -c "ClientHello: early_data(42) extension exists." \
+ -c "EncryptedExtensions: early_data(42) extension received." \
+ -c "bytes of early data written" \
+ -C "0 bytes of early data written" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384" \
+ -s "Sent max_early_data_size" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -s "ClientHello: early_data(42) extension exists." \
+ -s "EncryptedExtensions: early_data(42) extension exists." \
+ -s "early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, early data cli-enabled/srv-default" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -C "received max_early_data_size" \
+ -C "NewSessionTicket: early_data(42) extension received." \
+ -C "ClientHello: early_data(42) extension exists." \
+ -C "EncryptedExtensions: early_data(42) extension received." \
+ -c "0 bytes of early data written" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -S "Sent max_early_data_size" \
+ -S "NewSessionTicket: early_data(42) extension exists." \
+ -S "ClientHello: early_data(42) extension exists." \
+ -S "EncryptedExtensions: early_data(42) extension exists." \
+ -S "early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, early data cli-enabled/srv-disabled" \
+ "$P_SRV debug_level=4 early_data=0 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -C "received max_early_data_size" \
+ -C "NewSessionTicket: early_data(42) extension received." \
+ -C "ClientHello: early_data(42) extension exists." \
+ -C "EncryptedExtensions: early_data(42) extension received." \
+ -c "0 bytes of early data written" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -S "Sent max_early_data_size" \
+ -S "NewSessionTicket: early_data(42) extension exists." \
+ -S "ClientHello: early_data(42) extension exists." \
+ -S "EncryptedExtensions: early_data(42) extension exists." \
+ -S "early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, early data cli-default/srv-enabled" \
+ "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=3 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -C "ClientHello: early_data(42) extension exists." \
+ -C "EncryptedExtensions: early_data(42) extension received." \
+ -C "bytes of early data written" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -s "Sent max_early_data_size" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -S "ClientHello: early_data(42) extension exists." \
+ -S "EncryptedExtensions: early_data(42) extension exists." \
+ -S "early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, early data cli-disabled/srv-enabled" \
+ "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=3 early_data=0 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -C "ClientHello: early_data(42) extension exists." \
+ -C "EncryptedExtensions: early_data(42) extension received." \
+ -C "bytes of early data written" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -s "Sent max_early_data_size" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -S "ClientHello: early_data(42) extension exists." \
+ -S "EncryptedExtensions: early_data(42) extension exists." \
+ -S "early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, ticket lifetime too long (7d + 1s)" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \
+ "$P_CLI reco_mode=1 reconnect=1" \
+ 1 \
+ -c "Protocol is TLSv1.3" \
+ -C "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... failed" \
+ -S "Protocol is TLSv1.3" \
+ -S "key exchange mode: psk" \
+ -S "Select PSK ciphersuite" \
+ -s "Ticket lifetime (604801) is greater than 7 days."
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, ticket lifetime=0" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \
+ "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \
+ 1 \
+ -c "Protocol is TLSv1.3" \
+ -C "Saving session for reuse... ok" \
+ -c "Discard new session ticket" \
+ -c "Reconnecting with saved session... failed" \
+ -s "Protocol is TLSv1.3" \
+ -S "key exchange mode: psk" \
+ -S "Select PSK ciphersuite"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, servername check failed" \
+ "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
+ "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \
+ 1 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "Hostname mismatch the session ticket, disable session resumption." \
+ -s "Protocol is TLSv1.3" \
+ -S "key exchange mode: psk" \
+ -S "Select PSK ciphersuite"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, ticket auth failed." \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=1" \
+ "$P_CLI reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -S "key exchange mode: psk" \
+ -s "ticket is not authentic" \
+ -S "ticket is expired" \
+ -S "Invalid ticket creation time" \
+ -S "Ticket age exceeds limitation" \
+ -S "Ticket age outside tolerance window"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, ticket expired." \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=2" \
+ "$P_CLI reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -S "key exchange mode: psk" \
+ -S "ticket is not authentic" \
+ -s "ticket is expired" \
+ -S "Invalid ticket creation time" \
+ -S "Ticket age exceeds limitation" \
+ -S "Ticket age outside tolerance window"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, invalid creation time." \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=3" \
+ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -S "key exchange mode: psk" \
+ -S "ticket is not authentic" \
+ -S "ticket is expired" \
+ -s "Invalid ticket creation time" \
+ -S "Ticket age exceeds limitation" \
+ -S "Ticket age outside tolerance window"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, ticket expired, too old" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=4" \
+ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -S "key exchange mode: psk" \
+ -S "ticket is not authentic" \
+ -S "ticket is expired" \
+ -S "Invalid ticket creation time" \
+ -s "Ticket age exceeds limitation" \
+ -S "Ticket age outside tolerance window"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, age outside tolerance window, too young" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=5" \
+ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -S "key exchange mode: psk" \
+ -S "ticket is not authentic" \
+ -S "ticket is expired" \
+ -S "Invalid ticket creation time" \
+ -S "Ticket age exceeds limitation" \
+ -s "Ticket age outside tolerance window"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, age outside tolerance window, too old" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=6" \
+ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -S "key exchange mode: psk" \
+ -S "ticket is not authentic" \
+ -S "ticket is expired" \
+ -S "Invalid ticket creation time" \
+ -S "Ticket age exceeds limitation" \
+ -s "Ticket age outside tolerance window"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_EARLY_DATA
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk/none" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \
+ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: ephemeral over psk resumption, cli/tkt kex modes psk/psk" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \
+ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk/psk_ephemeral" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \
+ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: ephemeral over psk resumption, cli/tkt kex modes psk/psk_all" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \
+ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk_ephemeral/none" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \
+ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk_ephemeral/psk" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \
+ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_ephemeral/psk_ephemeral" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \
+ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_ephemeral/psk_all" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \
+ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk_all/none" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \
+ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+ 0 \
+ -c "Pre-configured PSK number = 1" \
+ -S "sent selected_identity:" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: ephemeral over psk resumption, cli/tkt kex modes psk_all/psk" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \
+ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_all/psk_ephemeral" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \
+ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_all/psk_all" \
+ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \
+ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -s "key exchange mode: ephemeral" \
+ -s "key exchange mode: psk_ephemeral" \
+ -S "key exchange mode: psk$" \
+ -s "found matched identity" \
+ -S "No suitable PSK key exchange mode" \
+ -S "No usable PSK or ticket"
+
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3 m->G: EarlyData: basic check, good" \
- "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK \
- --earlydata --maxearlydata 16384 --disable-client-cert" \
- "$P_CLI debug_level=4 early_data=$EARLY_DATA_INPUT reco_mode=1 reconnect=1 reco_delay=900" \
+run_test "TLS 1.3 m->O: resumption" \
+ "$O_NEXT_SRV -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 1" \
+ "$P_CLI reco_mode=1 reconnect=1" \
0 \
- -c "received max_early_data_size: 16384" \
- -c "Reconnecting with saved session" \
- -c "NewSessionTicket: early_data(42) extension received." \
- -c "ClientHello: early_data(42) extension exists." \
- -c "EncryptedExtensions: early_data(42) extension received." \
- -c "EncryptedExtensions: early_data(42) extension exists." \
- -c "<= write EndOfEarlyData" \
- -s "Parsing extension 'Early Data/42' (0 bytes)" \
- -s "Sending extension Early Data/42 (0 bytes)" \
- -s "END OF EARLY DATA (5) was received." \
- -s "early data accepted"
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 ok"
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_EARLY_DATA
-requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \
- "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \
- "$P_CLI debug_level=4 early_data=$EARLY_DATA_INPUT reco_mode=1 reconnect=1" \
- 0 \
- -c "Reconnecting with saved session" \
- -C "NewSessionTicket: early_data(42) extension received." \
- -c "ClientHello: early_data(42) extension does not exist." \
- -C "EncryptedExtensions: early_data(42) extension received." \
- -C "EncryptedExtensions: early_data(42) extension exists."
-
-#TODO: OpenSSL tests don't work now. It might be openssl options issue, cause GnuTLS has worked.
+# No early data m->O tests for the time being. The option -early_data is needed
+# to enable early data on OpenSSL server and it is not compatible with the
+# -www option we usually use for testing with OpenSSL server (see
+# O_NEXT_SRV_EARLY_DATA definition). In this configuration when running the
+# ephemeral then ticket based scenario we use for early data testing the first
+# handshake fails. The following skipped test is here to illustrate the kind
+# of testing we would like to do.
skip_next_test
-requires_openssl_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_EARLY_DATA
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_EARLY_DATA \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3, ext PSK, early data" \
- "$O_NEXT_SRV_EARLY_DATA -msg -debug -tls1_3 -psk_identity 0a0b0c -psk 010203 -allow_no_dhe_kex -nocert" \
- "$P_CLI debug_level=5 tls13_kex_modes=psk early_data=1 psk=010203 psk_identity=0a0b0c" \
- 1 \
+run_test "TLS 1.3 m->O: resumption with early data" \
+ "$O_NEXT_SRV_EARLY_DATA -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 1" \
+ "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
-c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size: 16384" \
-c "NewSessionTicket: early_data(42) extension received." \
-c "ClientHello: early_data(42) extension exists." \
-c "EncryptedExtensions: early_data(42) extension received." \
- -c "EncryptedExtensions: early_data(42) extension ( ignored )."
+ -c "bytes of early data written" \
+ -s "decrypted early data with length:"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \
- "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+run_test "TLS 1.3 m->G: resumption" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \
+ "$P_CLI reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 OK"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \
- "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity"
+requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
+run_test "TLS 1.3 m->G: resumption with AES-256-GCM-SHA384 only" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \
+ "$P_CLI force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session... ok" \
+ -c "HTTP/1.0 200 OK"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_EARLY_DATA \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \
- "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+run_test "TLS 1.3 m->G: resumption with early data" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \
+ --earlydata --maxearlydata 16384" \
+ "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size: 16384" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -c "ClientHello: early_data(42) extension exists." \
+ -c "EncryptedExtensions: early_data(42) extension received." \
+ -c "bytes of early data written" \
+ -s "decrypted early data with length:"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_EARLY_DATA \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \
- "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity"
+requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
+run_test "TLS 1.3 m->G: resumption with early data, AES-256-GCM-SHA384 only" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \
+ --earlydata --maxearlydata 16384" \
+ "$P_CLI debug_level=3 force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size: 16384" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -c "ClientHello: early_data(42) extension exists." \
+ -c "EncryptedExtensions: early_data(42) extension received." \
+ -c "bytes of early data written" \
+ -s "decrypted early data with length:"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \
- "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_EARLY_DATA \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->G: resumption, early data cli-enabled/srv-disabled" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \
+ "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -C "received max_early_data_size: 16384" \
+ -C "NewSessionTicket: early_data(42) extension received." \
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \
- "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_EARLY_DATA \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->G: resumption, early data cli-default/srv-enabled" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \
+ --earlydata --maxearlydata 16384" \
+ "$P_CLI debug_level=3 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size: 16384" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -C "ClientHello: early_data(42) extension exists." \
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemeral." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \
- "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity" \
- -s "key exchange mode: psk_ephemeral"
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_EARLY_DATA \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->G: resumption, early data cli-disabled/srv-enabled" \
+ "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \
+ --earlydata --maxearlydata 16384" \
+ "$P_CLI debug_level=3 early_data=0 reco_mode=1 reconnect=1" \
+ 0 \
+ -c "Protocol is TLSv1.3" \
+ -c "Saving session for reuse... ok" \
+ -c "Reconnecting with saved session" \
+ -c "HTTP/1.0 200 OK" \
+ -c "received max_early_data_size: 16384" \
+ -c "NewSessionTicket: early_data(42) extension received." \
+ -C "ClientHello: early_data(42) extension exists." \
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \
- "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity" \
- -s "key exchange mode: psk_ephemeral"
+# https://github.com/openssl/openssl/issues/10714
+# Until now, OpenSSL client does not support reconnect.
+skip_next_test
+run_test "TLS 1.3 O->m: resumption" \
+ "$P_SRV debug_level=2 tickets=1" \
+ "$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \
+ 0 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \
- "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "sent selected_identity:" \
- -s "key exchange mode: ephemeral" \
- -S "key exchange mode: psk_ephemeral" \
- -S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+run_test "TLS 1.3 G->m: resumption" \
+ "$P_SRV debug_level=2 tickets=1" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \
+ 0 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite"
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \
- "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity"
-
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \
- "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity" \
- -s "key exchange mode: psk_ephemeral"
-
-requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \
- "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
- 0 \
- -c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
- -s "found matched identity" \
- -s "key exchange mode: psk_ephemeral"
+requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
+# Test the session resumption when the cipher suite for the original session is
+# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not
+# 256 bits long as with all the other TLS 1.3 cipher suites.
+run_test "TLS 1.3 G->m: resumption with AES-256-GCM-SHA384 only" \
+ "$P_SRV debug_level=2 tickets=1" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \
+ 0 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384"
EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 ))
EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 ))
-requires_gnutls_next
-requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
- MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \
- "$P_SRV force_version=tls13 debug_level=4 max_early_data_size=$EARLY_DATA_INPUT_LEN" \
- "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \
- -d 10 -r --earlydata $EARLY_DATA_INPUT " \
+run_test "TLS 1.3 G->m: resumption with early data" \
+ "$P_SRV debug_level=4 tickets=1 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r \
+ --earlydata $EARLY_DATA_INPUT" \
0 \
- -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
- -s "NewSessionTicket: early_data(42) extension exists." \
- -s "ClientHello: early_data(42) extension exists." \
- -s "EncryptedExtensions: early_data(42) extension exists." \
- -s "$( head -1 $EARLY_DATA_INPUT )" \
- -s "$( tail -1 $EARLY_DATA_INPUT )" \
- -s "200 early data bytes read" \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -s "ClientHello: early_data(42) extension exists." \
+ -s "EncryptedExtensions: early_data(42) extension exists." \
+ -s "$( head -1 $EARLY_DATA_INPUT )" \
+ -s "$( tail -1 $EARLY_DATA_INPUT )" \
+ -s "200 early data bytes read" \
-s "106 early data bytes read"
+
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
+run_test "TLS 1.3 G->m: resumption with early data, AES-256-GCM-SHA384 only" \
+ "$P_SRV debug_level=4 tickets=1 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r \
+ --earlydata $EARLY_DATA_INPUT" \
+ 0 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384" \
+ -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -s "ClientHello: early_data(42) extension exists." \
+ -s "EncryptedExtensions: early_data(42) extension exists." \
+ -s "$( head -1 $EARLY_DATA_INPUT )" \
+ -s "$( tail -1 $EARLY_DATA_INPUT )" \
+ -s "200 early data bytes read" \
+ -s "106 early data bytes read"
+
+# The Mbed TLS server does not allow early data for the ticket it sends but
+# the GnuTLS indicates early data anyway when resuming with the ticket and
+# sends early data. The Mbed TLS server does not expect early data in
+# association with the ticket thus it eventually fails the resumption
+# handshake. The GnuTLS client behavior is not compliant here with the TLS 1.3
+# specification and thus its behavior may change in following versions.
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 G->m: resumption, early data cli-enabled/srv-default" \
+ "$P_SRV debug_level=4 tickets=1" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r \
+ --earlydata $EARLY_DATA_INPUT" \
+ 1 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -S "Sent max_early_data_size" \
+ -S "NewSessionTicket: early_data(42) extension exists." \
+ -s "ClientHello: early_data(42) extension exists." \
+ -s "EarlyData: rejected, feature disabled in server configuration." \
+ -S "EncryptedExtensions: early_data(42) extension exists." \
+ -s "EarlyData: deprotect and discard app data records" \
+ -s "EarlyData: Too much early data received"
+
+# The Mbed TLS server does not allow early data for the ticket it sends but
+# the GnuTLS indicates early data anyway when resuming with the ticket and
+# sends early data. The Mbed TLS server does not expect early data in
+# association with the ticket thus it eventually fails the resumption
+# handshake. The GnuTLS client behavior is not compliant here with the TLS 1.3
+# specification and thus its behavior may change in following versions.
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 G->m: resumption, early data cli-enabled/srv-disabled" \
+ "$P_SRV debug_level=4 tickets=1 early_data=0" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r \
+ --earlydata $EARLY_DATA_INPUT" \
+ 1 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -S "Sent max_early_data_size" \
+ -S "NewSessionTicket: early_data(42) extension exists." \
+ -s "ClientHello: early_data(42) extension exists." \
+ -s "EarlyData: rejected, feature disabled in server configuration." \
+ -S "EncryptedExtensions: early_data(42) extension exists." \
+ -s "EarlyData: deprotect and discard app data records" \
+ -s "EarlyData: Too much early data received"
+
+requires_gnutls_tls1_3
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 G->m: resumption, early data cli-disabled/srv-enabled" \
+ "$P_SRV debug_level=4 tickets=1 early_data=1" \
+ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \
+ 0 \
+ -s "Protocol is TLSv1.3" \
+ -s "key exchange mode: psk" \
+ -s "Select PSK ciphersuite" \
+ -s "Sent max_early_data_size" \
+ -s "NewSessionTicket: early_data(42) extension exists." \
+ -S "ClientHello: early_data(42) extension exists." \
+ -S "EncryptedExtensions: early_data(42) extension exists."
+
+requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Ephemeral over PSK kex with early data enabled" \
+ "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=1024" \
+ "$P_CLI debug_level=4 early_data=1 tls13_kex_modes=psk_or_ephemeral reco_mode=1 reconnect=1" \
+ 0 \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk" \
+ -s "found matched identity" \
+ -s "EarlyData: rejected, not a session resumption" \
+ -C "EncryptedExtensions: early_data(42) extension exists."
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index c25f044..acfcf5c 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -212,10 +212,21 @@
# defined in this script whose name starts with "component_".
ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//')
- # Delay determinig SUPPORTED_COMPONENTS until the command line options have a chance to override
+ # Delay determining SUPPORTED_COMPONENTS until the command line options have a chance to override
# the commands set by the environment
}
+setup_quiet_wrappers()
+{
+ # Pick up "quiet" wrappers for make and cmake, which don't output very much
+ # unless there is an error. This reduces logging overhead in the CI.
+ #
+ # Note that the cmake wrapper breaks unless we use an absolute path here.
+ if [[ -e ${PWD}/tests/scripts/quiet ]]; then
+ export PATH=${PWD}/tests/scripts/quiet:$PATH
+ fi
+}
+
# Test whether the component $1 is included in the command line patterns.
is_component_included()
{
@@ -889,6 +900,16 @@
# Dynamic secure element support is a deprecated feature and needs to be disabled here.
# This is done to have the same form of psa_key_attributes_s for libdriver and library.
scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+
+ # If threading is enabled on the normal build, then we need to enable it in the drivers as well,
+ # otherwise we will end up running multithreaded tests without mutexes to protect them.
+ if scripts/config.py get MBEDTLS_THREADING_C; then
+ scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_THREADING_C
+ fi
+
+ if scripts/config.py get MBEDTLS_THREADING_PTHREAD; then
+ scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_THREADING_PTHREAD
+ fi
}
# When called with no parameter this function disables all builtin curves.
@@ -1089,6 +1110,8 @@
echo "MBEDTLS_ECP_RESTARTABLE" >> $expected
# No PSA equivalent - needed by some init tests
echo "MBEDTLS_ENTROPY_NV_SEED" >> $expected
+ # No PSA equivalent - required to run threaded tests.
+ echo "MBEDTLS_THREADING_PTHREAD" >> $expected
# Compare reality with expectation.
# We want an exact match, to ensure the above list remains up-to-date.
@@ -1262,19 +1285,67 @@
check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a
}
-component_test_psa_crypto_client () {
- msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT, make"
+# Get a list of library-wise undefined symbols and ensure that they only
+# belong to psa_xxx() functions and not to mbedtls_yyy() ones.
+# This function is a common helper used by both:
+# - component_test_default_psa_crypto_client_without_crypto_provider
+# - component_build_full_psa_crypto_client_without_crypto_provider.
+common_check_mbedtls_missing_symbols() {
+ nm library/libmbedcrypto.a | grep ' [TRrDC] ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_def.txt
+ nm library/libmbedcrypto.a | grep ' U ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_undef.txt
+ comm sym_def.txt sym_undef.txt -13 > linking_errors.txt
+ not grep mbedtls_ linking_errors.txt
+
+ rm sym_def.txt sym_undef.txt linking_errors.txt
+}
+
+component_test_default_psa_crypto_client_without_crypto_provider () {
+ msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
+
scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+ scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
scripts/config.py set MBEDTLS_PSA_CRYPTO_CLIENT
scripts/config.py unset MBEDTLS_LMS_C
- scripts/config.py unset MBEDTLS_LMS_PRIVATE
+
make
- msg "test: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT, make"
+ msg "check missing symbols: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
+ common_check_mbedtls_missing_symbols
+
+ msg "test: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
make test
}
+component_build_full_psa_crypto_client_without_crypto_provider () {
+ msg "build: full config - PSA_CRYPTO_C"
+
+ # Use full config which includes USE_PSA and CRYPTO_CLIENT.
+ scripts/config.py full
+
+ scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+ scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+ # Dynamic secure element support is a deprecated feature and it is not
+ # available when CRYPTO_C and PSA_CRYPTO_STORAGE_C are disabled.
+ scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+
+ # Since there is no crypto provider in this build it is not possible to
+ # build all the test executables and progrems due to missing PSA functions
+ # at link time. Therefore we will just build libraries and we'll check
+ # that symbols of interest are there.
+ make lib
+
+ msg "check missing symbols: full config - PSA_CRYPTO_C"
+
+ common_check_mbedtls_missing_symbols
+
+ # Ensure that desired functions are included into the build (extend the
+ # following list as required).
+ grep mbedtls_pk_get_psa_attributes library/libmbedcrypto.a
+ grep mbedtls_pk_import_into_psa library/libmbedcrypto.a
+ grep mbedtls_pk_copy_from_psa library/libmbedcrypto.a
+}
+
component_test_psa_crypto_rsa_no_genprime() {
msg "build: default config minus MBEDTLS_GENPRIME"
scripts/config.py unset MBEDTLS_GENPRIME
@@ -1531,6 +1602,23 @@
make test
}
+component_full_no_pkparse_pkwrite() {
+ msg "build: full without pkparse and pkwrite"
+
+ scripts/config.py crypto_full
+ scripts/config.py unset MBEDTLS_PK_PARSE_C
+ scripts/config.py unset MBEDTLS_PK_WRITE_C
+
+ make CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+ # Ensure that PK_[PARSE|WRITE]_C were not re-enabled accidentally (additive config).
+ not grep mbedtls_pk_parse_key library/pkparse.o
+ not grep mbedtls_pk_write_key_der library/pkwrite.o
+
+ msg "test: full without pkparse and pkwrite"
+ make test
+}
+
component_test_crypto_full_md_light_only () {
msg "build: crypto_full with only the light subset of MD"
scripts/config.py crypto_full
@@ -2177,6 +2265,11 @@
scripts/config.py full
scripts/config.py set MBEDTLS_THREADING_C
scripts/config.py set MBEDTLS_THREADING_PTHREAD
+ # Self-tests do not currently use multiple threads.
+ scripts/config.py unset MBEDTLS_SELF_TEST
+
+ # The deprecated MBEDTLS_PSA_CRYPTO_SE_C interface is not thread safe.
+ scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
CC=clang cmake -D CMAKE_BUILD_TYPE:String=TSan .
make
@@ -4756,6 +4849,26 @@
not grep -q "AES note: built-in implementation." ./programs/test/selftest
}
+component_test_sha3_variations() {
+ msg "sha3 loop unroll variations"
+
+ # define minimal config sufficient to test SHA3
+ cat > include/mbedtls/mbedtls_config.h << END
+ #define MBEDTLS_SELF_TEST
+ #define MBEDTLS_SHA3_C
+END
+
+ msg "all loops unrolled"
+ make clean
+ make -C tests test_suite_shax CFLAGS="-DMBEDTLS_SHA3_THETA_UNROLL=1 -DMBEDTLS_SHA3_PI_UNROLL=1 -DMBEDTLS_SHA3_CHI_UNROLL=1 -DMBEDTLS_SHA3_RHO_UNROLL=1"
+ ./tests/test_suite_shax
+
+ msg "all loops rolled up"
+ make clean
+ make -C tests test_suite_shax CFLAGS="-DMBEDTLS_SHA3_THETA_UNROLL=0 -DMBEDTLS_SHA3_PI_UNROLL=0 -DMBEDTLS_SHA3_CHI_UNROLL=0 -DMBEDTLS_SHA3_RHO_UNROLL=0"
+ ./tests/test_suite_shax
+}
+
support_test_aesni_m32() {
support_test_m32_no_asm && (lscpu | grep -qw aes)
}
@@ -6353,6 +6466,7 @@
pre_initialize_variables
pre_parse_command_line "$@"
+setup_quiet_wrappers
pre_check_git
pre_restore_files
pre_back_up
diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh
index 3fe4e8c..792885f 100755
--- a/tests/scripts/check-generated-files.sh
+++ b/tests/scripts/check-generated-files.sh
@@ -142,5 +142,5 @@
# generate_visualc_files enumerates source files (library/*.c). It doesn't
# care about their content, but the files must exist. So it must run after
# the step that creates or updates these files.
- check scripts/generate_visualc_files.pl visualc/VS2013
+ check scripts/generate_visualc_files.pl visualc/VS2017
fi
diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py
index 65fbc9f..d5a4b92 100755
--- a/tests/scripts/check_files.py
+++ b/tests/scripts/check_files.py
@@ -173,6 +173,8 @@
b'sh': 'sh',
}
+ path_exemptions = re.compile(r'tests/scripts/quiet/.*')
+
def is_valid_shebang(self, first_line, filepath):
m = re.match(self._shebang_re, first_line)
if not m:
@@ -321,6 +323,7 @@
".make",
".pem", # some openssl dumps have tabs
".sln",
+ "/.gitmodules",
"/Makefile",
"/Makefile.inc",
"/generate_visualc_files.pl",
@@ -467,6 +470,7 @@
]
def setup_logger(self, log_file, level=logging.INFO):
+ """Log to log_file if provided, or to stderr if None."""
self.logger = logging.getLogger()
self.logger.setLevel(level)
if log_file:
@@ -478,9 +482,19 @@
@staticmethod
def collect_files():
+ """Return the list of files to check.
+
+ These are the regular files commited into Git.
+ """
bytes_output = subprocess.check_output(['git', 'ls-files', '-z'])
bytes_filepaths = bytes_output.split(b'\0')[:-1]
ascii_filepaths = map(lambda fp: fp.decode('ascii'), bytes_filepaths)
+ # Filter out directories. Normally Git doesn't list directories
+ # (it only knows about the files inside them), but there is
+ # at least one case where 'git ls-files' includes a directory:
+ # submodules. Just skip submodules (and any other directories).
+ ascii_filepaths = [fp for fp in ascii_filepaths
+ if os.path.isfile(fp)]
# Prepend './' to files in the top-level directory so that
# something like `'/Makefile' in fp` matches in the top-level
# directory as well as in subdirectories.
@@ -488,12 +502,17 @@
for fp in ascii_filepaths]
def check_files(self):
+ """Check all files for all issues."""
for issue_to_check in self.issues_to_check:
for filepath in self.collect_files():
if issue_to_check.should_check_file(filepath):
issue_to_check.check_file_for_issue(filepath)
def output_issues(self):
+ """Log the issues found and their locations.
+
+ Return 1 if there were issues, 0 otherwise.
+ """
integrity_return_code = 0
for issue_to_check in self.issues_to_check:
if issue_to_check.files_with_issues:
diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py
index 68e7e69..d67e678 100755
--- a/tests/scripts/check_test_cases.py
+++ b/tests/scripts/check_test_cases.py
@@ -16,6 +16,23 @@
import subprocess
import sys
+class ScriptOutputError(ValueError):
+ """A kind of ValueError that indicates we found
+ the script doesn't list test cases in an expected
+ pattern.
+ """
+
+ @property
+ def script_name(self):
+ return super().args[0]
+
+ @property
+ def idx(self):
+ return super().args[1]
+
+ @property
+ def line(self):
+ return super().args[2]
class Results:
"""Store file and line information about errors or warnings in test suites."""
@@ -86,19 +103,27 @@
data_file_name, line_number, line)
in_paragraph = True
- def collect_from_script(self, file_name):
+ def collect_from_script(self, script_name):
"""Collect the test cases in a script by calling its listing test cases
option"""
descriptions = self.new_per_file_state() # pylint: disable=assignment-from-none
- listed = subprocess.check_output(['sh', file_name, '--list-test-cases'])
+ listed = subprocess.check_output(['sh', script_name, '--list-test-cases'])
# Assume test file is responsible for printing identical format of
# test case description between --list-test-cases and its OUTCOME.CSV
#
# idx indicates the number of test case since there is no line number
# in the script for each test case.
- for idx, description in enumerate(listed.splitlines()):
+ for idx, line in enumerate(listed.splitlines()):
+ # We are expecting the script to list the test cases in
+ # `<suite_name>;<description>` pattern.
+ script_outputs = line.split(b';', 1)
+ if len(script_outputs) == 2:
+ suite_name, description = script_outputs
+ else:
+ raise ScriptOutputError(script_name, idx, line.decode("utf-8"))
+
self.process_test_case(descriptions,
- file_name,
+ suite_name.decode('utf-8'),
idx,
description.rstrip())
@@ -124,8 +149,7 @@
for sh_file in ['ssl-opt.sh', 'compat.sh']:
sh_file = os.path.join(directory, sh_file)
- if os.path.exists(sh_file):
- self.collect_from_script(sh_file)
+ self.collect_from_script(sh_file)
class TestDescriptions(TestDescriptionExplorer):
"""Collect the available test cases."""
@@ -202,7 +226,12 @@
return
results = Results(options)
checker = DescriptionChecker(results)
- checker.walk_all()
+ try:
+ checker.walk_all()
+ except ScriptOutputError as e:
+ results.error(e.script_name, e.idx,
+ '"{}" should be listed as "<suite_name>;<description>"',
+ e.line)
if (results.warnings or results.errors) and not options.quiet:
sys.stderr.write('{}: {} errors, {} warnings\n'
.format(sys.argv[0], results.errors, results.warnings))
diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake
new file mode 100755
index 0000000..a34365b
--- /dev/null
+++ b/tests/scripts/quiet/cmake
@@ -0,0 +1,19 @@
+#! /usr/bin/env bash
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# This swallows the output of the wrapped tool, unless there is an error.
+# This helps reduce excess logging in the CI.
+
+# If you are debugging a build / CI issue, you can get complete unsilenced logs
+# by un-commenting the following line (or setting VERBOSE_LOGS in your environment):
+
+# export VERBOSE_LOGS=1
+
+# don't silence invocations containing these arguments
+NO_SILENCE=" --version "
+
+TOOL="cmake"
+
+. "$(dirname "$0")/quiet.sh"
diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make
new file mode 100755
index 0000000..920e5b8
--- /dev/null
+++ b/tests/scripts/quiet/make
@@ -0,0 +1,19 @@
+#! /usr/bin/env bash
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# This swallows the output of the wrapped tool, unless there is an error.
+# This helps reduce excess logging in the CI.
+
+# If you are debugging a build / CI issue, you can get complete unsilenced logs
+# by un-commenting the following line (or setting VERBOSE_LOGS in your environment):
+
+# export VERBOSE_LOGS=1
+
+# don't silence invocations containing these arguments
+NO_SILENCE=" --version | test "
+
+TOOL="make"
+
+. "$(dirname "$0")/quiet.sh"
diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh
new file mode 100644
index 0000000..0f26184
--- /dev/null
+++ b/tests/scripts/quiet/quiet.sh
@@ -0,0 +1,79 @@
+# -*-mode: sh; sh-shell: bash -*-
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# This swallows the output of the wrapped tool, unless there is an error.
+# This helps reduce excess logging in the CI.
+
+# If you are debugging a build / CI issue, you can get complete unsilenced logs
+# by un-commenting the following line (or setting VERBOSE_LOGS in your environment):
+#
+# VERBOSE_LOGS=1
+#
+# This script provides most of the functionality for the adjacent make and cmake
+# wrappers.
+#
+# It requires two variables to be set:
+#
+# TOOL - the name of the tool that is being wrapped (with no path), e.g. "make"
+#
+# NO_SILENCE - a regex that describes the commandline arguments for which output will not
+# be silenced, e.g. " --version | test ". In this example, "make lib test" will
+# not be silent, but "make lib" will be.
+
+# Identify path to original tool. There is an edge-case here where the quiet wrapper is on the path via
+# a symlink or relative path, but "type -ap" yields the wrapper with it's normalised path. We use
+# the -ef operator to compare paths, to avoid picking the wrapper in this case (to avoid infinitely
+# recursing).
+while IFS= read -r ORIGINAL_TOOL; do
+ if ! [[ $ORIGINAL_TOOL -ef "$0" ]]; then break; fi
+done < <(type -ap -- "$TOOL")
+
+print_quoted_args() {
+ # similar to printf '%q' "$@"
+ # but produce more human-readable results for common/simple cases like "a b"
+ for a in "$@"; do
+ # Get bash to quote the string
+ printf -v q '%q' "$a"
+ simple_pattern="^([-[:alnum:]_+./:@]+=)?([^']*)$"
+ if [[ "$a" != "$q" && $a =~ $simple_pattern ]]; then
+ # a requires some quoting (a != q), but has no single quotes, so we can
+ # simplify the quoted form - e.g.:
+ # a b -> 'a b'
+ # CFLAGS=a b -> CFLAGS='a b'
+ q="${BASH_REMATCH[1]}'${BASH_REMATCH[2]}'"
+ fi
+ printf " %s" "$q"
+ done
+}
+
+if [[ ! " $* " =~ " --version " ]]; then
+ # Display the command being invoked - if it succeeds, this is all that will
+ # be displayed. Don't do this for invocations with --version, because
+ # this output is often parsed by scripts, so we don't want to modify it.
+ printf %s "${TOOL}" 1>&2
+ print_quoted_args "$@" 1>&2
+ echo 1>&2
+fi
+
+if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then
+ # Run original command with no output supression
+ exec "${ORIGINAL_TOOL}" "$@"
+else
+ # Run original command and capture output & exit status
+ TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX")
+ "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1
+ EXIT_STATUS=$?
+
+ if [[ $EXIT_STATUS -ne 0 ]]; then
+ # On error, display the full output
+ cat "${TMPFILE}"
+ fi
+
+ # Remove tmpfile
+ rm "${TMPFILE}"
+
+ # Propagate the exit status
+ exit $EXIT_STATUS
+fi
diff --git a/tests/src/drivers/test_driver_signature.c b/tests/src/drivers/test_driver_signature.c
index 00dd3e2..4fca5d1 100644
--- a/tests/src/drivers/test_driver_signature.c
+++ b/tests/src/drivers/test_driver_signature.c
@@ -49,7 +49,7 @@
size_t signature_size,
size_t *signature_length)
{
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
@@ -71,7 +71,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
(defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
@@ -116,7 +116,7 @@
const uint8_t *signature,
size_t signature_length)
{
- if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
@@ -138,7 +138,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
(defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
diff --git a/tests/src/psa_crypto_stubs.c b/tests/src/psa_crypto_stubs.c
new file mode 100644
index 0000000..81d7f4b
--- /dev/null
+++ b/tests/src/psa_crypto_stubs.c
@@ -0,0 +1,75 @@
+/** \file psa_crypto_stubs.c
+ *
+ * \brief Stub functions when MBEDTLS_PSA_CRYPTO_CLIENT is enabled but
+ * MBEDTLS_PSA_CRYPTO_C is disabled.
+ */
+
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#include <psa/crypto.h>
+
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
+
+psa_status_t psa_generate_random(uint8_t *output,
+ size_t output_size)
+{
+ (void) output;
+ (void) output_size;
+
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ (void) key;
+ (void) data;
+ (void) data_size;
+ (void) data_length;
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ (void) key;
+ (void) data;
+ (void) data_size;
+ (void) data_length;
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
+ psa_key_attributes_t *attributes)
+{
+ (void) key;
+ (void) attributes;
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
+{
+ (void) operation;
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data,
+ size_t data_length,
+ mbedtls_svc_key_id_t *key)
+{
+ (void) attributes;
+ (void) data;
+ (void) data_length;
+ (void) key;
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */
diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c
index 7b81052..937bd45 100644
--- a/tests/src/psa_exercise_key.c
+++ b/tests/src/psa_exercise_key.c
@@ -38,7 +38,8 @@
}
#endif
-static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
+static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
+ int key_destroyable)
{
int ok = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -46,8 +47,13 @@
mbedtls_svc_key_id_t id;
psa_key_type_t type;
size_t bits;
-
- PSA_ASSERT(psa_get_key_attributes(key, &attributes));
+ psa_status_t status = psa_get_key_attributes(key, &attributes);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ psa_reset_key_attributes(&attributes);
+ return 1;
+ }
+ PSA_ASSERT(status);
lifetime = psa_get_key_lifetime(&attributes);
id = psa_get_key_id(&attributes);
type = psa_get_key_type(&attributes);
@@ -66,17 +72,20 @@
(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
- /* randomly-generated 64-bit constant, should never appear in test data */
- psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
- psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
- if (lifetime_is_dynamic_secure_element(lifetime)) {
- /* Mbed TLS currently always exposes the slot number to
- * applications. This is not mandated by the PSA specification
- * and may change in future versions. */
- TEST_EQUAL(status, 0);
- TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
- } else {
- TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
+ /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
+ if (key_destroyable == 0) {
+ /* randomly-generated 64-bit constant, should never appear in test data */
+ psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
+ status = psa_get_key_slot_number(&attributes, &slot_number);
+ if (lifetime_is_dynamic_secure_element(lifetime)) {
+ /* Mbed TLS currently always exposes the slot number to
+ * applications. This is not mandated by the PSA specification
+ * and may change in future versions. */
+ TEST_EQUAL(status, 0);
+ TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
+ } else {
+ TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
+ }
}
#endif
@@ -110,20 +119,27 @@
static int exercise_mac_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
const unsigned char input[] = "foo";
unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
size_t mac_length = sizeof(mac);
-
+ psa_status_t status = PSA_SUCCESS;
/* Convert wildcard algorithm to exercisable algorithm */
if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
}
if (usage & PSA_KEY_USAGE_SIGN_HASH) {
- PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
+ status = psa_mac_sign_setup(&operation, key, alg);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ PSA_ASSERT(psa_mac_abort(&operation));
+ return 1;
+ }
+ PSA_ASSERT(status);
PSA_ASSERT(psa_mac_update(&operation,
input, sizeof(input)));
PSA_ASSERT(psa_mac_sign_finish(&operation,
@@ -136,7 +152,13 @@
(usage & PSA_KEY_USAGE_SIGN_HASH ?
PSA_SUCCESS :
PSA_ERROR_INVALID_SIGNATURE);
- PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
+ status = psa_mac_verify_setup(&operation, key, alg);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ PSA_ASSERT(psa_mac_abort(&operation));
+ return 1;
+ }
+ PSA_ASSERT(status);
PSA_ASSERT(psa_mac_update(&operation,
input, sizeof(input)));
TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
@@ -152,7 +174,8 @@
static int exercise_cipher_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
@@ -164,13 +187,20 @@
size_t ciphertext_length = sizeof(ciphertext);
unsigned char decrypted[sizeof(ciphertext)];
size_t part_length;
+ psa_status_t status = PSA_SUCCESS;
PSA_ASSERT(psa_get_key_attributes(key, &attributes));
key_type = psa_get_key_type(&attributes);
iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
if (usage & PSA_KEY_USAGE_ENCRYPT) {
- PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
+ status = psa_cipher_encrypt_setup(&operation, key, alg);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ PSA_ASSERT(psa_cipher_abort(&operation));
+ return 1;
+ }
+ PSA_ASSERT(status);
if (iv_length != 0) {
PSA_ASSERT(psa_cipher_generate_iv(&operation,
iv, sizeof(iv),
@@ -188,12 +218,17 @@
}
if (usage & PSA_KEY_USAGE_DECRYPT) {
- psa_status_t status;
int maybe_invalid_padding = 0;
if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
}
- PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
+ status = psa_cipher_decrypt_setup(&operation, key, alg);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ PSA_ASSERT(psa_cipher_abort(&operation));
+ return 1;
+ }
+ PSA_ASSERT(status);
if (iv_length != 0) {
PSA_ASSERT(psa_cipher_set_iv(&operation,
iv, iv_length));
@@ -227,7 +262,8 @@
static int exercise_aead_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
size_t nonce_length;
@@ -237,6 +273,7 @@
unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
size_t ciphertext_length = sizeof(ciphertext);
size_t plaintext_length = sizeof(ciphertext);
+ psa_status_t status = PSA_SUCCESS;
/* Convert wildcard algorithm to exercisable algorithm */
if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
@@ -248,12 +285,17 @@
nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
if (usage & PSA_KEY_USAGE_ENCRYPT) {
- PSA_ASSERT(psa_aead_encrypt(key, alg,
- nonce, nonce_length,
- NULL, 0,
- plaintext, sizeof(plaintext),
- ciphertext, sizeof(ciphertext),
- &ciphertext_length));
+ status = psa_aead_encrypt(key, alg,
+ nonce, nonce_length,
+ NULL, 0,
+ plaintext, sizeof(plaintext),
+ ciphertext, sizeof(ciphertext),
+ &ciphertext_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
}
if (usage & PSA_KEY_USAGE_DECRYPT) {
@@ -261,13 +303,17 @@
(usage & PSA_KEY_USAGE_ENCRYPT ?
PSA_SUCCESS :
PSA_ERROR_INVALID_SIGNATURE);
- TEST_EQUAL(psa_aead_decrypt(key, alg,
- nonce, nonce_length,
- NULL, 0,
- ciphertext, ciphertext_length,
- plaintext, sizeof(plaintext),
- &plaintext_length),
- verify_status);
+ status = psa_aead_decrypt(key, alg,
+ nonce, nonce_length,
+ NULL, 0,
+ ciphertext, ciphertext_length,
+ plaintext, sizeof(plaintext),
+ &plaintext_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ TEST_ASSERT(status == verify_status);
}
return 1;
@@ -291,7 +337,8 @@
static int exercise_signature_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
/* If the policy allows signing with any hash, just pick one. */
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
@@ -305,6 +352,7 @@
TEST_FAIL("No hash algorithm for hash-and-sign testing");
#endif
}
+ psa_status_t status = PSA_SUCCESS;
if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
PSA_ALG_IS_SIGN_HASH(alg)) {
@@ -321,10 +369,15 @@
}
if (usage & PSA_KEY_USAGE_SIGN_HASH) {
- PSA_ASSERT(psa_sign_hash(key, alg,
- payload, payload_length,
- signature, sizeof(signature),
- &signature_length));
+ status = psa_sign_hash(key, alg,
+ payload, payload_length,
+ signature, sizeof(signature),
+ &signature_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
}
if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
@@ -332,10 +385,14 @@
(usage & PSA_KEY_USAGE_SIGN_HASH ?
PSA_SUCCESS :
PSA_ERROR_INVALID_SIGNATURE);
- TEST_EQUAL(psa_verify_hash(key, alg,
- payload, payload_length,
- signature, signature_length),
- verify_status);
+ status = psa_verify_hash(key, alg,
+ payload, payload_length,
+ signature, signature_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ TEST_ASSERT(status == verify_status);
}
}
@@ -346,10 +403,15 @@
size_t signature_length = sizeof(signature);
if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
- PSA_ASSERT(psa_sign_message(key, alg,
- message, message_length,
- signature, sizeof(signature),
- &signature_length));
+ status = psa_sign_message(key, alg,
+ message, message_length,
+ signature, sizeof(signature),
+ &signature_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
}
if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
@@ -357,10 +419,14 @@
(usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
PSA_SUCCESS :
PSA_ERROR_INVALID_SIGNATURE);
- TEST_EQUAL(psa_verify_message(key, alg,
- message, message_length,
- signature, signature_length),
- verify_status);
+ status = psa_verify_message(key, alg,
+ message, message_length,
+ signature, signature_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ TEST_ASSERT(status == verify_status);
}
}
@@ -372,7 +438,8 @@
static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
"Hello, world...";
@@ -380,22 +447,30 @@
"(wabblewebblewibblewobblewubble)";
size_t ciphertext_length = sizeof(ciphertext);
size_t plaintext_length = 16;
-
+ psa_status_t status = PSA_SUCCESS;
if (usage & PSA_KEY_USAGE_ENCRYPT) {
- PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
- plaintext, plaintext_length,
- NULL, 0,
- ciphertext, sizeof(ciphertext),
- &ciphertext_length));
+ status = psa_asymmetric_encrypt(key, alg,
+ plaintext, plaintext_length,
+ NULL, 0,
+ ciphertext, sizeof(ciphertext),
+ &ciphertext_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
}
if (usage & PSA_KEY_USAGE_DECRYPT) {
- psa_status_t status =
- psa_asymmetric_decrypt(key, alg,
- ciphertext, ciphertext_length,
- NULL, 0,
- plaintext, sizeof(plaintext),
- &plaintext_length);
+ status = psa_asymmetric_decrypt(key, alg,
+ ciphertext, ciphertext_length,
+ NULL, 0,
+ plaintext, sizeof(plaintext),
+ &plaintext_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
TEST_ASSERT(status == PSA_SUCCESS ||
((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
(status == PSA_ERROR_INVALID_ARGUMENT ||
@@ -414,16 +489,22 @@
psa_algorithm_t alg,
const unsigned char *input1, size_t input1_length,
const unsigned char *input2, size_t input2_length,
- size_t capacity)
+ size_t capacity, int key_destroyable)
{
PSA_ASSERT(psa_key_derivation_setup(operation, alg));
+ psa_status_t status = PSA_SUCCESS;
if (PSA_ALG_IS_HKDF(alg)) {
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_SALT,
input1, input1_length));
- PSA_ASSERT(psa_key_derivation_input_key(operation,
- PSA_KEY_DERIVATION_INPUT_SECRET,
- key));
+ status = psa_key_derivation_input_key(operation,
+ PSA_KEY_DERIVATION_INPUT_SECRET,
+ key);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_INFO,
input2,
@@ -432,13 +513,23 @@
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_SALT,
input1, input1_length));
- PSA_ASSERT(psa_key_derivation_input_key(operation,
- PSA_KEY_DERIVATION_INPUT_SECRET,
- key));
+ status = psa_key_derivation_input_key(operation,
+ PSA_KEY_DERIVATION_INPUT_SECRET,
+ key);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
} else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
- PSA_ASSERT(psa_key_derivation_input_key(operation,
- PSA_KEY_DERIVATION_INPUT_SECRET,
- key));
+ status = psa_key_derivation_input_key(operation,
+ PSA_KEY_DERIVATION_INPUT_SECRET,
+ key);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_INFO,
input2,
@@ -448,9 +539,14 @@
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_SEED,
input1, input1_length));
- PSA_ASSERT(psa_key_derivation_input_key(operation,
- PSA_KEY_DERIVATION_INPUT_SECRET,
- key));
+ status = psa_key_derivation_input_key(operation,
+ PSA_KEY_DERIVATION_INPUT_SECRET,
+ key);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_LABEL,
input2, input2_length));
@@ -462,9 +558,14 @@
PSA_KEY_DERIVATION_INPUT_SALT,
input2,
input2_length));
- PSA_ASSERT(psa_key_derivation_input_key(operation,
- PSA_KEY_DERIVATION_INPUT_PASSWORD,
- key));
+ status = psa_key_derivation_input_key(operation,
+ PSA_KEY_DERIVATION_INPUT_PASSWORD,
+ key);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ return 1;
+ }
+ PSA_ASSERT(status);
} else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
PSA_KEY_DERIVATION_INPUT_SECRET,
@@ -486,7 +587,8 @@
static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
unsigned char input1[] = "Input 1";
@@ -500,14 +602,20 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
input1, input1_length,
input2, input2_length,
- capacity)) {
+ capacity, key_destroyable)) {
goto exit;
}
- PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
- output,
- capacity));
- PSA_ASSERT(psa_key_derivation_abort(&operation));
+ psa_status_t status = psa_key_derivation_output_bytes(&operation,
+ output,
+ capacity);
+ if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
+ /* The key has been destroyed. */
+ PSA_ASSERT(psa_key_derivation_abort(&operation));
+ } else {
+ PSA_ASSERT(status);
+ PSA_ASSERT(psa_key_derivation_abort(&operation));
+ }
}
return 1;
@@ -520,31 +628,45 @@
* private key against its own public key. */
psa_status_t mbedtls_test_psa_key_agreement_with_self(
psa_key_derivation_operation_t *operation,
- mbedtls_svc_key_id_t key)
+ mbedtls_svc_key_id_t key, int key_destroyable)
{
psa_key_type_t private_key_type;
psa_key_type_t public_key_type;
size_t key_bits;
uint8_t *public_key = NULL;
size_t public_key_length;
- /* Return GENERIC_ERROR if something other than the final call to
- * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
- * but it's good enough: callers will report it as a failed test anyway. */
- psa_status_t status = PSA_ERROR_GENERIC_ERROR;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- PSA_ASSERT(psa_get_key_attributes(key, &attributes));
+ psa_status_t status = psa_get_key_attributes(key, &attributes);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ psa_reset_key_attributes(&attributes);
+ return PSA_SUCCESS;
+ }
+ PSA_ASSERT(status);
+
private_key_type = psa_get_key_type(&attributes);
key_bits = psa_get_key_bits(&attributes);
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
TEST_CALLOC(public_key, public_key_length);
- PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
- &public_key_length));
+ status = psa_export_public_key(key, public_key, public_key_length,
+ &public_key_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ status = PSA_SUCCESS;
+ goto exit;
+ }
+ PSA_ASSERT(status);
status = psa_key_derivation_key_agreement(
operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
public_key, public_key_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ status = PSA_SUCCESS;
+ goto exit;
+ }
exit:
/*
* Key attributes may have been returned by psa_get_key_attributes()
@@ -560,7 +682,8 @@
* private key against its own public key. */
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
psa_algorithm_t alg,
- mbedtls_svc_key_id_t key)
+ mbedtls_svc_key_id_t key,
+ int key_destroyable)
{
psa_key_type_t private_key_type;
psa_key_type_t public_key_type;
@@ -569,25 +692,39 @@
size_t public_key_length;
uint8_t output[1024];
size_t output_length;
- /* Return GENERIC_ERROR if something other than the final call to
- * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
- * but it's good enough: callers will report it as a failed test anyway. */
- psa_status_t status = PSA_ERROR_GENERIC_ERROR;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- PSA_ASSERT(psa_get_key_attributes(key, &attributes));
+ psa_status_t status = psa_get_key_attributes(key, &attributes);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ psa_reset_key_attributes(&attributes);
+ return PSA_SUCCESS;
+ }
+ PSA_ASSERT(status);
+
private_key_type = psa_get_key_type(&attributes);
key_bits = psa_get_key_bits(&attributes);
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
TEST_CALLOC(public_key, public_key_length);
- PSA_ASSERT(psa_export_public_key(key,
- public_key, public_key_length,
- &public_key_length));
+ status = psa_export_public_key(key,
+ public_key, public_key_length,
+ &public_key_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ status = PSA_SUCCESS;
+ goto exit;
+ }
+ PSA_ASSERT(status);
status = psa_raw_key_agreement(alg, key,
public_key, public_key_length,
output, sizeof(output), &output_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ status = PSA_SUCCESS;
+ goto exit;
+ }
if (status == PSA_SUCCESS) {
TEST_ASSERT(output_length <=
PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
@@ -609,14 +746,16 @@
static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
int ok = 0;
if (usage & PSA_KEY_USAGE_DERIVE) {
/* We need two keys to exercise key agreement. Exercise the
* private key against its own public key. */
- PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
+ PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
+ key_destroyable));
}
ok = 1;
@@ -626,7 +765,8 @@
static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
unsigned char input[1] = { 0 };
@@ -657,7 +797,12 @@
hash length. Otherwise test should fail with INVALID_ARGUMENT. */
if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- PSA_ASSERT(psa_get_key_attributes(key, &attributes));
+ psa_status_t status = psa_get_key_attributes(key, &attributes);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ ok = 1;
+ }
+ PSA_ASSERT(status);
size_t key_bits = psa_get_key_bits(&attributes);
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
@@ -666,7 +811,8 @@
}
}
- TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
+ TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
+ key_destroyable),
expected_key_agreement_status);
if (expected_key_agreement_status != PSA_SUCCESS) {
@@ -857,7 +1003,8 @@
}
static int exercise_export_key(mbedtls_svc_key_id_t key,
- psa_key_usage_t usage)
+ psa_key_usage_t usage,
+ int key_destroyable)
{
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t *exported = NULL;
@@ -865,25 +1012,31 @@
size_t exported_length = 0;
int ok = 0;
- PSA_ASSERT(psa_get_key_attributes(key, &attributes));
+ psa_status_t status = psa_get_key_attributes(key, &attributes);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ psa_reset_key_attributes(&attributes);
+ return 1;
+ }
+ PSA_ASSERT(status);
exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
psa_get_key_type(&attributes),
psa_get_key_bits(&attributes));
TEST_CALLOC(exported, exported_size);
- if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
- !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
- TEST_EQUAL(psa_export_key(key, exported,
- exported_size, &exported_length),
- PSA_ERROR_NOT_PERMITTED);
+ status = psa_export_key(key, exported, exported_size, &exported_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ ok = 1;
+ goto exit;
+ } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
+ !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
+ TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
ok = 1;
goto exit;
}
-
- PSA_ASSERT(psa_export_key(key,
- exported, exported_size,
- &exported_length));
+ PSA_ASSERT(status);
ok = mbedtls_test_psa_exported_key_sanity_check(
psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
exported, exported_length);
@@ -899,7 +1052,8 @@
return ok;
}
-static int exercise_export_public_key(mbedtls_svc_key_id_t key)
+static int exercise_export_public_key(mbedtls_svc_key_id_t key,
+ int key_destroyable)
{
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t public_type;
@@ -908,16 +1062,27 @@
size_t exported_length = 0;
int ok = 0;
- PSA_ASSERT(psa_get_key_attributes(key, &attributes));
+ psa_status_t status = psa_get_key_attributes(key, &attributes);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ psa_reset_key_attributes(&attributes);
+ return 1;
+ }
+ PSA_ASSERT(status);
if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
psa_get_key_type(&attributes),
psa_get_key_bits(&attributes));
TEST_CALLOC(exported, exported_size);
- TEST_EQUAL(psa_export_public_key(key, exported,
- exported_size, &exported_length),
- PSA_ERROR_INVALID_ARGUMENT);
+ status = psa_export_public_key(key, exported,
+ exported_size, &exported_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ ok = 1;
+ goto exit;
+ }
+ TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
ok = 1;
goto exit;
}
@@ -928,9 +1093,14 @@
psa_get_key_bits(&attributes));
TEST_CALLOC(exported, exported_size);
- PSA_ASSERT(psa_export_public_key(key,
- exported, exported_size,
- &exported_length));
+ status = psa_export_public_key(key, exported,
+ exported_size, &exported_length);
+ if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
+ /* The key has been destroyed. */
+ ok = 1;
+ goto exit;
+ }
+ PSA_ASSERT(status);
ok = mbedtls_test_psa_exported_key_sanity_check(
public_type, psa_get_key_bits(&attributes),
exported, exported_length);
@@ -948,38 +1118,43 @@
int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
psa_key_usage_t usage,
- psa_algorithm_t alg)
+ psa_algorithm_t alg,
+ int key_destroyable)
{
int ok = 0;
- if (!check_key_attributes_sanity(key)) {
+ if (!check_key_attributes_sanity(key, key_destroyable)) {
return 0;
}
if (alg == 0) {
ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
} else if (PSA_ALG_IS_MAC(alg)) {
- ok = exercise_mac_key(key, usage, alg);
+ ok = exercise_mac_key(key, usage, alg, key_destroyable);
} else if (PSA_ALG_IS_CIPHER(alg)) {
- ok = exercise_cipher_key(key, usage, alg);
+ ok = exercise_cipher_key(key, usage, alg, key_destroyable);
} else if (PSA_ALG_IS_AEAD(alg)) {
- ok = exercise_aead_key(key, usage, alg);
+ ok = exercise_aead_key(key, usage, alg, key_destroyable);
} else if (PSA_ALG_IS_SIGN(alg)) {
- ok = exercise_signature_key(key, usage, alg);
+ ok = exercise_signature_key(key, usage, alg, key_destroyable);
} else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
- ok = exercise_asymmetric_encryption_key(key, usage, alg);
+ ok = exercise_asymmetric_encryption_key(key, usage, alg,
+ key_destroyable);
} else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
- ok = exercise_key_derivation_key(key, usage, alg);
+ ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
} else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
- ok = exercise_raw_key_agreement_key(key, usage, alg);
+ ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
} else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
- ok = exercise_key_agreement_key(key, usage, alg);
+ ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
} else {
TEST_FAIL("No code to exercise this category of algorithm");
}
- ok = ok && exercise_export_key(key, usage);
- ok = ok && exercise_export_public_key(key);
+ ok = ok && exercise_export_key(key,
+ usage,
+ key_destroyable);
+ ok = ok && exercise_export_public_key(key,
+ key_destroyable);
exit:
return ok;
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index 7a28bd8..55201c0 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -12,9 +12,7 @@
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_SSL_TLS_C)
-#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
-static int rng_seed = 0xBEEF;
-static int rng_get(void *p_rng, unsigned char *output, size_t output_len)
+int mbedtls_test_random(void *p_rng, unsigned char *output, size_t output_len)
{
(void) p_rng;
for (size_t i = 0; i < output_len; i++) {
@@ -23,7 +21,6 @@
return 0;
}
-#endif
void mbedtls_test_ssl_log_analyzer(void *ctx, int level,
const char *file, int line,
@@ -46,6 +43,8 @@
mbedtls_test_handshake_test_options *opts)
{
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
+ static int rng_seed = 0xBEEF;
+
srand(rng_seed);
rng_seed += 0xD0;
#endif
@@ -68,6 +67,7 @@
opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
opts->resize_buffers = 1;
opts->early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ opts->max_early_data_size = -1;
#if defined(MBEDTLS_SSL_CACHE_C)
TEST_CALLOC(opts->cache, 1);
mbedtls_ssl_cache_init(opts->cache);
@@ -685,9 +685,20 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (opaque_alg != 0) {
- TEST_EQUAL(mbedtls_pk_wrap_as_opaque(cert->pkey, &key_slot,
- opaque_alg, opaque_usage,
- opaque_alg2), 0);
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+ /* Use a fake key usage to get a successful initial guess for the PSA attributes. */
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(cert->pkey, PSA_KEY_USAGE_SIGN_HASH,
+ &key_attr), 0);
+ /* Then manually usage, alg and alg2 as requested by the test. */
+ psa_set_key_usage_flags(&key_attr, opaque_usage);
+ psa_set_key_algorithm(&key_attr, opaque_alg);
+ if (opaque_alg2 != PSA_ALG_NONE) {
+ psa_set_key_enrollment_algorithm(&key_attr, opaque_alg2);
+ }
+ TEST_EQUAL(mbedtls_pk_import_into_psa(cert->pkey, &key_attr, &key_slot), 0);
+ mbedtls_pk_free(cert->pkey);
+ mbedtls_pk_init(cert->pkey);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(cert->pkey, key_slot), 0);
}
#else
(void) opaque_alg;
@@ -744,7 +755,7 @@
mbedtls_ssl_init(&(ep->ssl));
mbedtls_ssl_config_init(&(ep->conf));
- mbedtls_ssl_conf_rng(&(ep->conf), rng_get, NULL);
+ mbedtls_ssl_conf_rng(&(ep->conf), mbedtls_test_random, NULL);
TEST_ASSERT(mbedtls_ssl_conf_get_user_data_p(&ep->conf) == NULL);
TEST_EQUAL(mbedtls_ssl_conf_get_user_data_n(&ep->conf), 0);
@@ -815,6 +826,19 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_conf_early_data(&(ep->conf), options->early_data);
+#if defined(MBEDTLS_SSL_SRV_C)
+ if (endpoint_type == MBEDTLS_SSL_IS_SERVER &&
+ (options->max_early_data_size >= 0)) {
+ mbedtls_ssl_conf_max_early_data_size(&(ep->conf),
+ options->max_early_data_size);
+ }
+#endif
+#if defined(MBEDTLS_SSL_ALPN)
+ /* check that alpn_list contains at least one valid entry */
+ if (options->alpn_list[0] != NULL) {
+ mbedtls_ssl_conf_alpn_protocols(&(ep->conf), options->alpn_list);
+ }
+#endif
#endif
#if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C)
@@ -1775,7 +1799,13 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
session->max_early_data_size = 0x87654321;
-#endif
+#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C)
+ int ret = mbedtls_ssl_session_set_ticket_alpn(session, "ALPNExample");
+ if (ret != 0) {
+ return -1;
+ }
+#endif /* MBEDTLS_SSL_ALPN && MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index fd2fc0a..ceb31af 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1629,7 +1629,7 @@
fi
if [ "$LIST_TESTS" -gt 0 ]; then
- printf "%s\n" "$NAME"
+ printf "%s\n" "${TEST_SUITE_NAME:-ssl-opt};$NAME"
return
fi
@@ -2047,64 +2047,6 @@
-s "Protocol is DTLSv1.2" \
-s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"
-# GnuTLS can be setup to send a ClientHello containing a supported versions
-# extension proposing TLS 1.2 (preferred) and then TLS 1.3. In that case,
-# a TLS 1.3 and TLS 1.2 capable server is supposed to negotiate TLS 1.2 and
-# to indicate in the ServerHello that it downgrades from TLS 1.3. The GnuTLS
-# client then detects the downgrade indication and aborts the handshake even
-# if TLS 1.2 was its preferred version. Keeping the test even if the
-# handshake fails eventually as it exercices parts of the Mbed TLS
-# implementation that are otherwise not exercised.
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-run_test "Server selecting TLS 1.2 over TLS 1.3" \
- "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \
- "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \
- 1 \
- -c "Detected downgrade to TLS 1.2 from TLS 1.3"
-
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-run_test "Server selecting TLS 1.2" \
- "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \
- "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \
- 0 \
- -s "Protocol is TLSv1.2" \
- -c "HTTP/1.0 200 OK"
-
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-run_test "Server selecting TLS 1.3, over TLS 1.2 if supported" \
- "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \
- "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:%DISABLE_TLS13_COMPAT_MODE" \
- 0 \
- -s "Protocol is TLSv1.3" \
- -c "HTTP/1.0 200 OK"
-
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
-run_test "Server selecting TLS 1.3, over TLS 1.2 if supported - compat mode enabled" \
- "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \
- "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2" \
- 0 \
- -s "Protocol is TLSv1.3" \
- -c "HTTP/1.0 200 OK"
-
requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "TLS client auth: required" \
"$P_SRV auth_mode=required" \
@@ -6929,36 +6871,456 @@
0 \
-c "Read from server: .* bytes read"
-# Tests for version negotiation
+# Tests for version negotiation, MbedTLS client and server
-run_test "Version check: all -> 1.2" \
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Version negotiation check m->m: 1.2 / 1.2 -> 1.2" \
"$P_SRV" \
- "$P_CLI force_version=tls12" \
+ "$P_CLI" \
0 \
-S "mbedtls_ssl_handshake returned" \
-C "mbedtls_ssl_handshake returned" \
-s "Protocol is TLSv1.2" \
-c "Protocol is TLSv1.2"
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "Not supported version check: cli TLS 1.0" \
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Version negotiation check m->m: 1.2 (max=1.2) / 1.2 (max=1.2) -> 1.2" \
+ "$P_SRV max_version=tls12" \
+ "$P_CLI max_version=tls12" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2" \
+ -c "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "Version negotiation check m->m: 1.3 / 1.3 -> 1.3" \
+ "$P_SRV" \
+ "$P_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3" \
+ -c "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Version negotiation check m->m: 1.3 (min=1.3) / 1.3 (min=1.3) -> 1.3" \
+ "$P_SRV min_version=tls13" \
+ "$P_CLI min_version=tls13" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3" \
+ -c "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Version negotiation check m->m: 1.2+1.3 / 1.2+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$P_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3" \
+ -c "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Version negotiation check m->m: 1.2+1.3 / 1.3 (min=1.3) -> 1.3" \
+ "$P_SRV min_version=tls13" \
+ "$P_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3" \
+ -c "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Version negotiation check m->m: 1.2+1.3 / 1.2 (max=1.2) -> 1.2" \
+ "$P_SRV max_version=tls12" \
+ "$P_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2" \
+ -c "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Version negotiation check m->m: 1.2 (max=1.2) / 1.2+1.3 -> 1.2" \
+ "$P_SRV" \
+ "$P_CLI max_version=tls12" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2" \
+ -c "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Version negotiation check m->m: 1.3 (min=1.3) / 1.2+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$P_CLI min_version=tls13" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -C "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3" \
+ -c "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check m->m: 1.2 (max=1.2) / 1.3 (min=1.3)" \
+ "$P_SRV min_version=tls13" \
+ "$P_CLI max_version=tls12" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.2" \
+ -C "Protocol is TLSv1.2" \
+ -S "Protocol is TLSv1.3" \
+ -C "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check m->m: 1.3 (min=1.3) / 1.2 (max=1.2)" \
+ "$P_SRV max_version=tls12" \
+ "$P_CLI min_version=tls13" \
+ 1 \
+ -s "The handshake negotiation failed" \
+ -S "Protocol is TLSv1.2" \
+ -C "Protocol is TLSv1.2" \
+ -S "Protocol is TLSv1.3" \
+ -C "Protocol is TLSv1.3"
+
+# Tests of version negotiation on server side against GnuTLS client
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_2
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check G->m: 1.2 / 1.2+(1.3) -> 1.2" \
+ "$P_SRV" \
+ "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check G->m: 1.2 / 1.2 (max=1.2) -> 1.2" \
+ "$P_SRV max_version=tls12" \
+ "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check G->m: 1.3 / (1.2)+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check G->m: 1.3 / 1.3 (min=1.3) -> 1.3" \
+ "$P_SRV min_version=tls13" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check G->m: 1.2+1.3 / (1.2)+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$G_NEXT_CLI localhost --priority=NORMAL" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_gnutls_next_disable_tls13_compat
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Server version nego check G->m (no compat): 1.2+1.3 / (1.2)+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:%DISABLE_TLS13_COMPAT_MODE" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+# GnuTLS can be setup to send a ClientHello containing a supported versions
+# extension proposing TLS 1.2 (preferred) and then TLS 1.3. In that case,
+# a TLS 1.3 and TLS 1.2 capable server is supposed to negotiate TLS 1.2 and
+# to indicate in the ServerHello that it downgrades from TLS 1.3. The GnuTLS
+# client then detects the downgrade indication and aborts the handshake even
+# if TLS 1.2 was its preferred version. Keeping the test even if the
+# handshake fails eventually as it exercices parts of the Mbed TLS
+# implementation that are otherwise not exercised.
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check G->m: [1.2]+1.3 / 1.2+1.3 -> 1.2" \
+ "$P_SRV" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \
+ 1 \
+ -c "Detected downgrade to TLS 1.2 from TLS 1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check G->m: 1.2+1.3 / 1.3 (min=1.3) -> 1.3" \
+ "$P_SRV min_version=tls13" \
+ "$G_NEXT_CLI localhost --priority=NORMAL" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check G->m: 1.2+1.3 / 1.2 -> 1.2" \
+ "$P_SRV" \
+ "$G_NEXT_CLI localhost --priority=NORMAL" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check G->m: 1.2+1.3 / 1.2 (max=1.2) -> 1.2" \
+ "$P_SRV max_version=tls12" \
+ "$G_NEXT_CLI localhost --priority=NORMAL" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test "Not supported version check G->m: 1.0 / (1.2)+(1.3)" \
"$P_SRV" \
"$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.0" \
1 \
-s "Handshake protocol not within min/max boundaries" \
- -c "Error in protocol version" \
- -S "Protocol is TLSv1.0" \
- -C "Handshake was completed"
+ -S "Protocol is TLSv1.0"
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "Not supported version check: cli TLS 1.1" \
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test "Not supported version check G->m: 1.1 / (1.2)+(1.3)" \
"$P_SRV" \
"$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.1" \
1 \
-s "Handshake protocol not within min/max boundaries" \
- -c "Error in protocol version" \
- -S "Protocol is TLSv1.1" \
- -C "Handshake was completed"
+ -S "Protocol is TLSv1.1"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "Not supported version check G->m: 1.2 / 1.3" \
+ "$P_SRV" \
+ "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.2"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check G->m: 1.3 / 1.2" \
+ "$P_SRV" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \
+ 1 \
+ -S "Handshake protocol not within min/max boundaries" \
+ -s "The handshake negotiation failed" \
+ -S "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check G->m: 1.2 / 1.3 (min=1.3)" \
+ "$P_SRV min_version=tls13" \
+ "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check G->m: 1.3 / 1.2 (max=1.2)" \
+ "$P_SRV max_version=tls12" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \
+ 1 \
+ -S "Handshake protocol not within min/max boundaries" \
+ -s "The handshake negotiation failed" \
+ -S "Protocol is TLSv1.3"
+
+# Tests of version negotiation on server side against OpenSSL client
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_2
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check O->m: 1.2 / 1.2+(1.3) -> 1.2" \
+ "$P_SRV" \
+ "$O_NEXT_CLI -tls1_2" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check O->m: 1.2 / 1.2 (max=1.2) -> 1.2" \
+ "$P_SRV max_version=tls12" \
+ "$O_NEXT_CLI -tls1_2" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check O->m: 1.3 / (1.2)+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$O_NEXT_CLI -tls1_3" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check O->m: 1.3 / 1.3 (min=1.3) -> 1.3" \
+ "$P_SRV min_version=tls13" \
+ "$O_NEXT_CLI -tls1_3" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check O->m: 1.2+1.3 / (1.2)+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$O_NEXT_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "Server version nego check O->m (no compat): 1.2+1.3 / (1.2)+1.3 -> 1.3" \
+ "$P_SRV" \
+ "$O_NEXT_CLI -no_middlebox" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_openssl_tls1_3_with_compatible_ephemeral
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+run_test "Server version nego check O->m: 1.2+1.3 / 1.3 (min=1.3) -> 1.3" \
+ "$P_SRV min_version=tls13" \
+ "$O_NEXT_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.3"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check O->m: 1.2+1.3 / 1.2 -> 1.2" \
+ "$P_SRV" \
+ "$O_NEXT_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
+run_test "Server version nego check O->m: 1.2+1.3 / 1.2 (max=1.2) -> 1.2" \
+ "$P_SRV max_version=tls12" \
+ "$O_NEXT_CLI" \
+ 0 \
+ -S "mbedtls_ssl_handshake returned" \
+ -s "Protocol is TLSv1.2"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test "Not supported version check O->m: 1.0 / (1.2)+(1.3)" \
+ "$P_SRV" \
+ "$O_CLI -tls1" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.0"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test "Not supported version check O->m: 1.1 / (1.2)+(1.3)" \
+ "$P_SRV" \
+ "$O_CLI -tls1_1" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.1"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "Not supported version check O->m: 1.2 / 1.3" \
+ "$P_SRV" \
+ "$O_NEXT_CLI -tls1_2" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.2"
+
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check O->m: 1.3 / 1.2" \
+ "$P_SRV" \
+ "$O_NEXT_CLI -tls1_3" \
+ 1 \
+ -S "Handshake protocol not within min/max boundaries" \
+ -s "The handshake negotiation failed" \
+ -S "Protocol is TLSv1.3"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check O->m: 1.2 / 1.3 (min=1.3)" \
+ "$P_SRV min_version=tls13" \
+ "$O_NEXT_CLI -tls1_2" \
+ 1 \
+ -s "Handshake protocol not within min/max boundaries" \
+ -S "Protocol is TLSv1.2"
+
+requires_all_configs_enabled MBEDTLS_SSL_SRV_C \
+ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3
+run_test "Not supported version check O->m: 1.3 / 1.2 (max=1.2)" \
+ "$P_SRV max_version=tls12" \
+ "$O_NEXT_CLI -tls1_3" \
+ 1 \
+ -S "Handshake protocol not within min/max boundaries" \
+ -s "The handshake negotiation failed" \
+ -S "Protocol is TLSv1.3"
+
+# Tests of version negotiation on client side against GnuTLS and OpenSSL server
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Not supported version check: srv max TLS 1.0" \
@@ -6980,6 +7342,88 @@
-S "Version: TLS1.1" \
-C "Protocol is TLSv1.1"
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+skip_handshake_stage_check
+requires_gnutls_tls1_3
+run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.0" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0 -d 4" \
+ "$P_CLI debug_level=4" \
+ 1 \
+ -s "Client's version: 3.3" \
+ -S "Version: TLS1.0" \
+ -C "Protocol is TLSv1.0"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+skip_handshake_stage_check
+requires_gnutls_tls1_3
+run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.1" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1 -d 4" \
+ "$P_CLI debug_level=4" \
+ 1 \
+ -s "Client's version: 3.3" \
+ -S "Version: TLS1.1" \
+ -C "Protocol is TLSv1.1"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+skip_handshake_stage_check
+requires_gnutls_tls1_3
+run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.2" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 -d 4" \
+ "$P_CLI force_version=tls13 debug_level=4" \
+ 1 \
+ -s "Client's version: 3.3" \
+ -c "is a fatal alert message (msg 40)" \
+ -S "Version: TLS1.2" \
+ -C "Protocol is TLSv1.2"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+skip_handshake_stage_check
+requires_openssl_next
+run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.0" \
+ "$O_NEXT_SRV -msg -tls1" \
+ "$P_CLI debug_level=4" \
+ 1 \
+ -s "fatal protocol_version" \
+ -c "is a fatal alert message (msg 70)" \
+ -S "Version: TLS1.0" \
+ -C "Protocol : TLSv1.0"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+skip_handshake_stage_check
+requires_openssl_next
+run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.1" \
+ "$O_NEXT_SRV -msg -tls1_1" \
+ "$P_CLI debug_level=4" \
+ 1 \
+ -s "fatal protocol_version" \
+ -c "is a fatal alert message (msg 70)" \
+ -S "Version: TLS1.1" \
+ -C "Protocol : TLSv1.1"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+skip_handshake_stage_check
+requires_openssl_next
+run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.2" \
+ "$O_NEXT_SRV -msg -tls1_2" \
+ "$P_CLI force_version=tls13 debug_level=4" \
+ 1 \
+ -s "fatal protocol_version" \
+ -c "is a fatal alert message (msg 70)" \
+ -S "Version: TLS1.2" \
+ -C "Protocol : TLSv1.2"
+
# Tests for ALPN extension
requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
@@ -11866,103 +12310,6 @@
-s "HTTP/1.0 200 OK" \
-s "Application Layer Protocol is h2"
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-skip_handshake_stage_check
-requires_gnutls_tls1_3
-run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.0" \
- "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0 -d 4" \
- "$P_CLI debug_level=4" \
- 1 \
- -s "Client's version: 3.3" \
- -S "Version: TLS1.0" \
- -C "Protocol is TLSv1.0"
-
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-skip_handshake_stage_check
-requires_gnutls_tls1_3
-run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.1" \
- "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1 -d 4" \
- "$P_CLI debug_level=4" \
- 1 \
- -s "Client's version: 3.3" \
- -S "Version: TLS1.1" \
- -C "Protocol is TLSv1.1"
-
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-skip_handshake_stage_check
-requires_gnutls_tls1_3
-run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.2" \
- "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 -d 4" \
- "$P_CLI force_version=tls13 debug_level=4" \
- 1 \
- -s "Client's version: 3.3" \
- -c "is a fatal alert message (msg 40)" \
- -S "Version: TLS1.2" \
- -C "Protocol is TLSv1.2"
-
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-skip_handshake_stage_check
-requires_openssl_next
-run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.0" \
- "$O_NEXT_SRV -msg -tls1" \
- "$P_CLI debug_level=4" \
- 1 \
- -s "fatal protocol_version" \
- -c "is a fatal alert message (msg 70)" \
- -S "Version: TLS1.0" \
- -C "Protocol : TLSv1.0"
-
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-skip_handshake_stage_check
-requires_openssl_next
-run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.1" \
- "$O_NEXT_SRV -msg -tls1_1" \
- "$P_CLI debug_level=4" \
- 1 \
- -s "fatal protocol_version" \
- -c "is a fatal alert message (msg 70)" \
- -S "Version: TLS1.1" \
- -C "Protocol : TLSv1.1"
-
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-skip_handshake_stage_check
-requires_openssl_next
-run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.2" \
- "$O_NEXT_SRV -msg -tls1_2" \
- "$P_CLI force_version=tls13 debug_level=4" \
- 1 \
- -s "fatal protocol_version" \
- -c "is a fatal alert message (msg 70)" \
- -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
@@ -13414,125 +13761,6 @@
-c "no suitable signature algorithm"
requires_openssl_tls1_3_with_compatible_ephemeral
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3: NewSessionTicket: Basic check, m->O" \
- "$O_NEXT_SRV -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 4" \
- "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \
- 0 \
- -c "Protocol is TLSv1.3" \
- -c "got new session ticket." \
- -c "Saving session for reuse... ok" \
- -c "Reconnecting with saved session" \
- -c "HTTP/1.0 200 ok"
-
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3: NewSessionTicket: Basic check, m->G" \
- "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \
- "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \
- 0 \
- -c "Protocol is TLSv1.3" \
- -c "got new session ticket." \
- -c "Saving session for reuse... ok" \
- -c "Reconnecting with saved session" \
- -c "HTTP/1.0 200 OK" \
- -s "This is a resumed session"
-
-requires_openssl_tls1_3_with_compatible_ephemeral
-requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-# https://github.com/openssl/openssl/issues/10714
-# Until now, OpenSSL client does not support reconnect.
-skip_next_test
-run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \
- "$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \
- 0 \
- -s "=> write NewSessionTicket msg" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH"
-
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \
- "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \
- 0 \
- -c "Connecting again- trying to resume previous session" \
- -c "NEW SESSION TICKET (4) was received" \
- -s "=> write NewSessionTicket msg" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \
- -s "key exchange mode: ephemeral" \
- -s "key exchange mode: psk_ephemeral" \
- -s "found pre_shared_key extension"
-
-requires_gnutls_tls1_3
-requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-# Test the session resumption when the cipher suite for the original session is
-# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not
-# 256 bits long as with all the other TLS 1.3 cipher suites.
-requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
-run_test "TLS 1.3: NewSessionTicket: Basic check with AES-256-GCM only, G->m" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \
- "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \
- 0 \
- -c "Connecting again- trying to resume previous session" \
- -c "NEW SESSION TICKET (4) was received" \
- -s "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \
- -s "=> write NewSessionTicket msg" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \
- -s "key exchange mode: ephemeral" \
- -s "key exchange mode: psk_ephemeral" \
- -s "found pre_shared_key extension"
-
-requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \
- "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
- 0 \
- -c "Protocol is TLSv1.3" \
- -c "got new session ticket ( 3 )" \
- -c "Saving session for reuse... ok" \
- -c "Reconnecting with saved session" \
- -c "HTTP/1.0 200 OK" \
- -s "=> write NewSessionTicket msg" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \
- -s "key exchange mode: ephemeral" \
- -s "key exchange mode: psk_ephemeral" \
- -s "found pre_shared_key extension"
-
-requires_openssl_tls1_3_with_compatible_ephemeral
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
@@ -13563,51 +13791,6 @@
-c "Protocol is TLSv1.2" \
-c "HTTP/1.0 200 [Oo][Kk]"
-requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \
- sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
- "$P_CLI debug_level=4 server_name=localhost reco_mode=1 reconnect=1" \
- 0 \
- -c "Protocol is TLSv1.3" \
- -c "got new session ticket." \
- -c "Saving session for reuse... ok" \
- -c "Reconnecting with saved session" \
- -c "HTTP/1.0 200 OK" \
- -s "=> write NewSessionTicket msg" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \
- -s "key exchange mode: ephemeral" \
- -s "key exchange mode: psk_ephemeral" \
- -s "found pre_shared_key extension"
-
-requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
-requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_enabled MBEDTLS_DEBUG_C
-requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \
- "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \
- sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
- "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \
- 1 \
- -c "Protocol is TLSv1.3" \
- -c "got new session ticket." \
- -c "Saving session for reuse... ok" \
- -c "Reconnecting with saved session" \
- -c "Hostname mismatch the session ticket, disable session resumption." \
- -s "=> write NewSessionTicket msg" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
- -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH"
-
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function
index 50be2d2..f3a64e1 100644
--- a/tests/suites/test_suite_bignum.function
+++ b/tests/suites/test_suite_bignum.function
@@ -966,6 +966,45 @@
/* END_CASE */
/* BEGIN_CASE */
+void mpi_exp_mod_min_RR(char *input_A, char *input_E,
+ char *input_N, char *input_X,
+ int exp_result)
+{
+ mbedtls_mpi A, E, N, RR, Z, X;
+ int res;
+ mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
+ mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
+
+ TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
+ TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
+ TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
+ TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
+
+ TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
+ TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
+ /* The objective of this test is to check that exp_mod defends
+ * against a smaller RR. */
+ TEST_LE_U(RR.n, N.n - 1);
+
+ res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
+ /* We know that exp_mod internally needs RR to be as large as N.
+ * Validate that it is the case now, otherwise there was probably
+ * a buffer overread. */
+ TEST_EQUAL(RR.n, N.n);
+
+ TEST_EQUAL(res, exp_result);
+ if (res == 0) {
+ TEST_EQUAL(sign_is_valid(&Z), 1);
+ TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
+ }
+
+exit:
+ mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
+ mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mpi_exp_mod(char *input_A, char *input_E,
char *input_N, char *input_X,
int exp_result)
diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data
index c53e42a..eb55dbe 100644
--- a/tests/suites/test_suite_bignum.misc.data
+++ b/tests/suites/test_suite_bignum.misc.data
@@ -1362,6 +1362,9 @@
Test mbedtls_mpi_exp_mod: 10 ^ 0 (1 limb) mod 9
mpi_exp_mod:"0a":"00":"09":"1":0
+Test mbedtls_mpi_exp_mod: -3 ^ 3 mod 27
+mpi_exp_mod:"-3":"3":"1b":"1b":0
+
Test mbedtls_mpi_exp_mod: MAX_SIZE exponent
mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:10:"":0
@@ -1391,6 +1394,14 @@
depends_on:MPI_MAX_BITS_LARGER_THAN_792
mpi_exp_mod:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
+Test mbedtls_mpi_exp_mod (N.n=3, RR.n=1 on 32 bit)
+depends_on:MBEDTLS_HAVE_INT32
+mpi_exp_mod_min_RR:"10":"2":"10000000100000001":"100":0
+
+Test mbedtls_mpi_exp_mod (N.n=3, RR.n=1 on 64 bit)
+depends_on:MBEDTLS_HAVE_INT64
+mpi_exp_mod_min_RR:"10":"2":"100000000000000010000000000000001":"100":0
+
Base test GCD #1
mpi_gcd:"2b5":"261":"15"
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index eeefc95..70e7bad 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -2,6 +2,7 @@
#include "debug_internal.h"
#include "string.h"
#include "mbedtls/pk.h"
+#include <test/ssl_helpers.h>
struct buffer_data {
char buf[2000];
@@ -65,11 +66,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -103,11 +105,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -138,11 +141,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -175,11 +179,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -214,11 +219,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data
index cc58432..8d06067 100644
--- a/tests/suites/test_suite_ecdh.data
+++ b/tests/suites/test_suite_ecdh.data
@@ -100,3 +100,19 @@
ECDH get_params with mismatched groups: their SECP256R1, our BP256R1
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED
ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+Context get ECP Group #1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecdh_context_grp:MBEDTLS_ECP_DP_SECP256R1
+
+Context get ECP Group #2
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecdh_primitive_random:MBEDTLS_ECP_DP_SECP384R1
+
+Context get ECP Group #3
+depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED
+ecdh_primitive_random:MBEDTLS_ECP_DP_SECP521R1
+
+Context get ECP Group #4
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecdh_primitive_random:MBEDTLS_ECP_DP_CURVE448
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index cc193da..300916f 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -464,3 +464,20 @@
mbedtls_ecp_keypair_free(&their_key);
}
/* END_CASE */
+
+/* BEGIN_CASE */
+void ecdh_context_grp(int id)
+{
+ mbedtls_ecdh_context srv;
+
+ mbedtls_ecdh_init(&srv);
+ TEST_ASSERT(mbedtls_ecdh_setup(&srv, id) == 0);
+
+ /* Test the retrieved group id matches/*/
+ TEST_ASSERT((int) mbedtls_ecdh_get_grp_id(&srv) == id);
+
+exit:
+ mbedtls_ecdh_free(&srv);
+
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 1dd963a..fd63657 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -888,6 +888,109 @@
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
ecp_write_key:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ECP write key ext: secp256r1, nominal
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":32:0
+
+ECP write key ext: secp256r1, output longer by 1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":33:0
+
+ECP write key ext: secp256r1, output short by 1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, output_size=0
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":0:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, top byte = 0, output_size=32
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":32:0
+
+ECP write key ext: secp256r1, top byte = 0, output_size=31
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, top byte = 0, output_size=30
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":30:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, mostly-0 key, output_size=32
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"0000000000000000000000000000000000000000000000000000000000000001":32:0
+
+ECP write key ext: secp256r1, mostly-0 key, output_size=1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"0000000000000000000000000000000000000000000000000000000000000001":1:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, private key not set
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+ECP write key ext: secp384r1, nominal
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":48:0
+
+ECP write key ext: secp384r1, output longer by 1
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":49:0
+
+ECP write key ext: secp384r1, output short by 1
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":47:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, nominal
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":32:0
+
+ECP write key ext: Curve25519, output longer by 1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":33:0
+
+ECP write key ext: Curve25519, output short by 1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, output_size=0
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":0:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, mostly-0 key, output_size=32
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000040":32:0
+
+ECP write key ext: Curve25519, mostly-0 key, output_size=31
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000040":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, private key not set
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+ECP write key ext: Curve448, nominal
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":56:0
+
+ECP write key ext: Curve448, output longer by 1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":57:0
+
+ECP write key ext: Curve448, output short by 1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve448, mostly-0 key, output_size=56
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":56:0
+
+ECP write key ext: Curve448, mostly-0 key, output_size=55
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: group not set
+ecp_write_key_ext:MBEDTLS_ECP_DP_NONE:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits)
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_ECP_NIST_OPTIM
ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100"
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 9cf0ce1..9b5c86f 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1204,29 +1204,46 @@
TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Y, 2), 0);
TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Z, 3), 0);
- if (canonical) {
+ if (canonical && in_key->len == (key.grp.nbits + 7) / 8) {
unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
+ size_t length = 0xdeadbeef;
- ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
- TEST_ASSERT(ret == 0);
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key,
+ &length, buf, in_key->len), 0);
+ TEST_MEMORY_COMPARE(in_key->x, in_key->len,
+ buf, length);
+#if defined(MBEDTLS_TEST_DEPRECATED)
+ memset(buf, 0, sizeof(buf));
+ TEST_EQUAL(mbedtls_ecp_write_key(&key, buf, in_key->len), 0);
TEST_MEMORY_COMPARE(in_key->x, in_key->len,
buf, in_key->len);
+#endif /* MBEDTLS_TEST_DEPRECATED */
} else {
unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
- ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
- TEST_ASSERT(ret == 0);
+ size_t length1 = 0xdeadbeef;
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &length1,
+ export1, sizeof(export1)), 0);
+ TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, length1),
+ expected);
+ size_t length2 = 0xdeadbeef;
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key2, &length2,
+ export2, sizeof(export2)), 0);
+ TEST_MEMORY_COMPARE(export1, length1,
+ export2, length2);
- ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
- TEST_ASSERT(ret == expected);
-
- ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
- TEST_ASSERT(ret == 0);
-
+#if defined(MBEDTLS_TEST_DEPRECATED)
+ memset(export1, 0, sizeof(export1));
+ memset(export2, 0, sizeof(export2));
+ TEST_EQUAL(mbedtls_ecp_write_key(&key, export1, in_key->len), 0);
+ TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len),
+ expected);
+ TEST_EQUAL(mbedtls_ecp_write_key(&key2, export2, in_key->len), 0);
TEST_MEMORY_COMPARE(export1, in_key->len,
export2, in_key->len);
+#endif /* MBEDTLS_TEST_DEPRECATED */
}
}
@@ -1236,7 +1253,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_DEPRECATED */
void ecp_write_key(int grp_id, data_t *in_key,
int exported_size, int expected_ret)
{
@@ -1296,6 +1313,42 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void ecp_write_key_ext(int grp_id, data_t *in_key,
+ int exported_size, int expected_ret)
+{
+ mbedtls_ecp_keypair key;
+ mbedtls_ecp_keypair_init(&key);
+ unsigned char *exported = NULL;
+
+ if (in_key->len != 0) {
+ TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len), 0);
+ } else if (grp_id != MBEDTLS_ECP_DP_NONE) {
+ TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0);
+ }
+
+ TEST_CALLOC(exported, exported_size);
+ size_t olen = 0xdeadbeef;
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &olen, exported, exported_size),
+ expected_ret);
+
+ if (expected_ret == 0) {
+ TEST_EQUAL(olen, (key.grp.nbits + 7) / 8);
+ TEST_LE_U(olen, MBEDTLS_ECP_MAX_BYTES);
+ TEST_MEMORY_COMPARE(in_key->x, in_key->len,
+ exported, olen);
+ } else {
+ /* Robustness check: even in the error case, insist that olen is less
+ * than the buffer size. */
+ TEST_LE_U(olen, exported_size);
+ }
+
+exit:
+ mbedtls_ecp_keypair_free(&key);
+ mbedtls_free(exported);
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBEDTLS_ECP_LIGHT */
void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
{
diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data
index b88bd08..a0dacf0 100644
--- a/tests/suites/test_suite_pk.data
+++ b/tests/suites/test_suite_pk.data
@@ -450,9 +450,13 @@
depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_GENPRIME:MBEDTLS_RSA_GEN_KEY_MIN_BITS >= 512:MBEDTLS_MD_CAN_SHA256
pk_sign_verify:MBEDTLS_PK_RSA:MBEDTLS_RSA_GEN_KEY_MIN_BITS:MBEDTLS_RSA_PKCS_V21:MBEDTLS_MD_SHA256:0:0
-RSA encrypt-decrypt test
+RSA encrypt-decrypt test PKCS1 v1.5
depends_on:MBEDTLS_PKCS1_V15
-pk_rsa_encrypt_decrypt_test:"4E636AF98E40F3ADCFCCB698F4E80B9F":2048:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"3":0
+pk_rsa_encrypt_decrypt_test:"4E636AF98E40F3ADCFCCB698F4E80B9F":2048:MBEDTLS_RSA_PKCS_V15:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"3":0
+
+RSA encrypt-decrypt test PKCS1 v2.1
+depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA1
+pk_rsa_encrypt_decrypt_test:"4E636AF98E40F3ADCFCCB698F4E80B9F":2048:MBEDTLS_RSA_PKCS_V21:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"3":0
RSA decrypt test vector - PKCS1v1.5
depends_on:MBEDTLS_PKCS1_V15
@@ -1527,3 +1531,136 @@
PSA import into PSA: opaque ECC to public, different family (bad)
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:MBEDTLS_TEST_PSA_ECC_HAVE_TWO_FAMILIES:PSA_WANT_ALG_ECDSA
pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY):MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:0:PSA_KEY_TYPE_ECC_PUBLIC_KEY(MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY):MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:0:MBEDTLS_ERR_PK_TYPE_MISMATCH
+
+Copy from PSA: use wrong parameters
+pk_copy_from_psa_fail:
+
+# The following test is only possible for RSA keys and not for EC ones:
+# - for the former it is possible to have an accelerated RSA key in PSA while
+# having RSA_C disabled. Since RSA path is guarded by RSA_C in mbedtls_pk_copy_from_psa(),
+# any attempt to copy that key will fail.
+# - for the latter instead the guard is PK_HAVE_ECC_KEYS which is enabled as soon
+# as there is any curve supported either builtin or in a driver. In a scenario
+# in which a certain EC key is only available through a driver and not as
+# builtin mbedtls_pk_copy_from_psa() uses functions that will all succeed
+# and therefore it will succeed.
+Copy from PSA: accelerated key only, not available as built-in
+pk_copy_from_psa_builtin_fail:
+
+Copy from PSA: valid EC (SECP_R1_256 + ECDSA + ANY_HASH)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)
+
+Copy from PSA: valid EC (SECP_R1_256 + ECDSA + SHA_256)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_256)
+
+Copy from PSA: valid EC (SECP_R1_256 + ECDSA + SHA_512)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_512)
+
+Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + ANY_HASH)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH)
+
+Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_256)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)
+
+Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_512)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_CAN_SHA512
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512)
+
+Copy from PSA: valid EC (SECP_R1_256 + ECDSA_ANY)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA_ANY
+
+Copy from PSA: valid EC (SECP_R1_521 + ECDSA + SHA_256)
+depends_on:MBEDTLS_ECP_HAVE_SECP521R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"005dbb8e12240a62932b88cdd93c31cdd8873a2c15e40cc3c9f8e695b77fae015a44fe5267ef7868cb28cfb9579282fe060de44fe6de26f74a0d94afdaa870befbc5":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_256)
+
+Copy from PSA: valid EC (SECP_K1_256 + ECDSA + SHA_256)
+depends_on:MBEDTLS_ECP_HAVE_SECP256K1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"7154f04fcc79ac9df1652dcf99031610592b2b27f74f5985690a987357ba0428":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1):PSA_ALG_ECDSA(PSA_ALG_SHA_256)
+
+# The key's algorithm only allows ECDH, but pk_copy_from_psa() ignores this information
+# when building the PK context.
+Copy from PSA: valid EC, wrong alg (SECP_R1_256 + ECDH)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDH
+
+# The key's algorithm is absolutely wrong for an EC key, but pk_copy_from_psa()
+# ignores this information when building the PK context.
+Copy from PSA: valid EC, wrong alg (SECP_R1_256 + CMAC)
+depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_CMAC
+
+Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)
+
+Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_512)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512)
+
+Copy from PSA: valid RSA (PKCS1V15_CRYPT)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT
+
+Copy from PSA: valid RSA (OAEP + SHA_256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256)
+
+Copy from PSA: valid RSA (OAEP + SHA_512)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512)
+
+Copy from PSA: valid RSA (PSS_ANY_SALT + ANY_HASH)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)
+
+Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256)
+
+Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_512)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512)
+
+Copy from PSA: valid RSA (PSS + ANY_HASH)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH)
+
+Copy from PSA: valid RSA (PSS + SHA_256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)
+
+Copy from PSA: valid RSA (PSS + SHA_512)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_SHA_512)
+
+Copy from PSA: valid RSA, PSA_ALG_NONE
+depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_NONE
+
+# Key's algorithm is wrong for an RSA key, but pk_copy_from_psa() accepts
+# it anyway.
+Copy from PSA: valid RSA, wrong alg (CMAC)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_ALG_FOR_TEST
+pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_CMAC
+
+Copy from PSA: non-exportable -> public, RSA
+depends_on:MBEDTLS_RSA_C
+pk_copy_public_from_psa:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR
+
+Copy from PSA: non-exportable -> public, SECP_R1_256
+depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_ECP_HAVE_SECP256R1
+pk_copy_public_from_psa:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)
+
+Copy from PSA: non-exportable -> public, Curve25519
+depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_ECP_HAVE_CURVE25519
+pk_copy_public_from_psa:"a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 5ebe146..7df9aa9 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -1,5 +1,6 @@
/* BEGIN_HEADER */
#include "mbedtls/pk.h"
+#include "mbedtls/psa_util.h"
#include "pk_internal.h"
/* For error codes */
@@ -8,6 +9,7 @@
#include "mbedtls/ecp.h"
#include "mbedtls/error.h"
#include "mbedtls/rsa.h"
+#include "rsa_internal.h"
#include "pk_internal.h"
#include <limits.h>
@@ -167,6 +169,19 @@
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_CURVE_BITS 0
#endif
+/* Get an available MD alg to be used in sign/verify tests. */
+#if defined(MBEDTLS_MD_CAN_SHA1)
+#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA1
+#elif defined(MBEDTLS_MD_CAN_SHA224)
+#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA224
+#elif defined(MBEDTLS_MD_CAN_SHA256)
+#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA256
+#elif defined(MBEDTLS_MD_CAN_SHA384)
+#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA384
+#elif defined(MBEDTLS_MD_CAN_SHA512)
+#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA512
+#endif
+
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static int pk_genkey_ec(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
{
@@ -307,6 +322,83 @@
expected_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
return expected_usage;
}
+
+#define RSA_WRITE_PUBKEY_MAX_SIZE \
+ PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)
+#define ECP_WRITE_PUBKEY_MAX_SIZE \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+static int pk_public_same(const mbedtls_pk_context *pk1,
+ const mbedtls_pk_context *pk2)
+{
+ int ok = 0;
+
+ mbedtls_pk_type_t type = mbedtls_pk_get_type(pk1);
+ TEST_EQUAL(type, mbedtls_pk_get_type(pk2));
+
+ switch (type) {
+#if defined(MBEDTLS_RSA_C)
+ case MBEDTLS_PK_RSA:
+ {
+ const mbedtls_rsa_context *rsa1 = mbedtls_pk_rsa(*pk1);
+ const mbedtls_rsa_context *rsa2 = mbedtls_pk_rsa(*pk2);
+ TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa1),
+ mbedtls_rsa_get_padding_mode(rsa2));
+ TEST_EQUAL(mbedtls_rsa_get_md_alg(rsa1),
+ mbedtls_rsa_get_md_alg(rsa2));
+ unsigned char buf1[RSA_WRITE_PUBKEY_MAX_SIZE];
+ unsigned char *p1 = buf1 + sizeof(buf1);
+ int len1 = mbedtls_rsa_write_pubkey(rsa1, buf1, &p1);
+ TEST_LE_U(0, len1);
+ unsigned char buf2[RSA_WRITE_PUBKEY_MAX_SIZE];
+ unsigned char *p2 = buf2 + sizeof(buf2);
+ int len2 = mbedtls_rsa_write_pubkey(rsa2, buf2, &p2);
+ TEST_LE_U(0, len2);
+ TEST_MEMORY_COMPARE(p1, len1, p2, len2);
+ break;
+ }
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
+ case MBEDTLS_PK_ECKEY:
+ case MBEDTLS_PK_ECKEY_DH:
+ case MBEDTLS_PK_ECDSA:
+ {
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ TEST_MEMORY_COMPARE(pk1->pub_raw, pk1->pub_raw_len,
+ pk2->pub_raw, pk2->pub_raw_len);
+ TEST_EQUAL(pk1->ec_family, pk2->ec_family);
+ TEST_EQUAL(pk1->ec_bits, pk2->ec_bits);
+
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ const mbedtls_ecp_keypair *ec1 = mbedtls_pk_ec_ro(*pk1);
+ const mbedtls_ecp_keypair *ec2 = mbedtls_pk_ec_ro(*pk2);
+ TEST_EQUAL(mbedtls_ecp_keypair_get_group_id(ec1),
+ mbedtls_ecp_keypair_get_group_id(ec2));
+ unsigned char buf1[ECP_WRITE_PUBKEY_MAX_SIZE];
+ size_t len1 = 99999991;
+ TEST_EQUAL(mbedtls_ecp_write_public_key(
+ ec1, MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &len1, buf1, sizeof(buf1)), 0);
+ unsigned char buf2[ECP_WRITE_PUBKEY_MAX_SIZE];
+ size_t len2 = 99999992;
+ TEST_EQUAL(mbedtls_ecp_write_public_key(
+ ec2, MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &len2, buf2, sizeof(buf2)), 0);
+ TEST_MEMORY_COMPARE(buf1, len1, buf2, len2);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ }
+ break;
+#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
+
+ default:
+ TEST_FAIL("Unsupported pk type in pk_public_same");
+ }
+
+ ok = 1;
+
+exit:
+ return ok;
+}
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_RSA_C)
@@ -425,7 +517,110 @@
}
#endif
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+/* Create a new PSA key which will contain only the public part of the private
+ * key which is provided in input. For this new key:
+ * - Type is the public counterpart of the private key.
+ * - Usage is the copied from the original private key, but the PSA_KEY_USAGE_EXPORT
+ * flag is removed. This is to prove that mbedtls_pk_copy_from_psa() doesn't
+ * require the key to have the EXPORT flag.
+ * - Algorithm is copied from the original key pair.
+ */
+static mbedtls_svc_key_id_t psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id)
+{
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t type;
+ psa_algorithm_t alg;
+ psa_key_usage_t usage;
+ unsigned char pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
+ size_t pub_key_len;
+ mbedtls_svc_key_id_t pub_key = MBEDTLS_SVC_KEY_ID_INIT;
+
+ /* Get attributes from the private key. */
+ PSA_ASSERT(psa_get_key_attributes(priv_id, &attributes));
+ type = psa_get_key_type(&attributes);
+ usage = psa_get_key_usage_flags(&attributes);
+ alg = psa_get_key_algorithm(&attributes);
+ psa_reset_key_attributes(&attributes);
+
+ /* Export the public key and then import it in a new slot. */
+ PSA_ASSERT(psa_export_public_key(priv_id, pub_key_buf, sizeof(pub_key_buf), &pub_key_len));
+
+ /* Notes:
+ * - psa_import_key() automatically determines the key's bit length
+ * from the provided key data. That's why psa_set_key_bits() is not used
+ * below.
+ */
+ type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type);
+ usage &= ~PSA_KEY_USAGE_EXPORT;
+ psa_set_key_type(&attributes, type);
+ psa_set_key_usage_flags(&attributes, usage);
+ psa_set_key_algorithm(&attributes, alg);
+
+ PSA_ASSERT(psa_import_key(&attributes, pub_key_buf, pub_key_len, &pub_key));
+
+exit:
+ psa_reset_key_attributes(&attributes);
+ return pub_key;
+}
+
+/* Create a copy of a PSA key with same usage and algorithm policy and destroy
+ * the original one. */
+mbedtls_svc_key_id_t psa_copy_and_destroy(mbedtls_svc_key_id_t orig_key_id)
+{
+ psa_key_attributes_t orig_attr = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_attributes_t new_attr = PSA_KEY_ATTRIBUTES_INIT;
+ mbedtls_svc_key_id_t new_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+
+ PSA_ASSERT(psa_get_key_attributes(orig_key_id, &orig_attr));
+ psa_set_key_usage_flags(&new_attr, psa_get_key_usage_flags(&orig_attr));
+ psa_set_key_algorithm(&new_attr, psa_get_key_algorithm(&orig_attr));
+
+ PSA_ASSERT(psa_copy_key(orig_key_id, &new_attr, &new_key_id));
+ psa_destroy_key(orig_key_id);
+
+exit:
+ psa_reset_key_attributes(&orig_attr);
+ psa_reset_key_attributes(&new_attr);
+ return new_key_id;
+}
+
+psa_status_t pk_psa_import_key(unsigned char *key_data, size_t key_len,
+ psa_key_type_t type, psa_key_usage_t usage,
+ psa_algorithm_t alg, mbedtls_svc_key_id_t *key)
+{
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t status;
+
+ *key = MBEDTLS_SVC_KEY_ID_INIT;
+
+ /* Note: psa_import_key() automatically determines the key's bit length
+ * from the provided key data. That's why psa_set_key_bits() is not used below. */
+ psa_set_key_usage_flags(&attributes, usage);
+ psa_set_key_algorithm(&attributes, alg);
+ psa_set_key_type(&attributes, type);
+ status = psa_import_key(&attributes, key_data, key_len, key);
+
+ return status;
+}
+
+psa_status_t pk_psa_genkey_generic(psa_key_type_t type, size_t bits,
+ psa_key_usage_t usage, psa_algorithm_t alg,
+ mbedtls_svc_key_id_t *key)
+{
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t status;
+
+ *key = MBEDTLS_SVC_KEY_ID_INIT;
+
+ psa_set_key_usage_flags(&attributes, usage);
+ psa_set_key_algorithm(&attributes, alg);
+ psa_set_key_type(&attributes, type);
+ psa_set_key_bits(&attributes, bits);
+ status = psa_generate_key(&attributes, key);
+
+ return status;
+}
/*
* Generate an ECC key using PSA and return the key identifier of that key,
@@ -434,19 +629,12 @@
*/
mbedtls_svc_key_id_t pk_psa_genkey_ecc(void)
{
- mbedtls_svc_key_id_t key;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- const psa_key_type_t type =
- PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
- const size_t bits = 256;
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, type);
- psa_set_key_bits(&attributes, bits);
- PSA_ASSERT(psa_generate_key(&attributes, &key));
+ pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256,
+ PSA_KEY_USAGE_SIGN_HASH, PSA_ALG_ECDSA(PSA_ALG_SHA_256),
+ &key);
-exit:
return key;
}
@@ -456,21 +644,14 @@
*/
mbedtls_svc_key_id_t pk_psa_genkey_rsa(void)
{
- mbedtls_svc_key_id_t key;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- const psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
- const size_t bits = 1024;
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
- psa_set_key_type(&attributes, type);
- psa_set_key_bits(&attributes, bits);
- PSA_ASSERT(psa_generate_key(&attributes, &key));
+ pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, 1024, PSA_KEY_USAGE_SIGN_HASH,
+ PSA_ALG_RSA_PKCS1V15_SIGN_RAW, &key);
-exit:
return key;
}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_PSA_CRYPTO_C */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -482,7 +663,7 @@
void pk_psa_utils(int key_is_rsa)
{
mbedtls_pk_context pk, pk2;
- mbedtls_svc_key_id_t key;
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const char * const name = "Opaque";
@@ -836,6 +1017,7 @@
mbedtls_pk_context pub, prv, alt;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t opaque_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t opaque_key_attr = PSA_KEY_ATTRIBUTES_INIT;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_pk_init(&pub);
@@ -873,9 +1055,13 @@
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(&prv) == MBEDTLS_PK_ECKEY) {
- TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&prv, &opaque_key_id,
- PSA_ALG_ANY_HASH,
- PSA_KEY_USAGE_EXPORT, 0), 0);
+ /* Turn the prv PK context into an opaque one.*/
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&prv, PSA_KEY_USAGE_SIGN_HASH,
+ &opaque_key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&prv, &opaque_key_attr, &opaque_key_id), 0);
+ mbedtls_pk_free(&prv);
+ mbedtls_pk_init(&prv);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&prv, opaque_key_id), 0);
TEST_EQUAL(mbedtls_pk_check_pair(&pub, &prv, mbedtls_test_rnd_std_rand,
NULL), ret);
}
@@ -1245,7 +1431,7 @@
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
-void pk_rsa_encrypt_decrypt_test(data_t *message, int mod,
+void pk_rsa_encrypt_decrypt_test(data_t *message, int mod, int padding,
char *input_P, char *input_Q,
char *input_N, char *input_E,
int ret)
@@ -1260,7 +1446,7 @@
mbedtls_pk_init(&pk);
mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
- USE_PSA_INIT();
+ MD_OR_USE_PSA_INIT();
memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
memset(output, 0, sizeof(output));
@@ -1270,6 +1456,7 @@
/* init pk-rsa context */
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
+ mbedtls_rsa_set_padding(rsa, padding, MBEDTLS_MD_SHA1);
/* load public key */
rsa->len = (mod + 7) / 8;
@@ -1289,6 +1476,7 @@
TEST_ASSERT(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
+ mbedtls_rsa_set_padding(rsa, padding, MBEDTLS_MD_SHA1);
/* load public key */
TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
@@ -1318,7 +1506,7 @@
mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
mbedtls_pk_free(&pk);
- USE_PSA_DONE();
+ MD_OR_USE_PSA_DONE();
}
/* END_CASE */
@@ -1395,7 +1583,8 @@
mbedtls_mpi N, P, Q, E;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
- mbedtls_svc_key_id_t key_id;
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
size_t olen;
mbedtls_pk_init(&pk);
@@ -1422,10 +1611,11 @@
TEST_EQUAL(mbedtls_rsa_complete(rsa), 0);
/* Turn PK context into an opaque one. */
- TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&pk, &key_id,
- PSA_ALG_RSA_PKCS1V15_CRYPT,
- PSA_KEY_USAGE_DECRYPT,
- PSA_ALG_NONE), 0);
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_DECRYPT, &key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &key_attr, &key_id), 0);
+ mbedtls_pk_free(&pk);
+ mbedtls_pk_init(&pk);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key_id), 0);
TEST_EQUAL(mbedtls_pk_get_bitlen(&pk), mod);
@@ -1635,10 +1825,9 @@
unsigned char pkey_legacy[200];
unsigned char pkey_psa[200];
unsigned char *pkey_legacy_start, *pkey_psa_start;
- psa_algorithm_t alg_psa;
size_t sig_len, klen_legacy, klen_psa;
int ret;
- mbedtls_svc_key_id_t key_id;
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
/*
@@ -1660,7 +1849,6 @@
TEST_ASSERT(mbedtls_rsa_gen_key(mbedtls_pk_rsa(pk),
mbedtls_test_rnd_std_rand, NULL,
curve_or_keybits, 3) == 0);
- alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256);
} else
#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
@@ -1671,8 +1859,6 @@
TEST_ASSERT(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0);
TEST_ASSERT(pk_genkey(&pk, grpid) == 0);
-
- alg_psa = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
} else
#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
{
@@ -1699,9 +1885,11 @@
#endif /* MBEDTLS_PK_WRITE_C */
/* Turn PK context into an opaque one. */
- TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&pk, &key_id, alg_psa,
- PSA_KEY_USAGE_SIGN_HASH,
- PSA_ALG_NONE) == 0);
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &attributes), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &key_id), 0);
+ mbedtls_pk_free(&pk);
+ mbedtls_pk_init(&pk);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key_id), 0);
PSA_ASSERT(psa_get_key_attributes(key_id, &attributes));
TEST_EQUAL(psa_get_key_type(&attributes), (psa_key_type_t) psa_type);
@@ -1821,13 +2009,13 @@
{
mbedtls_pk_context pk;
size_t sig_len, pkey_len;
- mbedtls_svc_key_id_t key_id;
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
unsigned char pkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
unsigned char *pkey_start;
unsigned char hash[PSA_HASH_MAX_SIZE];
psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
- psa_algorithm_t psa_alg;
size_t hash_len = PSA_HASH_LENGTH(psa_md_alg);
void const *options = NULL;
mbedtls_pk_rsassa_pss_options rsassa_pss_options;
@@ -1844,26 +2032,26 @@
mbedtls_test_rnd_std_rand, NULL,
key_bits, 3), 0);
- /* Export underlying public key for re-importing in a legacy context. */
- ret = mbedtls_pk_write_pubkey_der(&pk, pkey, sizeof(pkey));
+ if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
+ mbedtls_rsa_set_padding(mbedtls_pk_rsa(pk), MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_NONE);
+ }
+
+ /* Export underlying public key for re-importing in a legacy context.
+ * Note: mbedtls_rsa_write_key() writes backwards in the data buffer. */
+ pkey_start = pkey + sizeof(pkey);
+ ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(pk), pkey, &pkey_start);
TEST_ASSERT(ret >= 0);
pkey_len = (size_t) ret;
/* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */
pkey_start = pkey + sizeof(pkey) - pkey_len;
- if (key_pk_type == MBEDTLS_PK_RSA) {
- psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
- } else if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
- psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
- } else {
- TEST_ASSUME(!"PK key type not supported in this configuration");
- }
-
/* Turn PK context into an opaque one. */
- TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&pk, &key_id, psa_alg,
- PSA_KEY_USAGE_SIGN_HASH,
- PSA_ALG_NONE), 0);
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &key_attr, &key_id), 0);
+ mbedtls_pk_free(&pk);
+ mbedtls_pk_init(&pk);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key_id), 0);
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
@@ -1876,7 +2064,9 @@
TEST_EQUAL(PSA_SUCCESS, psa_destroy_key(key_id));
mbedtls_pk_init(&pk);
- TEST_EQUAL(mbedtls_pk_parse_public_key(&pk, pkey_start, pkey_len), 0);
+ TEST_EQUAL(mbedtls_pk_setup(&pk,
+ mbedtls_pk_info_from_type(pk_type)), 0);
+ TEST_EQUAL(mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(pk), pkey_start, pkey_len), 0);
if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
rsassa_pss_options.mgf1_hash_id = md_alg;
@@ -2281,3 +2471,332 @@
PSA_DONE();
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/
+void pk_copy_from_psa_fail(void)
+{
+ mbedtls_pk_context pk_ctx;
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+
+ mbedtls_pk_init(&pk_ctx);
+ PSA_INIT();
+
+ /* Null pk pointer. */
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, NULL),
+ MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(key_id, NULL),
+ MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+
+ /* Invalid key ID. */
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_make(0, 0), &pk_ctx),
+ MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_make(0, 0), &pk_ctx),
+ MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+
+#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
+ /* Generate a key type that is not handled by the PK module. */
+ PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919), 2048,
+ PSA_KEY_USAGE_EXPORT, PSA_ALG_NONE, &key_id));
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+ psa_destroy_key(key_id);
+#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
+
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && defined(PSA_WANT_ECC_SECP_R1_256) && \
+ defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
+ /* Generate an EC key which cannot be exported. */
+ PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256,
+ 0, PSA_ALG_NONE, &key_id));
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_TYPE_MISMATCH);
+ psa_destroy_key(key_id);
+#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && PSA_WANT_ECC_SECP_R1_256 &&
+ PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
+
+exit:
+ mbedtls_pk_free(&pk_ctx);
+ psa_destroy_key(key_id);
+ PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC:!MBEDTLS_RSA_C */
+void pk_copy_from_psa_builtin_fail()
+{
+ mbedtls_pk_context pk_ctx;
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+
+ mbedtls_pk_init(&pk_ctx);
+ PSA_INIT();
+
+ PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR,
+ PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS,
+ PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT,
+ PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256),
+ &key_id));
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA);
+exit:
+ mbedtls_pk_free(&pk_ctx);
+ psa_destroy_key(key_id);
+ PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/
+void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg,
+ int key_alg_arg)
+{
+ psa_key_type_t key_type = key_type_arg;
+ psa_algorithm_t key_alg = key_alg_arg;
+ psa_key_usage_t key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
+ PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
+ mbedtls_pk_context pk_priv, pk_priv_copy_public, pk_pub, pk_pub_copy_public;
+ mbedtls_svc_key_id_t priv_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ mbedtls_svc_key_id_t pub_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ unsigned char *in_buf = NULL;
+ size_t in_buf_len = MBEDTLS_MD_MAX_SIZE;
+ unsigned char out_buf[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
+ unsigned char out_buf2[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
+ size_t out_buf_len, out_buf2_len;
+
+ mbedtls_pk_init(&pk_priv);
+ mbedtls_pk_init(&pk_priv_copy_public);
+ mbedtls_pk_init(&pk_pub);
+ mbedtls_pk_init(&pk_pub_copy_public);
+ PSA_INIT();
+
+ if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ key_usage |= PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
+ }
+
+ /* Create both a private key and its public counterpart in PSA. */
+ PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len,
+ key_type, key_usage, key_alg, &priv_key_id));
+ pub_key_id = psa_pub_key_from_priv(priv_key_id);
+
+ /* Create 4 PK contexts starting from the PSA keys we just created. */
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0);
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(priv_key_id, &pk_priv_copy_public), 0);
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0);
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(pub_key_id, &pk_pub_copy_public), 0);
+
+ /* Destoy both PSA keys to prove that generated PK contexts are independent
+ * from them. */
+ priv_key_id = psa_copy_and_destroy(priv_key_id);
+ pub_key_id = psa_copy_and_destroy(pub_key_id);
+
+ /* Test #1:
+ * - check that the generated PK contexts are of the correct type.
+ * - [only for RSA] check that the padding mode is correct.
+ */
+ if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
+ TEST_EQUAL(mbedtls_pk_get_type(&pk_priv), MBEDTLS_PK_ECKEY);
+ TEST_EQUAL(mbedtls_pk_get_type(&pk_pub), MBEDTLS_PK_ECKEY);
+ } else {
+ TEST_EQUAL(mbedtls_pk_get_type(&pk_priv), MBEDTLS_PK_RSA);
+ TEST_EQUAL(mbedtls_pk_get_type(&pk_pub), MBEDTLS_PK_RSA);
+#if defined(MBEDTLS_RSA_C)
+ mbedtls_rsa_context *rsa_priv = mbedtls_pk_rsa(pk_priv);
+ mbedtls_rsa_context *rsa_pub = mbedtls_pk_rsa(pk_pub);
+ if (PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) {
+ TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_priv), MBEDTLS_RSA_PKCS_V21);
+ TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_pub), MBEDTLS_RSA_PKCS_V21);
+ } else {
+ TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_priv), MBEDTLS_RSA_PKCS_V15);
+ TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_pub), MBEDTLS_RSA_PKCS_V15);
+ }
+#endif /* MBEDTLS_RSA_C */
+ }
+
+ /* Test #2: check that the 2 generated PK contexts form a valid private/public key pair. */
+ TEST_EQUAL(mbedtls_pk_check_pair(&pk_pub, &pk_priv, mbedtls_test_rnd_std_rand, NULL), 0);
+
+ /* Get the MD alg to be used for the tests below from the provided key policy. */
+ mbedtls_md_type_t md_for_test = MBEDTLS_MD_ALG_FOR_TEST; /* Default */
+ if ((PSA_ALG_GET_HASH(key_alg) != PSA_ALG_NONE) &&
+ (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)) {
+ md_for_test = mbedtls_md_type_from_psa_alg(key_alg);
+ }
+ /* Use also the same MD algorithm for PSA sign/verify checks. This is helpful
+ * for the cases in which the key policy algorithm is ANY_HASH type. */
+ psa_algorithm_t psa_alg_for_test =
+ (key_alg & ~PSA_ALG_HASH_MASK) |
+ (mbedtls_md_psa_alg_from_type(md_for_test) & PSA_ALG_HASH_MASK);
+
+ in_buf_len = mbedtls_md_get_size_from_type(md_for_test);
+ TEST_CALLOC(in_buf, in_buf_len);
+ memset(in_buf, 0x1, in_buf_len);
+
+ /* Test #3: sign/verify with the following pattern:
+ * - Sign using the PK context generated from the private key.
+ * - Verify from the same PK context used for signature.
+ * - Verify with the PK context generated using public key.
+ * - Verify using the public PSA key directly.
+ */
+
+ /* Edge cases: in a build with RSA key support but not RSA padding modes,
+ * or with ECDSA verify support but not signature, the signature might be
+ * impossible. */
+ int pk_can_sign = 0;
+#if defined(MBEDTLS_PKCS1_V15)
+ if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(key_alg) || key_alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
+ pk_can_sign = 1;
+ }
+#endif
+#if defined(MBEDTLS_PKCS1_V21)
+ if (PSA_ALG_IS_RSA_PSS(key_alg) || PSA_ALG_IS_RSA_OAEP(key_alg)) {
+ pk_can_sign = 1;
+ }
+#endif
+#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
+ if (PSA_ALG_IS_ECDSA(key_alg) || PSA_ALG_IS_DETERMINISTIC_ECDSA(key_alg)) {
+ pk_can_sign = 1;
+ }
+#endif
+ if (pk_can_sign) {
+ TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len,
+ out_buf, sizeof(out_buf), &out_buf_len,
+ mbedtls_test_rnd_std_rand, NULL), 0);
+
+ TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len,
+ out_buf, out_buf_len), 0);
+ TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len,
+ out_buf, out_buf_len), 0);
+ }
+
+ if (PSA_ALG_IS_HASH_AND_SIGN(key_alg)) {
+#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
+ /* ECDSA signature requires PK->PSA format conversion. */
+ if (PSA_ALG_IS_ECDSA(key_alg)) {
+ TEST_EQUAL(mbedtls_ecdsa_der_to_raw(mbedtls_pk_get_bitlen(&pk_pub),
+ out_buf, out_buf_len, out_buf,
+ sizeof(out_buf), &out_buf_len), 0);
+ }
+#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
+ PSA_ASSERT(psa_verify_hash(pub_key_id, psa_alg_for_test, in_buf, in_buf_len,
+ out_buf, out_buf_len));
+ }
+
+ /* Test #4: check sign/verify interoperability also in the opposite direction:
+ * sign with PSA and verify with PK. Key's policy must include a valid hash
+ * algorithm (not any).
+ */
+ if (PSA_ALG_IS_HASH_AND_SIGN(key_alg)) {
+ PSA_ASSERT(psa_sign_hash(priv_key_id, psa_alg_for_test, in_buf, in_buf_len,
+ out_buf, sizeof(out_buf), &out_buf_len));
+#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
+ /* ECDSA signature requires PSA->PK format conversion */
+ if (PSA_ALG_IS_ECDSA(key_alg)) {
+ TEST_EQUAL(mbedtls_ecdsa_raw_to_der(mbedtls_pk_get_bitlen(&pk_pub),
+ out_buf, out_buf_len, out_buf,
+ sizeof(out_buf), &out_buf_len), 0);
+ }
+#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
+ TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len,
+ out_buf, out_buf_len), 0);
+ }
+
+ /* Test #5: in case of RSA key pair try also encryption/decryption. */
+ if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(key_alg)) {
+ /* Encrypt with the public key only PK context. */
+ TEST_EQUAL(mbedtls_pk_encrypt(&pk_pub, in_buf, in_buf_len,
+ out_buf, &out_buf_len, sizeof(out_buf),
+ mbedtls_test_rnd_std_rand, NULL), 0);
+
+ /* Decrypt with key pair PK context and compare with original data. */
+ TEST_EQUAL(mbedtls_pk_decrypt(&pk_priv, out_buf, out_buf_len,
+ out_buf2, &out_buf2_len, sizeof(out_buf2),
+ mbedtls_test_rnd_std_rand, NULL), 0);
+ TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len);
+
+ if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(key_alg)) {
+ /* Decrypt with PSA private key directly and compare with original data. */
+ PSA_ASSERT(psa_asymmetric_decrypt(priv_key_id, key_alg, out_buf, out_buf_len,
+ NULL, 0,
+ out_buf2, sizeof(out_buf2), &out_buf2_len));
+ TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len);
+
+ /* Encrypt with PSA public key directly, decrypt with public key PK context
+ * and compare with original data. */
+ PSA_ASSERT(psa_asymmetric_encrypt(pub_key_id, key_alg, in_buf, in_buf_len,
+ NULL, 0,
+ out_buf, sizeof(out_buf), &out_buf_len));
+ TEST_EQUAL(mbedtls_pk_decrypt(&pk_priv, out_buf, out_buf_len,
+ out_buf2, &out_buf2_len, sizeof(out_buf2),
+ mbedtls_test_rnd_std_rand, NULL), 0);
+ TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len);
+ }
+ }
+
+ /* Test that the keys from mbedtls_pk_copy_public_from_psa() are identical
+ * to the public key from mbedtls_pk_copy_from_psa(). */
+ mbedtls_test_set_step(1);
+ TEST_ASSERT(pk_public_same(&pk_pub, &pk_priv_copy_public));
+ mbedtls_test_set_step(2);
+ TEST_ASSERT(pk_public_same(&pk_pub, &pk_pub_copy_public));
+
+exit:
+ mbedtls_free(in_buf);
+ mbedtls_pk_free(&pk_priv);
+ mbedtls_pk_free(&pk_priv_copy_public);
+ mbedtls_pk_free(&pk_pub);
+ mbedtls_pk_free(&pk_pub_copy_public);
+ psa_destroy_key(priv_key_id);
+ psa_destroy_key(pub_key_id);
+ PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/
+void pk_copy_public_from_psa(data_t *priv_key_data, int key_type_arg)
+{
+ psa_key_type_t key_type = key_type_arg;
+ mbedtls_pk_context pk_from_exportable;
+ mbedtls_pk_init(&pk_from_exportable);
+ mbedtls_pk_context pk_from_non_exportable;
+ mbedtls_pk_init(&pk_from_non_exportable);
+ mbedtls_pk_context pk_private;
+ mbedtls_pk_init(&pk_private);
+ mbedtls_svc_key_id_t non_exportable_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ mbedtls_svc_key_id_t exportable_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+
+ PSA_INIT();
+
+ PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len,
+ key_type,
+ PSA_KEY_USAGE_EXPORT,
+ PSA_ALG_NONE,
+ &exportable_key_id));
+ PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len,
+ key_type,
+ 0,
+ PSA_ALG_NONE,
+ &non_exportable_key_id));
+
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(exportable_key_id,
+ &pk_from_exportable), 0);
+ TEST_EQUAL(mbedtls_pk_copy_public_from_psa(non_exportable_key_id,
+ &pk_from_non_exportable), 0);
+
+ /* Check that the non-exportable key really is non-exportable */
+ TEST_EQUAL(mbedtls_pk_copy_from_psa(non_exportable_key_id, &pk_private),
+ MBEDTLS_ERR_PK_TYPE_MISMATCH);
+
+ psa_destroy_key(exportable_key_id);
+ psa_destroy_key(non_exportable_key_id);
+
+ /* The goal of this test function is mostly to check that
+ * mbedtls_pk_copy_public_from_psa works with a non-exportable key pair.
+ * We check that the resulting key is the same as for an exportable
+ * key pair. We rely on pk_copy_from_psa_success tests to validate that
+ * the result is correct. */
+ TEST_ASSERT(pk_public_same(&pk_from_non_exportable, &pk_from_exportable));
+
+exit:
+ mbedtls_pk_free(&pk_from_non_exportable);
+ mbedtls_pk_free(&pk_from_exportable);
+ mbedtls_pk_free(&pk_private);
+ psa_destroy_key(exportable_key_id);
+ psa_destroy_key(non_exportable_key_id);
+ PSA_DONE();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function
index 7dc8413..a06fc30 100644
--- a/tests/suites/test_suite_pkparse.function
+++ b/tests/suites/test_suite_pkparse.function
@@ -57,7 +57,7 @@
if (mbedtls_test_can_exercise_psa_algorithm(exercise_alg)) {
TEST_ASSERT(mbedtls_test_psa_exercise_key(psa_key,
exercise_usage,
- exercise_alg));
+ exercise_alg, 0));
}
mbedtls_test_set_step((unsigned long) -1);
diff --git a/tests/suites/test_suite_pkwrite.function b/tests/suites/test_suite_pkwrite.function
index c760090..735c125 100644
--- a/tests/suites/test_suite_pkwrite.function
+++ b/tests/suites/test_suite_pkwrite.function
@@ -75,6 +75,7 @@
size_t buf_len, check_buf_len;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t opaque_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
USE_PSA_INIT();
@@ -117,10 +118,13 @@
/* Verify that pk_write works also for opaque private keys */
if (!is_public_key) {
memset(buf, 0, check_buf_len);
- TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&key, &opaque_id,
- PSA_ALG_NONE,
- PSA_KEY_USAGE_EXPORT,
- PSA_ALG_NONE), 0);
+ /* Turn the key PK context into an opaque one.
+ * Note: set some practical usage for the key to make get_psa_attributes() happy. */
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&key, PSA_KEY_USAGE_SIGN_MESSAGE, &key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&key, &key_attr, &opaque_id), 0);
+ mbedtls_pk_free(&key);
+ mbedtls_pk_init(&key);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&key, opaque_id), 0);
start_buf = buf;
buf_len = check_buf_len;
TEST_EQUAL(pk_write_any_key(&key, &start_buf, &buf_len, is_public_key,
@@ -172,6 +176,7 @@
size_t pub_key_len = 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t opaque_key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_pk_init(&priv_key);
@@ -194,9 +199,12 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_platform_zeroize(derived_key_raw, derived_key_len);
- TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&priv_key, &opaque_key_id,
- PSA_ALG_NONE, PSA_KEY_USAGE_EXPORT,
- PSA_ALG_NONE), 0);
+ /* Turn the priv_key PK context into an opaque one. */
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&priv_key, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&priv_key, &key_attr, &opaque_key_id), 0);
+ mbedtls_pk_free(&priv_key);
+ mbedtls_pk_init(&priv_key);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&priv_key, opaque_key_id), 0);
TEST_EQUAL(mbedtls_pk_write_pubkey_der(&priv_key, derived_key_raw,
derived_key_len), pub_key_len);
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index c55af03..a3a457d 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -4278,6 +4278,50 @@
depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
import_and_exercise_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
+PSA concurrently import/exercise same key: RSA keypair, PKCS#1 v1.5 raw
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
+
+PSA concurrently import/exercise same key: RSA keypair, PSS-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: RSA keypair, PSS-any-salt-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: RSA public key, PKCS#1 v1.5 raw
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
+concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
+
+PSA concurrently import/exercise same key: RSA public key, PSS-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
+concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: RSA public key, PSS-any-salt-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
+concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDSA
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
+concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA_ANY:100
+
+PSA concurrently import/exercise same key: ECP SECP256R1 keypair, deterministic ECDSA
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
+concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):100
+
+PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDH
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
+concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDH:100
+
+PSA concurrently import/exercise same key: HKDF SHA-256
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_HKDF(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: TLS 1.2 PRF SHA-256
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
+concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):100
+
PSA sign hash: RSA PKCS#1 v1.5, raw
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
sign_hash_deterministic:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263":"2c7744983f023ac7bb1c55529d83ed11a76a7898a1bb5ce191375a4aa7495a633d27879ff58eba5a57371c34feb1180e8b850d552476ebb5634df620261992f12ebee9097041dbbea85a42d45b344be5073ceb772ffc604954b9158ba81ec3dc4d9d65e3ab7aa318165f38c36f841f1c69cb1cfa494aa5cbb4d6c0efbafb043a"
@@ -7532,6 +7576,150 @@
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT
+PSA concurrent key generation: bad type (RSA public key)
+depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 0 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 7 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation- raw data, 9 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:9:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: raw data, (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: raw data, 65528 bits (large key, ok if it fits)
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65528:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:1:8:5
+
+PSA concurrent key generation: raw data, 65536 bits (not supported)
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65536:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: AES, 128 bits, CTR
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: AES, 128 bits, GCM
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_GCM:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 64 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 128 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 192 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: invalid key size: AES, 64 bits
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: RSA, minimum allowed key size, good, sign (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS > 128:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1032 bits, good, sign (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1032:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1032:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, sign (PSS SHA-256)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, sign (PSS-any-salt SHA-256)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, minimum allowed key size, good, encrypt (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS >= 256:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 2048:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, encrypt (OAEP SHA-256)
+depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 0 bits: invalid
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: RSA, size not multiple of 8: not supported
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 62:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: RSA, size not multiple of 2: not supported
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 63:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: RSA, maximum size exceeded
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+8:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: ECC, SECP256R1, good
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: ECC, SECP256R1, incorrect bit size
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
+# INVALID_ARGUMENT would make more sense, but our code as currently structured
+# doesn't fully relate the curve with its size.
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: ECC, Curve25519, good
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_255:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: ECC, Curve448, good
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_448:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 2048 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_2048:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):2048:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 3072 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_3072:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):3072:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 4096 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_4096:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):4096:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 6144 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_6144:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):6144:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 8192 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_8192:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):8192:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 1024 bits, invalid bits
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
Key production parameters initializers
key_production_parameters_init:
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 09874a1..7a242fd 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -28,6 +28,10 @@
#define TEST_DRIVER_LOCATION 0x7fffff
#endif
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#include "mbedtls/threading.h"
+#endif
+
/* If this comes up, it's a bug in the test code or in the test data. */
#define UNUSED 0xdeadbeef
@@ -1333,6 +1337,186 @@
return 0;
}
+#if defined(MBEDTLS_THREADING_PTHREAD)
+
+typedef struct same_key_context {
+ data_t *data;
+ mbedtls_svc_key_id_t key;
+ psa_key_attributes_t *attributes;
+ int type;
+ int bits;
+ /* The following two parameters are used to ensure that when multiple
+ * threads attempt to load/destroy the key, exactly one thread succeeds. */
+ int key_loaded;
+ mbedtls_threading_mutex_t MBEDTLS_PRIVATE(key_loaded_mutex);
+}
+same_key_context;
+
+/* Attempt to import the key in ctx. This handles any valid error codes
+ * and reports an error for any invalid codes. This function also insures
+ * that once imported by some thread, all threads can use the key. */
+void *thread_import_key(void *ctx)
+{
+ mbedtls_svc_key_id_t returned_key_id;
+ same_key_context *skc = (struct same_key_context *) ctx;
+ psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* Import the key, exactly one thread must succeed. */
+ psa_status_t status = psa_import_key(skc->attributes, skc->data->x,
+ skc->data->len, &returned_key_id);
+ switch (status) {
+ case PSA_SUCCESS:
+ if (mbedtls_mutex_lock(&skc->key_loaded_mutex) == 0) {
+ if (skc->key_loaded) {
+ mbedtls_mutex_unlock(&skc->key_loaded_mutex);
+ /* More than one thread has succeeded, report a failure. */
+ TEST_FAIL("The same key has been loaded into the key store multiple times.");
+ }
+ skc->key_loaded = 1;
+ mbedtls_mutex_unlock(&skc->key_loaded_mutex);
+ }
+ break;
+ case PSA_ERROR_INSUFFICIENT_MEMORY:
+ /* If all of the key slots are reserved when a thread
+ * locks the mutex to reserve a new slot, it will return
+ * PSA_ERROR_INSUFFICIENT_MEMORY; this is correct behaviour.
+ * There is a chance for this to occur here when the number of
+ * threads running this function is larger than the number of
+ * free key slots. Each thread reserves an empty key slot,
+ * unlocks the mutex, then relocks it to finalize key creation.
+ * It is at that point where the thread sees that the key
+ * already exists, releases the reserved slot,
+ * and returns PSA_ERROR_ALREADY_EXISTS.
+ * There is no guarantee that the key is loaded upon this return
+ * code, so we can't test the key information. Just stop this
+ * thread from executing, note that this is not an error. */
+ goto exit;
+ break;
+ case PSA_ERROR_ALREADY_EXISTS:
+ /* The key has been loaded by a different thread. */
+ break;
+ default:
+ PSA_ASSERT(status);
+ }
+ /* At this point the key must exist, test the key information. */
+ status = psa_get_key_attributes(skc->key, &got_attributes);
+ if (status == PSA_ERROR_INSUFFICIENT_MEMORY) {
+ /* This is not a test failure. The following sequence of events
+ * causes this to occur:
+ * 1: This thread successfuly imports a persistent key skc->key.
+ * 2: N threads reserve an empty key slot in psa_import_key,
+ * where N is equal to the number of free key slots.
+ * 3: A final thread attempts to reserve an empty key slot, kicking
+ * skc->key (which has no registered readers) out of its slot.
+ * 4: This thread calls psa_get_key_attributes(skc->key,...):
+ * it sees that skc->key is not in a slot, attempts to load it and
+ * finds that there are no free slots.
+ * This thread returns PSA_ERROR_INSUFFICIENT_MEMORY.
+ *
+ * The PSA spec allows this behaviour, it is an unavoidable consequence
+ * of allowing persistent keys to be kicked out of the key store while
+ * they are still valid. */
+ goto exit;
+ }
+ PSA_ASSERT(status);
+ TEST_EQUAL(psa_get_key_type(&got_attributes), skc->type);
+ TEST_EQUAL(psa_get_key_bits(&got_attributes), skc->bits);
+
+exit:
+ /* Key attributes may have been returned by psa_get_key_attributes(),
+ * reset them as required. */
+ psa_reset_key_attributes(&got_attributes);
+ return NULL;
+}
+
+void *thread_use_and_destroy_key(void *ctx)
+{
+ same_key_context *skc = (struct same_key_context *) ctx;
+
+ /* Do something with the key according
+ * to its type and permitted usage. */
+ TEST_ASSERT(mbedtls_test_psa_exercise_key(skc->key,
+ skc->attributes->policy.usage,
+ skc->attributes->policy.alg, 1));
+
+ psa_status_t status = psa_destroy_key(skc->key);
+ if (status == PSA_SUCCESS) {
+ if (mbedtls_mutex_lock(&skc->key_loaded_mutex) == 0) {
+ /* Ensure that we are the only thread to succeed. */
+ if (skc->key_loaded != 1) {
+ mbedtls_mutex_unlock(&skc->key_loaded_mutex);
+ TEST_FAIL("The same key has been destroyed multiple times.");
+ }
+ skc->key_loaded = 0;
+ mbedtls_mutex_unlock(&skc->key_loaded_mutex);
+ }
+ } else {
+ TEST_EQUAL(status, PSA_ERROR_INVALID_HANDLE);
+ }
+
+exit:
+ return NULL;
+}
+
+typedef struct generate_key_context {
+ psa_key_type_t type;
+ psa_key_usage_t usage;
+ size_t bits;
+ psa_algorithm_t alg;
+ psa_status_t expected_status;
+ psa_key_attributes_t *attributes;
+ int is_large_key;
+ int reps;
+}
+generate_key_context;
+void *thread_generate_key(void *ctx)
+{
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
+ generate_key_context *gkc = (struct generate_key_context *) ctx;
+
+ /* If there are race conditions, it is likely the case that they do not
+ * arise every time the code runs. We repeat the code to increase the
+ * chance that any race conditions will be hit. */
+ for (int n = 0; n < gkc->reps; n++) {
+ /* Generate a key */
+ psa_status_t status = psa_generate_key(gkc->attributes, &key);
+
+ if (gkc->is_large_key > 0) {
+ TEST_ASSUME(status != PSA_ERROR_INSUFFICIENT_MEMORY);
+ }
+
+ TEST_EQUAL(status, gkc->expected_status);
+ if (gkc->expected_status != PSA_SUCCESS) {
+ PSA_ASSERT(psa_destroy_key(key));
+ goto exit;
+ }
+
+ /* Test the key information */
+ PSA_ASSERT(psa_get_key_attributes(key, &got_attributes));
+ TEST_EQUAL(psa_get_key_type(&got_attributes), gkc->type);
+ TEST_EQUAL(psa_get_key_bits(&got_attributes), gkc->bits);
+
+ /* Do something with the key according
+ * to its type and permitted usage. */
+ if (!mbedtls_test_psa_exercise_key(key, gkc->usage, gkc->alg, 0)) {
+ psa_destroy_key(key);
+ goto exit;
+ }
+ psa_reset_key_attributes(&got_attributes);
+
+ PSA_ASSERT(psa_destroy_key(key));
+ }
+exit:
+ /*
+ * Key attributes may have been returned by psa_get_key_attributes()
+ * thus reset them as required.
+ */
+ psa_reset_key_attributes(&got_attributes);
+ return NULL;
+}
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -1651,7 +1835,7 @@
* this doesn't directly validate the implementation, but it still helps
* by cross-validating the test data with the sanity check code. */
if (!psa_key_lifetime_is_external(lifetime)) {
- if (!mbedtls_test_psa_exercise_key(key, usage_arg, 0)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage_arg, 0, 0)) {
goto exit;
}
}
@@ -1760,6 +1944,78 @@
}
/* END_CASE */
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_CRYPTO_STORAGE_C */
+void concurrently_use_same_persistent_key(data_t *data,
+ int type_arg,
+ int bits_arg,
+ int alg_arg,
+ int thread_count_arg)
+{
+ size_t thread_count = (size_t) thread_count_arg;
+ mbedtls_test_thread_t *threads = NULL;
+ mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 1);
+ same_key_context skc;
+ skc.data = data;
+ skc.key = key_id;
+ skc.type = type_arg;
+ skc.bits = bits_arg;
+ skc.key_loaded = 0;
+ mbedtls_mutex_init(&skc.key_loaded_mutex);
+ psa_key_usage_t usage = mbedtls_test_psa_usage_to_exercise(skc.type, alg_arg);
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ PSA_ASSERT(psa_crypto_init());
+
+ psa_set_key_id(&attributes, key_id);
+ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
+ psa_set_key_usage_flags(&attributes, usage);
+ psa_set_key_algorithm(&attributes, alg_arg);
+ psa_set_key_type(&attributes, type_arg);
+ psa_set_key_bits(&attributes, bits_arg);
+ skc.attributes = &attributes;
+
+ TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
+
+ /* Test that when multiple threads import the same key,
+ * exactly one thread succeeds and the rest fail with valid errors.
+ * Also test that all threads can use the key as soon as it has been
+ * imported. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i], thread_import_key,
+ (void *) &skc), 0);
+ }
+
+ /* Join threads. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
+ }
+
+ /* Test that when multiple threads use and destroy a key no corruption
+ * occurs, and exactly one thread succeeds when destroying the key. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i], thread_use_and_destroy_key,
+ (void *) &skc), 0);
+ }
+
+ /* Join threads. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
+ }
+ /* Ensure that one thread succeeded in destroying the key. */
+ TEST_ASSERT(!skc.key_loaded);
+exit:
+ psa_reset_key_attributes(&attributes);
+ mbedtls_mutex_free(&skc.key_loaded_mutex);
+ mbedtls_free(threads);
+ PSA_DONE();
+}
+/* END_CASE */
+#endif
+
/* BEGIN_CASE */
void import_and_exercise_key(data_t *data,
int type_arg,
@@ -1789,7 +2045,7 @@
TEST_EQUAL(psa_get_key_bits(&got_attributes), bits);
/* Do something with the key according to its type and permitted usage. */
- if (!mbedtls_test_psa_exercise_key(key, usage, alg)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) {
goto exit;
}
@@ -2426,7 +2682,7 @@
&key));
PSA_ASSERT(psa_key_derivation_setup(&operation, exercise_alg));
- status = mbedtls_test_psa_key_agreement_with_self(&operation, key);
+ status = mbedtls_test_psa_key_agreement_with_self(&operation, key, 0);
TEST_EQUAL(status, expected_status);
@@ -2465,10 +2721,10 @@
TEST_EQUAL(psa_get_key_algorithm(&got_attributes), alg);
TEST_EQUAL(psa_get_key_enrollment_algorithm(&got_attributes), alg2);
- if (!mbedtls_test_psa_exercise_key(key, usage, alg)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) {
goto exit;
}
- if (!mbedtls_test_psa_exercise_key(key, usage, alg2)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage, alg2, 0)) {
goto exit;
}
@@ -2508,7 +2764,7 @@
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
&key));
- status = mbedtls_test_psa_raw_key_agreement_with_self(exercise_alg, key);
+ status = mbedtls_test_psa_raw_key_agreement_with_self(exercise_alg, key, 0);
TEST_EQUAL(status, expected_status);
@@ -2599,10 +2855,10 @@
}
if (!psa_key_lifetime_is_external(target_lifetime)) {
- if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg)) {
+ if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg, 0)) {
goto exit;
}
- if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg2)) {
+ if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg2, 0)) {
goto exit;
}
}
@@ -8617,7 +8873,7 @@
// When taking a private key as secret input, use key agreement
// to add the shared secret to the derivation
TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(
- &operation, keys[i]),
+ &operation, keys[i], 0),
expected_statuses[i]);
} else {
TEST_EQUAL(psa_key_derivation_input_key(&operation, steps[i],
@@ -8716,7 +8972,7 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
input1, input1_length,
input2, input2_length,
- capacity)) {
+ capacity, 0)) {
goto exit;
}
@@ -9035,7 +9291,7 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
input1->x, input1->len,
input2->x, input2->len,
- requested_capacity)) {
+ requested_capacity, 0)) {
goto exit;
}
@@ -9152,7 +9408,7 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
- capacity)) {
+ capacity, 0)) {
goto exit;
}
@@ -9169,7 +9425,7 @@
TEST_EQUAL(psa_get_key_bits(&got_attributes), derived_bits);
/* Exercise the derived key. */
- if (!mbedtls_test_psa_exercise_key(derived_key, derived_usage, derived_alg)) {
+ if (!mbedtls_test_psa_exercise_key(derived_key, derived_usage, derived_alg, 0)) {
goto exit;
}
@@ -9222,7 +9478,7 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
- capacity)) {
+ capacity, 0)) {
goto exit;
}
@@ -9235,7 +9491,7 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
- capacity)) {
+ capacity, 0)) {
goto exit;
}
@@ -9306,7 +9562,7 @@
&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
- PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) {
+ PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) {
goto exit;
}
@@ -9371,7 +9627,7 @@
&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
- PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) {
+ PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) {
goto exit;
}
@@ -9435,7 +9691,7 @@
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
- SIZE_MAX)) {
+ SIZE_MAX, 0)) {
goto exit;
}
@@ -9783,6 +10039,59 @@
}
/* END_CASE */
+#if defined MBEDTLS_THREADING_PTHREAD
+
+/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */
+void concurrently_generate_keys(int type_arg,
+ int bits_arg,
+ int usage_arg,
+ int alg_arg,
+ int expected_status_arg,
+ int is_large_key_arg,
+ int arg_thread_count,
+ int reps_arg)
+{
+ size_t thread_count = (size_t) arg_thread_count;
+ mbedtls_test_thread_t *threads = NULL;
+ generate_key_context gkc;
+ gkc.type = type_arg;
+ gkc.usage = usage_arg;
+ gkc.bits = bits_arg;
+ gkc.alg = alg_arg;
+ gkc.expected_status = expected_status_arg;
+ gkc.is_large_key = is_large_key_arg;
+ gkc.reps = reps_arg;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ PSA_ASSERT(psa_crypto_init());
+
+ psa_set_key_usage_flags(&attributes, usage_arg);
+ psa_set_key_algorithm(&attributes, alg_arg);
+ psa_set_key_type(&attributes, type_arg);
+ psa_set_key_bits(&attributes, bits_arg);
+ gkc.attributes = &attributes;
+
+ TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
+
+ /* Split threads to generate key then destroy key. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i], thread_generate_key,
+ (void *) &gkc), 0);
+ }
+
+ /* Join threads. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
+ }
+
+exit:
+ mbedtls_free(threads);
+ PSA_DONE();
+}
+/* END_CASE */
+#endif
+
/* BEGIN_CASE */
void generate_key(int type_arg,
int bits_arg,
@@ -9824,7 +10133,7 @@
TEST_EQUAL(psa_get_key_bits(&got_attributes), bits);
/* Do something with the key according to its type and permitted usage. */
- if (!mbedtls_test_psa_exercise_key(key, usage, alg)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) {
goto exit;
}
@@ -9894,7 +10203,7 @@
#endif
/* Do something with the key according to its type and permitted usage. */
- if (!mbedtls_test_psa_exercise_key(key, usage, alg)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) {
goto exit;
}
@@ -10045,7 +10354,7 @@
}
/* Do something with the key according to its type and permitted usage. */
- if (!mbedtls_test_psa_exercise_key(key, usage_flags, alg)) {
+ if (!mbedtls_test_psa_exercise_key(key, usage_flags, alg, 0)) {
goto exit;
}
diff --git a/tests/suites/test_suite_psa_crypto_init.data b/tests/suites/test_suite_psa_crypto_init.data
index 8c5b41d..147d03f 100644
--- a/tests/suites/test_suite_psa_crypto_init.data
+++ b/tests/suites/test_suite_psa_crypto_init.data
@@ -10,6 +10,9 @@
PSA deinit twice
deinit_without_init:1
+PSA threaded init checks
+psa_threaded_init:100
+
No random without init
validate_module_init_generate_random:0
diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function
index 7a43432..9ff33a6 100644
--- a/tests/suites/test_suite_psa_crypto_init.function
+++ b/tests/suites/test_suite_psa_crypto_init.function
@@ -1,6 +1,7 @@
/* BEGIN_HEADER */
#include <stdint.h>
+#include "psa_crypto_core.h"
/* Some tests in this module configure entropy sources. */
#include "psa_crypto_invasive.h"
@@ -112,6 +113,59 @@
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
+#if defined MBEDTLS_THREADING_PTHREAD
+
+typedef struct {
+ int do_init;
+} thread_psa_init_ctx_t;
+
+static void *thread_psa_init_function(void *ctx)
+{
+ thread_psa_init_ctx_t *init_context = (thread_psa_init_ctx_t *) ctx;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ uint8_t random[10] = { 0 };
+
+ if (init_context->do_init) {
+ PSA_ASSERT(psa_crypto_init());
+ }
+
+ /* If this is a test only thread, then we can assume PSA is being started
+ * up on another thread and thus we cannot know whether the following tests
+ * will be successful or not. These checks are still useful, however even
+ * without checking the return codes as they may show up race conditions on
+ * the flags they check under TSAN.*/
+
+ /* Test getting if drivers are initialised. */
+ int can_do = psa_can_do_hash(PSA_ALG_NONE);
+
+ if (init_context->do_init) {
+ TEST_ASSERT(can_do == 1);
+ }
+
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+
+ /* Test getting global_data.rng_state. */
+ status = mbedtls_psa_crypto_configure_entropy_sources(NULL, NULL);
+
+ if (init_context->do_init) {
+ /* Bad state due to entropy sources already being setup in
+ * psa_crypto_init() */
+ TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
+ }
+#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
+
+ /* Test using the PSA RNG ony if we know PSA is up and running. */
+ if (init_context->do_init) {
+ status = psa_generate_random(random, sizeof(random));
+
+ TEST_EQUAL(status, PSA_SUCCESS);
+ }
+
+exit:
+ return NULL;
+}
+#endif /* defined MBEDTLS_THREADING_PTHREAD */
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -154,6 +208,67 @@
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */
+void psa_threaded_init(int arg_thread_count)
+{
+ thread_psa_init_ctx_t init_context;
+ thread_psa_init_ctx_t init_context_2;
+
+ size_t thread_count = (size_t) arg_thread_count;
+ mbedtls_test_thread_t *threads = NULL;
+
+ TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
+
+ init_context.do_init = 1;
+
+ /* Test initialising PSA and testing certain protected globals on multiple
+ * threads. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i],
+ thread_psa_init_function,
+ (void *) &init_context),
+ 0);
+ }
+
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
+ }
+
+ PSA_DONE();
+
+ init_context_2.do_init = 0;
+
+ /* Test initialising PSA whilst also testing flags on other threads. */
+ for (size_t i = 0; i < thread_count; i++) {
+
+ if (i & 1) {
+
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i],
+ thread_psa_init_function,
+ (void *) &init_context),
+ 0);
+ } else {
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i],
+ thread_psa_init_function,
+ (void *) &init_context_2),
+ 0);
+ }
+ }
+
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
+ }
+exit:
+
+ PSA_DONE();
+
+ mbedtls_free(threads);
+}
+/* END_CASE */
+
/* BEGIN_CASE */
void validate_module_init_generate_random(int count)
{
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index c4e4c7d..ea8cb6b 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -61,7 +61,7 @@
TEST_CALLOC(file_data, file_data_length);
psa_format_key_data_for_storage(key_data->x, key_data->len,
- &attributes.core,
+ &attributes,
file_data);
TEST_MEMORY_COMPARE(expected_file_data->x, expected_file_data->len,
@@ -90,7 +90,7 @@
status = psa_parse_key_data_from_storage(file_data->x, file_data->len,
&key_data, &key_data_length,
- &attributes.core);
+ &attributes);
TEST_EQUAL(status, expected_status);
if (status != PSA_SUCCESS) {
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index 8e96984..e3681ba 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -952,7 +952,7 @@
psa_set_key_slot_number(&attributes, min_slot);
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
- attributes.core.id = returned_id;
+ attributes.id = returned_id;
} else {
psa_set_key_id(&attributes, returned_id);
}
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
index 6f28f93..b6d3a34 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
@@ -359,19 +359,19 @@
if (mock_alloc_return_value == PSA_SUCCESS) {
TEST_ASSERT(mbedtls_svc_key_id_equal(
- mock_import_data.attributes.core.id, id));
+ mock_import_data.attributes.id, id));
} else {
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
- mock_import_data.attributes.core.id) == 0);
+ mock_import_data.attributes.id) == 0);
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(
- mock_import_data.attributes.core.id) == 0);
+ mock_import_data.attributes.id) == 0);
}
- TEST_ASSERT(mock_import_data.attributes.core.lifetime ==
+ TEST_ASSERT(mock_import_data.attributes.lifetime ==
(mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0));
- TEST_ASSERT(mock_import_data.attributes.core.policy.usage ==
+ TEST_ASSERT(mock_import_data.attributes.policy.usage ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0));
- TEST_ASSERT(mock_import_data.attributes.core.type ==
+ TEST_ASSERT(mock_import_data.attributes.type ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0));
if (expected_result == PSA_SUCCESS) {
@@ -474,19 +474,19 @@
if (mock_alloc_return_value == PSA_SUCCESS) {
TEST_ASSERT(mbedtls_svc_key_id_equal(
- mock_generate_data.attributes.core.id, id));
+ mock_generate_data.attributes.id, id));
} else {
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
- mock_generate_data.attributes.core.id) == 0);
+ mock_generate_data.attributes.id) == 0);
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(
- mock_generate_data.attributes.core.id) == 0);
+ mock_generate_data.attributes.id) == 0);
}
- TEST_ASSERT(mock_generate_data.attributes.core.lifetime ==
+ TEST_ASSERT(mock_generate_data.attributes.lifetime ==
(mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0));
- TEST_ASSERT(mock_generate_data.attributes.core.policy.usage ==
+ TEST_ASSERT(mock_generate_data.attributes.policy.usage ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0));
- TEST_ASSERT(mock_generate_data.attributes.core.type ==
+ TEST_ASSERT(mock_generate_data.attributes.type ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0));
if (expected_result == PSA_SUCCESS) {
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index 8564d35..94f26f6 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -458,7 +458,7 @@
* PSA key attributes APIs thus accessing to the attributes
* directly.
*/
- attributes.core.id = id;
+ attributes.id = id;
} else {
psa_set_key_id(&attributes, id);
}
@@ -992,7 +992,7 @@
* Check that we can now access the persistent key again.
*/
PSA_ASSERT(psa_get_key_attributes(persistent_key, &attributes));
- TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.core.id,
+ TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.id,
persistent_key));
/*
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.function b/tests/suites/test_suite_psa_crypto_storage_format.function
index bb1e2c6..efaaba5 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.function
+++ b/tests/suites/test_suite_psa_crypto_storage_format.function
@@ -187,7 +187,7 @@
TEST_ASSERT(mbedtls_test_psa_exercise_key(
key_id,
psa_get_key_usage_flags(expected_attributes),
- psa_get_key_algorithm(expected_attributes)));
+ psa_get_key_algorithm(expected_attributes), 0));
}
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 69ccf26..734b945 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -961,6 +961,14 @@
depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_SRV_C
ssl_session_serialize_version_check:0:0:0:1:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3
+Test Session id & Ciphersuite accessors TLS 1.2
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
+ssl_session_id_accessors_check:MBEDTLS_SSL_VERSION_TLS1_2
+
+Test Session id & Ciphersuite accessors TLS 1.3
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3
+ssl_session_id_accessors_check:MBEDTLS_SSL_VERSION_TLS1_3
+
Record crypt, AES-128-CBC, 1.2, SHA-384
depends_on:MBEDTLS_SSL_HAVE_AES:MBEDTLS_SSL_HAVE_CBC:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_MD_CAN_SHA384
ssl_crypt_record:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_MD_SHA384:0:0:MBEDTLS_SSL_VERSION_TLS1_2:0:0
@@ -3274,23 +3282,102 @@
TLS 1.3 resume session with ticket
tls13_resume_session_with_ticket
-TLS 1.3 early data, early data accepted
-tls13_early_data:TEST_EARLY_DATA_ACCEPTED
+TLS 1.3 read early data, early data accepted
+tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED
-TLS 1.3 early data, server rejects early data
-tls13_early_data:TEST_EARLY_DATA_SERVER_REJECTS
+TLS 1.3 read early data, no early data indication
+tls13_read_early_data:TEST_EARLY_DATA_NO_INDICATION_SENT
-TLS 1.3 early data, discard after HRR
-tls13_early_data:TEST_EARLY_DATA_HRR
+TLS 1.3 read early data, server rejects early data
+tls13_read_early_data:TEST_EARLY_DATA_SERVER_REJECTS
-TLS 1.3 cli, early data status, early data accepted
-tls13_cli_early_data_status:TEST_EARLY_DATA_ACCEPTED
+TLS 1.3 read early data, discard after HRR
+tls13_read_early_data:TEST_EARLY_DATA_HRR
-TLS 1.3 cli, early data status, no early data indication
-tls13_cli_early_data_status:TEST_EARLY_DATA_NO_INDICATION_SENT
+TLS 1.3 cli, early data, same ALPN
+depends_on:MBEDTLS_SSL_ALPN
+tls13_read_early_data:TEST_EARLY_DATA_SAME_ALPN
-TLS 1.3 cli, early data status, server rejects early data
-tls13_cli_early_data_status:TEST_EARLY_DATA_SERVER_REJECTS
+TLS 1.3 cli, early data, different ALPN
+depends_on:MBEDTLS_SSL_ALPN
+tls13_read_early_data:TEST_EARLY_DATA_DIFF_ALPN
-TLS 1.3 cli, early data status, hello retry request
-tls13_cli_early_data_status:TEST_EARLY_DATA_HRR
+TLS 1.3 cli, early data, no initial ALPN
+depends_on:MBEDTLS_SSL_ALPN
+tls13_read_early_data:TEST_EARLY_DATA_NO_INITIAL_ALPN
+
+TLS 1.3 cli, early data, no later ALPN
+depends_on:MBEDTLS_SSL_ALPN
+tls13_read_early_data:TEST_EARLY_DATA_NO_LATER_ALPN
+
+TLS 1.3 cli, early data state, early data accepted
+tls13_cli_early_data_state:TEST_EARLY_DATA_ACCEPTED
+
+TLS 1.3 cli, early data state, no early data indication
+tls13_cli_early_data_state:TEST_EARLY_DATA_NO_INDICATION_SENT
+
+TLS 1.3 cli, early data state, server rejects early data
+tls13_cli_early_data_state:TEST_EARLY_DATA_SERVER_REJECTS
+
+TLS 1.3 cli, early data state, hello retry request
+tls13_cli_early_data_state:TEST_EARLY_DATA_HRR
+
+TLS 1.3 write early data, early data accepted
+tls13_write_early_data:TEST_EARLY_DATA_ACCEPTED
+
+TLS 1.3 write early data, no early data indication
+tls13_write_early_data:TEST_EARLY_DATA_NO_INDICATION_SENT
+
+TLS 1.3 write early data, server rejects early data
+tls13_write_early_data:TEST_EARLY_DATA_SERVER_REJECTS
+
+TLS 1.3 write early data, hello retry request
+tls13_write_early_data:TEST_EARLY_DATA_HRR
+
+TLS 1.3 cli, maximum early data size, default size
+tls13_cli_max_early_data_size:-1
+
+TLS 1.3 cli, maximum early data size, zero
+tls13_cli_max_early_data_size:0
+
+TLS 1.3 cli, maximum early data size, very small but not 0
+tls13_cli_max_early_data_size:3
+
+TLS 1.3 cli, maximum early data size, 93
+tls13_cli_max_early_data_size:93
+
+TLS 1.3 srv, max early data size, dflt, wsz=96
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:96
+
+TLS 1.3 srv, max early data size, dflt, wsz=128
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:128
+
+TLS 1.3 srv, max early data size, 3, wsz=2
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:2
+
+TLS 1.3 srv, max early data size, 3, wsz=3
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:3
+
+TLS 1.3 srv, max early data size, 98, wsz=23
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:23
+
+TLS 1.3 srv, max early data size, 98, wsz=49
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:49
+
+TLS 1.3 srv, max early data size, server rejects, dflt, wsz=128
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1:128
+
+TLS 1.3 srv, max early data size, server rejects, 3, wsz=3
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3:3
+
+TLS 1.3 srv, max early data size, server rejects, 98, wsz=49
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:98:49
+
+TLS 1.3 srv, max early data size, HRR, dflt, wsz=128
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1:128
+
+TLS 1.3 srv, max early data size, HRR, 3, wsz=3
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:3
+
+TLS 1.3 srv, max early data size, HRR, 98, wsz=49
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 0e798f4..67d97e4 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -17,6 +17,10 @@
#define TEST_EARLY_DATA_NO_INDICATION_SENT 1
#define TEST_EARLY_DATA_SERVER_REJECTS 2
#define TEST_EARLY_DATA_HRR 3
+#define TEST_EARLY_DATA_SAME_ALPN 4
+#define TEST_EARLY_DATA_DIFF_ALPN 5
+#define TEST_EARLY_DATA_NO_INITIAL_ALPN 6
+#define TEST_EARLY_DATA_NO_LATER_ALPN 7
#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \
@@ -28,10 +32,8 @@
defined(MBEDTLS_ECP_HAVE_SECP256R1) && defined(MBEDTLS_ECP_HAVE_SECP384R1) && \
defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) && defined(MBEDTLS_SSL_SESSION_TICKETS)
/*
- * The implementation of the function should be based on
- * mbedtls_ssl_write_early_data() eventually. The current version aims at
- * removing the dependency on mbedtls_ssl_write_early_data() for the
- * development and testing of reading early data.
+ * Test function to write early data for negative tests where
+ * mbedtls_ssl_write_early_data() cannot be used.
*/
static int write_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len)
@@ -39,7 +41,7 @@
int ret = mbedtls_ssl_get_max_out_record_payload(ssl);
TEST_ASSERT(ret > 0);
- TEST_ASSERT(len <= (size_t) ret);
+ TEST_LE_U(len, (size_t) ret);
ret = mbedtls_ssl_flush_output(ssl);
TEST_EQUAL(ret, 0);
@@ -1174,6 +1176,8 @@
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_DATAGRAM,
MBEDTLS_SSL_PRESET_DEFAULT) == 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
+
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
/* Read previous record numbers */
@@ -2104,6 +2108,14 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
TEST_ASSERT(
original.max_early_data_size == restored.max_early_data_size);
+#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C)
+ if (endpoint_type == MBEDTLS_SSL_IS_SERVER) {
+ TEST_ASSERT(original.ticket_alpn != NULL);
+ TEST_ASSERT(restored.ticket_alpn != NULL);
+ TEST_MEMORY_COMPARE(original.ticket_alpn, strlen(original.ticket_alpn),
+ restored.ticket_alpn, strlen(restored.ticket_alpn));
+ }
+#endif
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
@@ -2396,7 +2408,7 @@
* corrupt them bit-by-bit. */
for (cur_byte = 0; cur_byte < sizeof(should_corrupt_byte); cur_byte++) {
int cur_bit;
- unsigned char * const byte = &serialized_session[cur_byte];
+ unsigned char *const byte = &serialized_session[cur_byte];
if (should_corrupt_byte[cur_byte] == 0) {
continue;
@@ -2422,6 +2434,54 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void ssl_session_id_accessors_check(int tls_version)
+{
+ mbedtls_ssl_session session;
+ int ciphersuite_id;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+
+ mbedtls_ssl_session_init(&session);
+ USE_PSA_INIT();
+
+ switch (tls_version) {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ case MBEDTLS_SSL_VERSION_TLS1_3:
+ ciphersuite_id = MBEDTLS_TLS1_3_AES_128_GCM_SHA256;
+ TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+ &session, 0, MBEDTLS_SSL_IS_SERVER) == 0);
+ break;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ case MBEDTLS_SSL_VERSION_TLS1_2:
+ ciphersuite_id = MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256;
+ TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+ &session, 0, MBEDTLS_SSL_IS_SERVER, NULL) == 0);
+
+ break;
+#endif
+ default:
+ /* should never happen */
+ TEST_ASSERT(0);
+ break;
+ }
+ TEST_ASSERT(*mbedtls_ssl_session_get_id(&session) == session.id);
+ TEST_ASSERT(mbedtls_ssl_session_get_id_len(&session) == session.id_len);
+ /* mbedtls_test_ssl_tls1x_populate_session sets a mock suite-id of 0xabcd */
+ TEST_ASSERT(mbedtls_ssl_session_get_ciphersuite_id(&session) == 0xabcd);
+
+ /* Test setting a reference id for tls1.3 and tls1.2 */
+ ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id);
+ if (ciphersuite_info != NULL) {
+ TEST_ASSERT(mbedtls_ssl_ciphersuite_get_id(ciphersuite_info) == ciphersuite_id);
+ }
+
+exit:
+ mbedtls_ssl_session_free(&session);
+ USE_PSA_DONE();
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_RSA_C:MBEDTLS_ECP_HAVE_SECP384R1:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 */
void mbedtls_endpoint_sanity(int endpoint_type)
{
@@ -2922,6 +2982,7 @@
mbedtls_ssl_conf_transport(&conf, transport);
mbedtls_ssl_conf_min_tls_version(&conf, min_tls_version);
mbedtls_ssl_conf_max_tls_version(&conf, max_tls_version);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == expected_ssl_setup_result);
TEST_EQUAL(mbedtls_ssl_conf_get_endpoint(
@@ -2963,6 +3024,8 @@
mbedtls_ssl_init(&ssl);
MD_OR_USE_PSA_INIT();
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
+
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
TEST_ASSERT(ssl.handshake != NULL && ssl.handshake->group_list != NULL);
@@ -2994,6 +3057,7 @@
mbedtls_ssl_config conf;
mbedtls_ssl_config_init(&conf);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_max_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2);
mbedtls_ssl_conf_min_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2);
@@ -3102,6 +3166,7 @@
MBEDTLS_SSL_TRANSPORT_DATAGRAM,
MBEDTLS_SSL_PRESET_DEFAULT),
0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0);
TEST_EQUAL(mbedtls_ssl_check_dtls_clihlo_cookie(&ssl, ssl.cli_id,
@@ -3156,6 +3221,7 @@
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)
== 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -3414,6 +3480,7 @@
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT), 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0);
@@ -3624,12 +3691,12 @@
/* END_CASE */
/*
- * The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is
+ * The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_read_early_data() below is
* a temporary workaround to not run the test in Windows-2013 where there is
* an issue with mbedtls_vsnprintf().
*/
/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
-void tls13_early_data(int scenario)
+void tls13_read_early_data(int scenario)
{
int ret = -1;
unsigned char buf[64];
@@ -3665,6 +3732,19 @@
server_options.group_list = group_list;
server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+#if defined(MBEDTLS_SSL_ALPN)
+ switch (scenario) {
+ case TEST_EARLY_DATA_SAME_ALPN:
+ case TEST_EARLY_DATA_DIFF_ALPN:
+ case TEST_EARLY_DATA_NO_LATER_ALPN:
+ client_options.alpn_list[0] = "ALPNExample";
+ client_options.alpn_list[1] = NULL;
+ server_options.alpn_list[0] = "ALPNExample";
+ server_options.alpn_list[1] = NULL;
+ break;
+ }
+#endif
+
ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
&saved_session);
TEST_EQUAL(ret, 0);
@@ -3676,6 +3756,10 @@
case TEST_EARLY_DATA_ACCEPTED:
break;
+ case TEST_EARLY_DATA_NO_INDICATION_SENT:
+ client_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ break;
+
case TEST_EARLY_DATA_SERVER_REJECTS:
mbedtls_debug_set_threshold(3);
server_pattern.pattern =
@@ -3689,6 +3773,33 @@
"EarlyData: Ignore application message before 2nd ClientHello";
server_options.group_list = group_list + 1;
break;
+#if defined(MBEDTLS_SSL_ALPN)
+ case TEST_EARLY_DATA_SAME_ALPN:
+ client_options.alpn_list[0] = "ALPNExample";
+ client_options.alpn_list[1] = NULL;
+ server_options.alpn_list[0] = "ALPNExample";
+ server_options.alpn_list[1] = NULL;
+ break;
+ case TEST_EARLY_DATA_DIFF_ALPN:
+ case TEST_EARLY_DATA_NO_INITIAL_ALPN:
+ client_options.alpn_list[0] = "ALPNExample2";
+ client_options.alpn_list[1] = NULL;
+ server_options.alpn_list[0] = "ALPNExample2";
+ server_options.alpn_list[1] = NULL;
+ mbedtls_debug_set_threshold(3);
+ server_pattern.pattern =
+ "EarlyData: rejected, the selected ALPN is different "
+ "from the one associated with the pre-shared key.";
+ break;
+ case TEST_EARLY_DATA_NO_LATER_ALPN:
+ client_options.alpn_list[0] = NULL;
+ server_options.alpn_list[0] = NULL;
+ mbedtls_debug_set_threshold(3);
+ server_pattern.pattern =
+ "EarlyData: rejected, the selected ALPN is different "
+ "from the one associated with the pre-shared key.";
+ break;
+#endif
default:
TEST_FAIL("Unknown scenario.");
@@ -3723,12 +3834,16 @@
&(client_ep.ssl), &(server_ep.ssl),
MBEDTLS_SSL_SERVER_HELLO), 0);
- TEST_ASSERT(client_ep.ssl.early_data_status !=
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ ret = mbedtls_ssl_write_early_data(&(client_ep.ssl),
+ (unsigned char *) early_data,
+ early_data_len);
- ret = write_early_data(&(client_ep.ssl), (unsigned char *) early_data,
- early_data_len);
- TEST_EQUAL(ret, early_data_len);
+ if (client_ep.ssl.early_data_state !=
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
+ TEST_EQUAL(ret, early_data_len);
+ } else {
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ }
ret = mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
@@ -3736,6 +3851,9 @@
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
+#if defined(MBEDTLS_SSL_ALPN)
+ case TEST_EARLY_DATA_SAME_ALPN:
+#endif
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1);
TEST_EQUAL(mbedtls_ssl_read_early_data(&(server_ep.ssl),
@@ -3743,12 +3861,25 @@
TEST_MEMORY_COMPARE(buf, early_data_len, early_data, early_data_len);
break;
+ case TEST_EARLY_DATA_NO_INDICATION_SENT:
+ TEST_EQUAL(ret, 0);
+ TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 0);
+ break;
+
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
+#if defined(MBEDTLS_SSL_ALPN)
+ case TEST_EARLY_DATA_DIFF_ALPN:
+ case TEST_EARLY_DATA_NO_INITIAL_ALPN:
+ case TEST_EARLY_DATA_NO_LATER_ALPN:
+#endif
TEST_EQUAL(ret, 0);
TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 0);
TEST_EQUAL(server_pattern.counter, 1);
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
@@ -3767,7 +3898,7 @@
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
-void tls13_cli_early_data_status(int scenario)
+void tls13_cli_early_data_state(int scenario)
{
int ret = -1;
mbedtls_test_ssl_endpoint client_ep, server_ep;
@@ -3779,6 +3910,7 @@
MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
};
+ uint8_t client_random[MBEDTLS_CLIENT_HELLO_RANDOM_LEN];
mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
@@ -3869,25 +4001,33 @@
(ret == MBEDTLS_ERR_SSL_WANT_WRITE));
}
+ if (client_ep.ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER) {
+ TEST_EQUAL(mbedtls_ssl_get_early_data_status(&(client_ep.ssl)),
+ MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
+ }
+
switch (client_ep.ssl.state) {
case MBEDTLS_SSL_CLIENT_HELLO:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_NO_INDICATION_SENT: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_IDLE);
break;
case TEST_EARLY_DATA_HRR:
- if (client_ep.ssl.handshake->hello_retry_request_count == 0) {
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN);
+ if (!client_ep.ssl.handshake->hello_retry_request_flag) {
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_IDLE);
} else {
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
}
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
@@ -3895,24 +4035,34 @@
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_HRR:
- if (client_ep.ssl.handshake->hello_retry_request_count == 0) {
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE);
+ if (!client_ep.ssl.handshake->hello_retry_request_flag) {
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE);
+ memcpy(client_random,
+ client_ep.ssl.handshake->randbytes,
+ MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
} else {
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
+ TEST_MEMORY_COMPARE(client_random,
+ MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
+ client_ep.ssl.handshake->randbytes,
+ MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
}
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
@@ -3920,120 +4070,136 @@
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
case MBEDTLS_SSL_SERVER_FINISHED:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
case MBEDTLS_SSL_END_OF_EARLY_DATA:
TEST_EQUAL(scenario, TEST_EARLY_DATA_ACCEPTED);
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED);
break;
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
case MBEDTLS_SSL_CLIENT_FINISHED:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
- TEST_ASSERT(scenario != TEST_EARLY_DATA_NO_INDICATION_SENT);
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT);
break;
+
+ default:
+ TEST_FAIL("Unexpected or unknown scenario.");
}
break;
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
TEST_ASSERT(scenario == TEST_EARLY_DATA_HRR);
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
- TEST_ASSERT(scenario != TEST_EARLY_DATA_ACCEPTED);
switch (scenario) {
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
+
+ default:
+ TEST_FAIL("Unexpected or unknown scenario.");
}
break;
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
@@ -4043,20 +4209,23 @@
case MBEDTLS_SSL_HANDSHAKE_OVER:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
- TEST_EQUAL(client_ep.ssl.early_data_status,
- MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED);
break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
}
break;
@@ -4065,8 +4234,30 @@
}
} while (client_ep.ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER);
+ ret = mbedtls_ssl_get_early_data_status(&(client_ep.ssl));
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED);
+ break;
+
+ case TEST_EARLY_DATA_NO_INDICATION_SENT:
+ TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED);
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_HRR:
+ TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+
+ ret = mbedtls_ssl_get_early_data_status(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
+
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
- TEST_EQUAL(client_ep.ssl.handshake->ccs_count, 1);
+ TEST_EQUAL(client_ep.ssl.handshake->ccs_sent, 1);
#endif
exit:
@@ -4078,3 +4269,756 @@
PSA_DONE();
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
+void tls13_write_early_data(int scenario)
+{
+ int ret = -1;
+ mbedtls_test_ssl_endpoint client_ep, server_ep;
+ mbedtls_test_handshake_test_options client_options;
+ mbedtls_test_handshake_test_options server_options;
+ mbedtls_ssl_session saved_session;
+ uint16_t group_list[3] = {
+ MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
+ MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
+ MBEDTLS_SSL_IANA_TLS_GROUP_NONE
+ };
+ int beyond_first_hello = 0;
+
+ mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
+ mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
+ mbedtls_test_init_handshake_options(&client_options);
+ mbedtls_test_init_handshake_options(&server_options);
+ mbedtls_ssl_session_init(&saved_session);
+
+ PSA_INIT();
+
+ /*
+ * Run first handshake to get a ticket from the server.
+ */
+ client_options.pk_alg = MBEDTLS_PK_ECDSA;
+ client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.pk_alg = MBEDTLS_PK_ECDSA;
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ if (scenario == TEST_EARLY_DATA_HRR) {
+ client_options.group_list = group_list;
+ server_options.group_list = group_list;
+ }
+
+ ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
+ &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Prepare for handshake with the ticket.
+ */
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ break;
+
+ case TEST_EARLY_DATA_NO_INDICATION_SENT:
+ client_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ /*
+ * Remove server support for the group negotiated in
+ * mbedtls_test_get_tls13_ticket() forcing a HelloRetryRequest.
+ */
+ server_options.group_list = group_list + 1;
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+
+ ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
+ &client_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
+ &server_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf,
+ mbedtls_test_ticket_write,
+ mbedtls_test_ticket_parse,
+ NULL);
+
+ ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
+ &(server_ep.socket), 1024);
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Run handshakes going one state further in the handshake sequence at each
+ * loop up to the point where we reach the MBEDTLS_SSL_HANDSHAKE_OVER
+ * state. For each reached handshake state, check the result of the call
+ * to mbedtls_ssl_write_early_data(), make sure we can complete the
+ * handshake successfully and then reset the connection to restart the
+ * handshake from scratch.
+ */
+ do {
+ int client_state = client_ep.ssl.state;
+ int previous_client_state;
+ const char *early_data_string = "This is early data.";
+ const unsigned char *early_data = (const unsigned char *) early_data_string;
+ size_t early_data_len = strlen(early_data_string);
+ int write_early_data_ret, read_early_data_ret;
+ unsigned char read_buf[64];
+
+ write_early_data_ret = mbedtls_ssl_write_early_data(&(client_ep.ssl),
+ early_data,
+ early_data_len);
+
+ if (scenario == TEST_EARLY_DATA_NO_INDICATION_SENT) {
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, client_state);
+ goto complete_handshake;
+ }
+
+ switch (client_state) {
+ case MBEDTLS_SSL_HELLO_REQUEST: /* Intentional fallthrough */
+ case MBEDTLS_SSL_CLIENT_HELLO:
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ if (!client_ep.ssl.handshake->hello_retry_request_flag) {
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
+ } else {
+ beyond_first_hello = 1;
+ TEST_EQUAL(write_early_data_ret,
+ MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_CLIENT_HELLO);
+ }
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+ break;
+
+ case MBEDTLS_SSL_SERVER_HELLO:
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ if (!client_ep.ssl.handshake->hello_retry_request_flag) {
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
+ } else {
+ TEST_EQUAL(write_early_data_ret,
+ MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
+ }
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+ break;
+
+ case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+ break;
+
+ case MBEDTLS_SSL_SERVER_FINISHED:
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_FINISHED);
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_FINISHED);
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_FINISHED);
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+ break;
+
+ case MBEDTLS_SSL_END_OF_EARLY_DATA:
+ TEST_EQUAL(scenario, TEST_EARLY_DATA_ACCEPTED);
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_END_OF_EARLY_DATA);
+ break;
+
+#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
+ case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_HRR:
+ TEST_EQUAL(write_early_data_ret, early_data_len);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
+ break;
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+ break;
+
+ case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
+ TEST_EQUAL(scenario, TEST_EARLY_DATA_HRR);
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
+ break;
+
+ case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
+ switch (scenario) {
+ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_HRR:
+ TEST_EQUAL(write_early_data_ret,
+ MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state,
+ MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
+ break;
+ default:
+ TEST_FAIL("Unexpected or unknown scenario.");
+ }
+ break;
+#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
+
+ case MBEDTLS_SSL_CLIENT_CERTIFICATE: /* Intentional fallthrough */
+ case MBEDTLS_SSL_CLIENT_FINISHED: /* Intentional fallthrough */
+ case MBEDTLS_SSL_FLUSH_BUFFERS: /* Intentional fallthrough */
+ case MBEDTLS_SSL_HANDSHAKE_WRAPUP: /* Intentional fallthrough */
+ case MBEDTLS_SSL_HANDSHAKE_OVER:
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_HRR:
+ TEST_EQUAL(write_early_data_ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.state, client_state);
+ break;
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+ break;
+
+ default:
+ TEST_FAIL("Unexpected state.");
+ }
+
+complete_handshake:
+ do {
+ ret = mbedtls_test_move_handshake_to_state(
+ &(server_ep.ssl), &(client_ep.ssl),
+ MBEDTLS_SSL_HANDSHAKE_OVER);
+
+ if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
+ read_early_data_ret = mbedtls_ssl_read_early_data(
+ &(server_ep.ssl), read_buf, sizeof(read_buf));
+
+ TEST_EQUAL(read_early_data_ret, early_data_len);
+ }
+ } while (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
+
+ TEST_EQUAL(ret, 0);
+ TEST_EQUAL(mbedtls_test_move_handshake_to_state(
+ &(client_ep.ssl), &(server_ep.ssl),
+ MBEDTLS_SSL_HANDSHAKE_OVER), 0);
+
+ mbedtls_test_mock_socket_close(&(client_ep.socket));
+ mbedtls_test_mock_socket_close(&(server_ep.socket));
+
+ ret = mbedtls_ssl_session_reset(&(client_ep.ssl));
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_ssl_session_reset(&(server_ep.ssl));
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
+ &(server_ep.socket), 1024);
+ TEST_EQUAL(ret, 0);
+
+ previous_client_state = client_state;
+ if (previous_client_state == MBEDTLS_SSL_HANDSHAKE_OVER) {
+ break;
+ }
+
+ /* In case of HRR scenario, once we have been through it, move over
+ * the first ClientHello and ServerHello otherwise we just keep playing
+ * this first part of the handshake with HRR.
+ */
+ if ((scenario == TEST_EARLY_DATA_HRR) && (beyond_first_hello)) {
+ TEST_ASSERT(mbedtls_test_move_handshake_to_state(
+ &(client_ep.ssl), &(server_ep.ssl),
+ MBEDTLS_SSL_SERVER_HELLO) == 0);
+ TEST_ASSERT(mbedtls_test_move_handshake_to_state(
+ &(client_ep.ssl), &(server_ep.ssl),
+ MBEDTLS_SSL_CLIENT_HELLO) == 0);
+ }
+
+ TEST_EQUAL(mbedtls_test_move_handshake_to_state(
+ &(client_ep.ssl), &(server_ep.ssl),
+ previous_client_state), 0);
+
+ /* Progress the handshake from at least one state */
+ while (client_ep.ssl.state == previous_client_state) {
+ ret = mbedtls_ssl_handshake_step(&(client_ep.ssl));
+ TEST_ASSERT((ret == 0) ||
+ (ret == MBEDTLS_ERR_SSL_WANT_READ) ||
+ (ret == MBEDTLS_ERR_SSL_WANT_WRITE));
+ if (client_ep.ssl.state != previous_client_state) {
+ break;
+ }
+ ret = mbedtls_ssl_handshake_step(&(server_ep.ssl));
+ TEST_ASSERT((ret == 0) ||
+ (ret == MBEDTLS_ERR_SSL_WANT_READ) ||
+ (ret == MBEDTLS_ERR_SSL_WANT_WRITE));
+ }
+ } while (1);
+
+exit:
+ mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
+ mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
+ mbedtls_test_free_handshake_options(&client_options);
+ mbedtls_test_free_handshake_options(&server_options);
+ mbedtls_ssl_session_free(&saved_session);
+ PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
+void tls13_cli_max_early_data_size(int max_early_data_size_arg)
+{
+ int ret = -1;
+ mbedtls_test_ssl_endpoint client_ep, server_ep;
+ mbedtls_test_handshake_test_options client_options;
+ mbedtls_test_handshake_test_options server_options;
+ mbedtls_ssl_session saved_session;
+ unsigned char *buf = NULL;
+ uint32_t buf_size = 64;
+ uint32_t max_early_data_size;
+ uint32_t written_early_data_size = 0;
+ uint32_t read_early_data_size = 0;
+
+ mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
+ mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
+ mbedtls_test_init_handshake_options(&client_options);
+ mbedtls_test_init_handshake_options(&server_options);
+ mbedtls_ssl_session_init(&saved_session);
+
+ PSA_INIT();
+ TEST_CALLOC(buf, buf_size);
+
+ /*
+ * Run first handshake to get a ticket from the server.
+ */
+
+ client_options.pk_alg = MBEDTLS_PK_ECDSA;
+ client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.pk_alg = MBEDTLS_PK_ECDSA;
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.max_early_data_size = max_early_data_size_arg;
+
+ ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
+ &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Prepare for handshake with the ticket.
+ */
+ ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
+ &client_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
+ &server_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf,
+ mbedtls_test_ticket_write,
+ mbedtls_test_ticket_parse,
+ NULL);
+
+ max_early_data_size = saved_session.max_early_data_size;
+ /*
+ * (max_early_data_size + 1024) for the size of the socket buffers for the
+ * server one to be able to contain the maximum number of early data bytes
+ * plus the first flight of client messages. Needed because we cannot
+ * initiate the handshake on server side before doing all the calls to
+ * mbedtls_ssl_write_early_data() we want to test. See below for more
+ * information.
+ */
+ ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
+ &(server_ep.socket),
+ max_early_data_size + 1024);
+ TEST_EQUAL(ret, 0);
+
+ /* If our server is configured with max_early_data_size equal to zero, it
+ * does not set the MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA flag for
+ * the tickets it creates. To be able to test early data with a ticket
+ * allowing early data in its flags but with max_early_data_size equal to
+ * zero (case supported by our client) tweak the ticket flags here.
+ */
+ if (max_early_data_size == 0) {
+ saved_session.ticket_flags |= MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA;
+ }
+
+ ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ while (written_early_data_size < max_early_data_size) {
+ uint32_t remaining = max_early_data_size - written_early_data_size;
+
+ for (size_t i = 0; i < buf_size; i++) {
+ buf[i] = (unsigned char) (written_early_data_size + i);
+ }
+
+ ret = mbedtls_ssl_write_early_data(&(client_ep.ssl),
+ buf,
+ buf_size);
+
+ if (buf_size <= remaining) {
+ TEST_EQUAL(ret, buf_size);
+ } else {
+ TEST_EQUAL(ret, remaining);
+ }
+ written_early_data_size += buf_size;
+ }
+ TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size);
+
+ ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1);
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA);
+ TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size);
+ TEST_EQUAL(client_ep.ssl.early_data_state,
+ MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE);
+
+ /*
+ * Now, check data on server side. It is not done in the previous loop as
+ * in the first call to mbedtls_ssl_handshake(), the server ends up sending
+ * its Finished message and then in the following call to
+ * mbedtls_ssl_write_early_data() we go past the early data writing window
+ * and we cannot test multiple calls to the API is this writing window.
+ */
+ while (read_early_data_size < max_early_data_size) {
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
+
+ ret = mbedtls_ssl_read_early_data(&(server_ep.ssl),
+ buf,
+ buf_size);
+ TEST_ASSERT(ret > 0);
+
+ for (size_t i = 0; i < (size_t) ret; i++) {
+ TEST_EQUAL(buf[i], (unsigned char) (read_early_data_size + i));
+ }
+
+ read_early_data_size += ret;
+ }
+ TEST_EQUAL(read_early_data_size, max_early_data_size);
+
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ);
+
+ TEST_ASSERT(mbedtls_test_move_handshake_to_state(
+ &(client_ep.ssl), &(server_ep.ssl), MBEDTLS_SSL_HANDSHAKE_OVER)
+ == 0);
+
+exit:
+ mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
+ mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
+ mbedtls_test_free_handshake_options(&client_options);
+ mbedtls_test_free_handshake_options(&server_options);
+ mbedtls_ssl_session_free(&saved_session);
+ mbedtls_free(buf);
+ PSA_DONE();
+}
+/* END_CASE */
+
+/*
+ * The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is
+ * a temporary workaround to not run the test in Windows-2013 where there is
+ * an issue with mbedtls_vsnprintf().
+ */
+/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
+void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, int write_size_arg)
+{
+ int ret = -1;
+ mbedtls_test_ssl_endpoint client_ep, server_ep;
+ mbedtls_test_handshake_test_options client_options;
+ mbedtls_test_handshake_test_options server_options;
+ mbedtls_ssl_session saved_session;
+ mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 };
+ uint16_t group_list[3] = {
+ MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
+ MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
+ MBEDTLS_SSL_IANA_TLS_GROUP_NONE
+ };
+ char pattern[128];
+ unsigned char *buf_write = NULL;
+ uint32_t write_size = (uint32_t) write_size_arg;
+ unsigned char *buf_read = NULL;
+ uint32_t read_size;
+ uint32_t expanded_early_data_chunk_size = 0;
+ uint32_t written_early_data_size = 0;
+ uint32_t max_early_data_size;
+
+ mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
+ mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
+ mbedtls_test_init_handshake_options(&client_options);
+ mbedtls_test_init_handshake_options(&server_options);
+ mbedtls_ssl_session_init(&saved_session);
+ PSA_INIT();
+
+ TEST_CALLOC(buf_write, write_size);
+
+ /*
+ * Allocate a smaller buffer for early data reading to exercise the reading
+ * of data in one record in multiple calls.
+ */
+ read_size = (write_size / 2) + 1;
+ TEST_CALLOC(buf_read, read_size);
+
+ /*
+ * Run first handshake to get a ticket from the server.
+ */
+
+ client_options.pk_alg = MBEDTLS_PK_ECDSA;
+ client_options.group_list = group_list;
+ client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.pk_alg = MBEDTLS_PK_ECDSA;
+ server_options.group_list = group_list;
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.max_early_data_size = max_early_data_size_arg;
+
+ ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
+ &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Prepare for handshake with the ticket.
+ */
+ server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
+ server_options.srv_log_obj = &server_pattern;
+ server_pattern.pattern = pattern;
+
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ ret = mbedtls_snprintf(pattern, sizeof(pattern),
+ "EarlyData: deprotect and discard app data records.");
+ TEST_ASSERT(ret < (int) sizeof(pattern));
+ mbedtls_debug_set_threshold(3);
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ /*
+ * Remove server support for the group negotiated in
+ * mbedtls_test_get_tls13_ticket() forcing an HelloRetryRequest.
+ */
+ server_options.group_list = group_list + 1;
+ ret = mbedtls_snprintf(
+ pattern, sizeof(pattern),
+ "EarlyData: Ignore application message before 2nd ClientHello");
+ TEST_ASSERT(ret < (int) sizeof(pattern));
+ mbedtls_debug_set_threshold(3);
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+
+ ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
+ &client_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
+ &server_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf,
+ mbedtls_test_ticket_write,
+ mbedtls_test_ticket_parse,
+ NULL);
+
+ ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
+ &(server_ep.socket), 1024);
+ TEST_EQUAL(ret, 0);
+
+ max_early_data_size = saved_session.max_early_data_size;
+
+ ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Start an handshake based on the ticket up to the point where early data
+ * can be sent from client side. Then send in a loop as much early data as
+ * possible without going over the maximum permitted size for the ticket.
+ * Finally, do a last writting to go past that maximum permitted size and
+ * check that we detect it.
+ */
+ TEST_EQUAL(mbedtls_test_move_handshake_to_state(
+ &(client_ep.ssl), &(server_ep.ssl),
+ MBEDTLS_SSL_SERVER_HELLO), 0);
+
+ TEST_ASSERT(client_ep.ssl.early_data_state !=
+ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT);
+
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ);
+
+ /*
+ * Write and if possible read as much as possible chunks of write_size
+ * bytes data without getting over the max_early_data_size limit.
+ */
+ do {
+ uint32_t read_early_data_size = 0;
+
+ /*
+ * The contents of the early data are not very important, write a
+ * pattern that varies byte-by-byte and is different for every chunk of
+ * early data.
+ */
+ if ((written_early_data_size + write_size) > max_early_data_size) {
+ break;
+ }
+
+ /*
+ * If the server rejected early data, base the determination of when
+ * to stop the loop on the expanded size (padding and encryption
+ * expansion) of early data on server side and the number of early data
+ * received so far by the server (multiple of the expanded size).
+ */
+ if ((expanded_early_data_chunk_size != 0) &&
+ ((server_ep.ssl.total_early_data_size +
+ expanded_early_data_chunk_size) > max_early_data_size)) {
+ break;
+ }
+
+ for (size_t i = 0; i < write_size; i++) {
+ buf_write[i] = (unsigned char) (written_early_data_size + i);
+ }
+
+ ret = write_early_data(&(client_ep.ssl), buf_write, write_size);
+ TEST_EQUAL(ret, write_size);
+ written_early_data_size += write_size;
+
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ while (read_early_data_size < write_size) {
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
+
+ ret = mbedtls_ssl_read_early_data(&(server_ep.ssl),
+ buf_read, read_size);
+ TEST_ASSERT(ret > 0);
+
+ TEST_MEMORY_COMPARE(buf_read, ret,
+ buf_write + read_early_data_size, ret);
+ read_early_data_size += ret;
+
+ TEST_EQUAL(server_ep.ssl.total_early_data_size,
+ written_early_data_size);
+ }
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_HRR:
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ /*
+ * In this write loop we try to always stay below the
+ * max_early_data_size limit but if max_early_data_size is very
+ * small we may exceed the max_early_data_size limit on the
+ * first write. In TEST_EARLY_DATA_SERVER_REJECTS/
+ * TEST_EARLY_DATA_HRR scenario, this is for sure the case if
+ * max_early_data_size is smaller than the smallest possible
+ * inner content/protected record. Take into account this
+ * possibility here but only for max_early_data_size values
+ * that are close to write_size. Below, '1' is for the inner
+ * type byte and '16' is to take into account some AEAD
+ * expansion (tag, ...).
+ */
+ if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
+ if (scenario == TEST_EARLY_DATA_SERVER_REJECTS) {
+ TEST_LE_U(max_early_data_size,
+ write_size + 1 +
+ MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
+ } else {
+ TEST_LE_U(max_early_data_size,
+ write_size + 1 + 16 +
+ MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
+ }
+ goto exit;
+ }
+
+ TEST_ASSERT(ret == MBEDTLS_ERR_SSL_WANT_READ);
+
+ TEST_EQUAL(server_pattern.counter, 1);
+ server_pattern.counter = 0;
+ if (expanded_early_data_chunk_size == 0) {
+ expanded_early_data_chunk_size = server_ep.ssl.total_early_data_size;
+ }
+ break;
+ }
+ TEST_LE_U(server_ep.ssl.total_early_data_size, max_early_data_size);
+ } while (1);
+
+ mbedtls_debug_set_threshold(3);
+ ret = write_early_data(&(client_ep.ssl), buf_write, write_size);
+ TEST_EQUAL(ret, write_size);
+
+ ret = mbedtls_snprintf(pattern, sizeof(pattern),
+ "EarlyData: Too much early data received");
+ TEST_ASSERT(ret < (int) sizeof(pattern));
+
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
+ TEST_EQUAL(server_pattern.counter, 1);
+
+exit:
+ mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
+ mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
+ mbedtls_test_free_handshake_options(&client_options);
+ mbedtls_test_free_handshake_options(&server_options);
+ mbedtls_ssl_session_free(&saved_session);
+ mbedtls_free(buf_write);
+ mbedtls_free(buf_read);
+ mbedtls_debug_set_threshold(0);
+ PSA_DONE();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 2b0920d..754660c 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -3155,6 +3155,18 @@
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509parse_crt_file:"data_files/parse_input/server5.crt":0
+X509 File parse & read the ca_istrue field (Not Set)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_get_ca_istrue:"data_files/parse_input/server1.crt":0
+
+X509 File parse & read the ca_istrue field (Set)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_get_ca_istrue:"data_files/test-ca.crt":1
+
+X509 File parse & read the ca_istrue field (Legacy Certificate)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1:MBEDTLS_MD_CAN_SHA256
+mbedtls_x509_get_ca_istrue:"data_files/server1-v1.crt":MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
X509 Get time (UTC no issues)
depends_on:MBEDTLS_X509_USE_C
x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 66477e0..f3ae0f4 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -1083,6 +1083,21 @@
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_FS_IO */
+void mbedtls_x509_get_ca_istrue(char *crt_file, int result)
+{
+ mbedtls_x509_crt crt;
+ mbedtls_x509_crt_init(&crt);
+ USE_PSA_INIT();
+
+ TEST_EQUAL(mbedtls_x509_crt_parse_file(&crt, crt_file), 0);
+ TEST_EQUAL(mbedtls_x509_crt_get_ca_istrue(&crt), result);
+exit:
+ mbedtls_x509_crt_free(&crt);
+ USE_PSA_DONE();
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
void x509parse_crt(data_t *buf, char *result_str, int result)
{
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 3d84c72..1db7e1c 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -284,7 +284,7 @@
{
mbedtls_pk_context key;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
- psa_algorithm_t md_alg_psa, alg_psa;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_x509write_csr req;
unsigned char buf[4096];
int ret;
@@ -297,24 +297,16 @@
memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
- md_alg_psa = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) md_type);
- TEST_ASSERT(md_alg_psa != MBEDTLS_MD_NONE);
-
mbedtls_pk_init(&key);
TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL,
mbedtls_test_rnd_std_rand, NULL) == 0);
- if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) {
- alg_psa = PSA_ALG_ECDSA(md_alg_psa);
- } else if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_RSA) {
- alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(md_alg_psa);
- } else {
- TEST_ASSUME(!"PK key type not supported in this configuration");
- }
-
- TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&key, &key_id, alg_psa,
- PSA_KEY_USAGE_SIGN_HASH,
- PSA_ALG_NONE) == 0);
+ /* Turn the PK context into an opaque one. */
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&key, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&key, &key_attr, &key_id), 0);
+ mbedtls_pk_free(&key);
+ mbedtls_pk_init(&key);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&key, key_id), 0);
mbedtls_x509write_csr_set_md_alg(&req, md_type);
mbedtls_x509write_csr_set_key(&req, &key);
@@ -373,6 +365,7 @@
mbedtls_test_rnd_pseudo_info rnd_info;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
#endif
mbedtls_pk_type_t issuer_key_type;
mbedtls_x509_san_list san_ip;
@@ -451,24 +444,14 @@
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- /* For Opaque PK contexts, wrap key as an Opaque RSA context. */
+ /* Turn the issuer PK context into an opaque one. */
if (pk_wrap == 2) {
- psa_algorithm_t alg_psa, md_alg_psa;
-
- md_alg_psa = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) md_type);
- TEST_ASSERT(md_alg_psa != MBEDTLS_MD_NONE);
-
- if (mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_ECKEY) {
- alg_psa = PSA_ALG_ECDSA(md_alg_psa);
- } else if (mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_RSA) {
- alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(md_alg_psa);
- } else {
- TEST_ASSUME(!"PK key type not supported in this configuration");
- }
-
- TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&issuer_key, &key_id, alg_psa,
- PSA_KEY_USAGE_SIGN_HASH,
- PSA_ALG_NONE) == 0);
+ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&issuer_key, PSA_KEY_USAGE_SIGN_HASH,
+ &key_attr), 0);
+ TEST_EQUAL(mbedtls_pk_import_into_psa(&issuer_key, &key_attr, &key_id), 0);
+ mbedtls_pk_free(&issuer_key);
+ mbedtls_pk_init(&issuer_key);
+ TEST_EQUAL(mbedtls_pk_setup_opaque(&issuer_key, key_id), 0);
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
diff --git a/visualc/VS2013/.gitignore b/visualc/VS2017/.gitignore
similarity index 100%
rename from visualc/VS2013/.gitignore
rename to visualc/VS2017/.gitignore