Merge pull request #4338 from paul-elliott-arm/psa-m-aead
Implement multipart PSA AEAD
diff --git a/ChangeLog.d/do-not-use-obsolete-header.txt b/ChangeLog.d/do-not-use-obsolete-header.txt
new file mode 100644
index 0000000..9a57ef1
--- /dev/null
+++ b/ChangeLog.d/do-not-use-obsolete-header.txt
@@ -0,0 +1,5 @@
+Bugfix
+ * Don't use the obsolete header path sys/fcntl.h in unit tests.
+ These header files cause compilation errors in musl.
+ Fixes #4969.
+
diff --git a/ChangeLog.d/muladdc-amd64-memory.txt b/ChangeLog.d/muladdc-amd64-memory.txt
deleted file mode 100644
index b834331..0000000
--- a/ChangeLog.d/muladdc-amd64-memory.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix missing constraints on x86_64 assembly code for bignum multiplication
- that broke some bignum operations with (at least) Clang 12.
- Fixes #4116, #4786, #4917.
diff --git a/ChangeLog.d/muladdc-memory.txt b/ChangeLog.d/muladdc-memory.txt
new file mode 100644
index 0000000..218be5a
--- /dev/null
+++ b/ChangeLog.d/muladdc-memory.txt
@@ -0,0 +1,5 @@
+Bugfix
+ * Fix missing constraints on x86_64 and aarch64 assembly code
+ for bignum multiplication that broke some bignum operations with
+ (at least) Clang 12.
+ Fixes #4116, #4786, #4917, #4962.
diff --git a/docs/architecture/tls13-experimental.md b/docs/architecture/tls13-experimental.md
index 0009c68..5d7c14f 100644
--- a/docs/architecture/tls13-experimental.md
+++ b/docs/architecture/tls13-experimental.md
@@ -66,3 +66,342 @@
as part of `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL`:
- Reader ([`library/mps_reader.h`](../../library/mps_reader.h))
+
+
+MVP definition
+--------------
+
+- Overview
+
+ - The TLS 1.3 MVP implements only the client side of the protocol.
+
+ - The TLS 1.3 MVP supports ECDHE key establishment.
+
+ - The TLS 1.3 MVP does not support DHE key establishment.
+
+ - The TLS 1.3 MVP does not support pre-shared keys, including any form of
+ session resumption. This implies that it does not support sending early
+ data (0-RTT data).
+
+ - The TLS 1.3 MVP supports the authentication of the server by the client
+ but does not support authentication of the client by the server. In terms
+ of TLS 1.3 authentication messages, this means that the TLS 1.3 MVP
+ supports the processing of the Certificate and CertificateVerify messages
+ but not of the CertificateRequest message.
+
+ - The TLS 1.3 MVP does not support the handling of server HelloRetryRequest
+ message. In practice, this means that the handshake will fail if the MVP
+ does not provide in its ClientHello the shared secret associated to the
+ group selected by the server for key establishement. For more information,
+ see the comment associated to the `key_share` extension below.
+
+ - If the TLS 1.3 MVP receives a HelloRetryRequest or a CertificateRequest
+ message, it aborts the handshake with an handshake_failure closure alert
+ and the `mbedtls_ssl_handshake()` returns in error with the
+ `MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE` error code.
+
+- Supported cipher suites: depends on the library configuration. Potentially
+ all of them:
+ TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256,
+ TLS_AES_128_CCM_SHA256 and TLS_AES_128_CCM_8_SHA256.
+
+- Supported ClientHello extensions:
+
+ | Extension | MVP | Prototype (1) |
+ | ---------------------------- | ------- | ------------- |
+ | server_name | YES | YES |
+ | max_fragment_length | no | YES |
+ | status_request | no | no |
+ | supported_groups | YES | YES |
+ | signature_algorithms | YES | YES |
+ | use_srtp | no | no |
+ | heartbeat | no | no |
+ | apln | no | YES |
+ | signed_certificate_timestamp | no | no |
+ | client_certificate_type | no | no |
+ | server_certificate_type | no | no |
+ | padding | no | no |
+ | key_share | YES (2) | YES |
+ | pre_shared_key | no | YES |
+ | psk_key_exchange_modes | no | YES |
+ | early_data | no | YES |
+ | cookie | no | YES |
+ | supported_versions | YES (3) | YES |
+ | certificate_authorities | no | no |
+ | post_handshake_auth | no | no |
+ | signature_algorithms_cert | no | no |
+
+ (1) This is just for comparison.
+
+ (2) The MVP sends one shared secret corresponding to the configured preferred
+ group. The preferred group is the group of the first curve in the list of
+ allowed curves as defined by the configuration. The allowed curves are
+ by default ordered as follow: `secp256r1`, `x25519`, `secp384r1`
+ and finally `secp521r1`. This default order is aligned with the
+ list of mandatory-to-implement groups (in absence of an application
+ profile standard specifying otherwise) defined in section 9.1 of the
+ specification. The list of allowed curves can be changed through the
+ `mbedtls_ssl_conf_curves()` API.
+
+ (3) The MVP proposes only TLS 1.3 and does not support version negociation.
+ Out-of-protocol fallback is supported though if the Mbed TLS library
+ has been built to support both TLS 1.3 and TLS 1.2: just set the
+ maximum of the minor version of the SSL configuration to
+ MBEDTLS_SSL_MINOR_VERSION_3 (`mbedtls_ssl_conf_min_version()` API) and
+ re-initiate a server handshake.
+
+- Supported groups: depends on the library configuration.
+ Potentially all ECDHE groups but x448:
+ secp256r1, x25519, secp384r1 and secp521r1.
+
+ Finite field groups (DHE) are not supported.
+
+- Supported signature algorithms (both for certificates and CertificateVerify):
+ depends on the library configuration.
+ Potentially:
+ rsa_pkcs1_sha256, rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256,
+ ecdsa_secp384r1_sha384 and ecdsa_secp521r1_sha512.
+
+ Note that in absence of an application profile standard specifying otherwise
+ the three first ones in the list above are mandatory (see section 9.1 of the
+ specification).
+
+- Supported versions: only TLS 1.3, version negotiation is not supported.
+
+- Compatibility with existing SSL/TLS build options:
+
+ The TLS 1.3 MVP is compatible with all TLS 1.2 configuration options in the
+ sense that when enabling the TLS 1.3 MVP in the library there is no need to
+ modify the configuration for TLS 1.2. Mbed TLS SSL/TLS related features are
+ not supported or not applicable to the TLS 1.3 MVP:
+
+ | Mbed TLS configuration option | Support |
+ | ---------------------------------------- | ------- |
+ | MBEDTLS_SSL_ALL_ALERT_MESSAGES | no |
+ | MBEDTLS_SSL_ASYNC_PRIVATE | no |
+ | MBEDTLS_SSL_CONTEXT_SERIALIZATION | no |
+ | MBEDTLS_SSL_DEBUG_ALL | no |
+ | MBEDTLS_SSL_ENCRYPT_THEN_MAC | n/a |
+ | MBEDTLS_SSL_EXTENDED_MASTER_SECRET | n/a |
+ | MBEDTLS_SSL_KEEP_PEER_CERTIFICATE | no |
+ | MBEDTLS_SSL_RENEGOTIATION | n/a |
+ | MBEDTLS_SSL_MAX_FRAGMENT_LENGTH | no |
+ | | |
+ | MBEDTLS_SSL_SESSION_TICKETS | no |
+ | MBEDTLS_SSL_EXPORT_KEYS | no (1) |
+ | MBEDTLS_SSL_SERVER_NAME_INDICATION | no |
+ | MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH | no |
+ | | |
+ | MBEDTLS_ECP_RESTARTABLE | no |
+ | MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED | no |
+ | | |
+ | MBEDTLS_KEY_EXCHANGE_PSK_ENABLED | n/a (2) |
+ | MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_RSA_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED | n/a |
+ | MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED | n/a |
+ | | |
+ | MBEDTLS_USE_PSA_CRYPTO | no |
+
+ (1) Some support has already been upstreamed but it is incomplete.
+ (2) Key exchange configuration options for TLS 1.3 will likely to be
+ organized around the notion of key exchange mode along the line
+ of the MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_NONE/PSK/PSK_EPHEMERAL/EPHEMERAL
+ runtime configuration macros.
+
+- Quality considerations
+ - Standard Mbed TLS review bar
+ - Interoperability testing with OpenSSL and GnuTLS. Test with all the
+ cipher suites and signature algorithms supported by OpenSSL/GnuTLS server.
+ - Negative testing against OpenSSL/GnuTLS servers with which the
+ handshake fails due to incompatibility with the capabilities of the
+ MVP: TLS 1.2 or 1.1 server, server sending an HelloRetryRequest message in
+ response to the MVP ClientHello, server sending a CertificateRequest
+ message ...
+
+Coding rules checklist for TLS 1.3
+----------------------------------
+
+The following coding rules are aimed to be a checklist for TLS 1.3 upstreaming
+work to reduce review rounds and the number of comments in each round. They
+come along (do NOT replace) the project coding rules
+(https://tls.mbed.org/kb/development/mbedtls-coding-standards). They have been
+established and discussed following the review of #4882 that was the
+PR upstreaming the first part of TLS 1.3 ClientHello writing code.
+
+TLS 1.3 specific coding rules:
+
+ - TLS 1.3 specific C modules, headers, static functions names are prefixed
+ with `ssl_tls13_`. The same applies to structures and types that are
+ internal to C modules.
+
+ - TLS 1.3 specific exported functions, structures and types are
+ prefixed with `mbedtls_ssl_tls13_`.
+
+ - Use TLS1_3 in TLS 1.3 specific macros.
+
+ - The names of macros and variables related to a field or structure in the
+ TLS 1.3 specification should contain as far as possible the field name as
+ it is in the specification. If the field name is "too long" and we prefer
+ to introduce some kind of abbreviation of it, use the same abbreviation
+ everywhere in the code.
+
+ Example 1: #define CLIENT_HELLO_RANDOM_LEN 32, macro for the length of the
+ `random` field of the ClientHello message.
+
+ Example 2 (consistent abbreviation): `mbedtls_ssl_tls1_3_write_sig_alg_ext()`
+ and `MBEDTLS_TLS_EXT_SIG_ALG`, `sig_alg` standing for
+ `signature_algorithms`.
+
+ - Regarding vectors that are represented by a length followed by their value
+ in the data exchanged between servers and clients:
+
+ - Use `<vector name>_len` for the name of a variable used to compute the
+ length in bytes of the vector, where <vector name> is the name of the
+ vector as defined in the TLS 1.3 specification.
+
+ - Use `p_<vector_name>_len` for the name of a variable intended to hold
+ the address of the first byte of the vector length.
+
+ - Use `<vector_name>` for the name of a variable intended to hold the
+ address of the first byte of the vector value.
+
+ - Use `<vector_name>_end` for the name of a variable intended to hold
+ the address of the first byte past the vector value.
+
+ Those idioms should lower the risk of mis-using one of the address in place
+ of another one which could potentially lead to some nasty issues.
+
+ Example: `cipher_suites` vector of ClientHello in
+ `ssl_tls1_3_write_client_hello_cipher_suites()`
+ ```
+ size_t cipher_suites_len;
+ unsigned char *p_cipher_suites_len;
+ unsigned char *cipher_suites;
+ ```
+
+ - Where applicable, use:
+ - the macros to extract a byte from a multi-byte integer MBEDTLS_BYTE_{0-8}.
+ - the macros to write in memory in big-endian order a multi-byte integer
+ MBEDTLS_PUT_UINT{8|16|32|64}_BE.
+ - the macros to read from memory a multi-byte integer in big-endian order
+ MBEDTLS_GET_UINT{8|16|32|64}_BE.
+ - the macro to check for space when writing into an output buffer
+ `MBEDTLS_SSL_CHK_BUF_PTR`.
+ - 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.
+
+ The two last types, `MBEDTLS_SSL_CHK_BUF_PTR` and
+ `MBEDTLS_SSL_CHK_BUF_READ_PTR`, improve the readability of the code and
+ reduce the risk of error in the non-completely-trivial arithmetic to
+ check that we do not write or read past the end of a data buffer. The
+ usage of those macros combined with the following rule mitigate the risk
+ to read/write past the end of a data buffer.
+
+ Examples:
+ ```
+ hs_hdr[1] = MBEDTLS_BYTE_2( total_hs_len );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0 );
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 );
+ ```
+
+ - To mitigate what happened here
+ (https://github.com/ARMmbed/mbedtls/pull/4882#discussion_r701704527) from
+ happening again, use always a local variable named `p` for the reading
+ pointer in functions parsing TLS 1.3 data, and for the writing pointer in
+ functions writing data into an output buffer and only that variable. The
+ name `p` has been chosen as it was already widely used in TLS code.
+
+ - When an TLS 1.3 structure is written or read by a function or as part of
+ a function, provide as documentation the definition of the structure as
+ it is in the TLS 1.3 specification.
+
+General coding rules:
+
+ - We prefer grouping "related statement lines" by not adding blank lines
+ between them.
+
+ Example 1:
+ ```
+ ret = ssl_tls13_write_client_hello_cipher_suites( ssl, buf, end, &output_len );
+ if( ret != 0 )
+ return( ret );
+ buf += output_len;
+ ```
+
+ Example 2:
+ ```
+ MBEDTLS_SSL_CHK_BUF_PTR( cipher_suites_iter, end, 2 );
+ MBEDTLS_PUT_UINT16_BE( cipher_suite, cipher_suites_iter, 0 );
+ cipher_suites_iter += 2;
+ ```
+
+ - Use macros for constants that are used in different functions, different
+ places in the code. When a constant is used only locally in a function
+ (like the length in bytes of the vector lengths in functions reading and
+ writing TLS handshake message) there is no need to define a macro for it.
+
+ Example: `#define CLIENT_HELLO_RANDOM_LEN 32`
+
+ - When declaring a pointer the dereferencing operator should be prepended to
+ the pointer name not appended to the pointer type:
+
+ Example: `mbedtls_ssl_context *ssl;`
+
+ - Maximum line length is 80 characters.
+
+ Exceptions:
+
+ - string literals can extend beyond 80 characters as we do not want to
+ split them to ease their search in the code base.
+
+ - A line can be more than 80 characters by a few characters if just looking
+ at the 80 first characters is enough to fully understand the line. For
+ example it is generally fine if some closure characters like ";" or ")"
+ are beyond the 80 characters limit.
+
+ If a line becomes too long due to a refactoring (for example renaming a
+ function to a longer name, or indenting a block more), avoid rewrapping
+ lines in the same commit: it makes the review harder. Make one commit with
+ the longer lines and another commit with just the rewrapping.
+
+ - When in successive lines, functions and macros parameters should be aligned
+ vertically.
+
+ Example:
+ ```
+ int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
+ unsigned hs_type,
+ unsigned char **buf,
+ size_t *buf_len );
+ ```
+
+ - When a function's parameters span several lines, group related parameters
+ together if possible.
+
+ For example, prefer:
+
+ ```
+ mbedtls_ssl_tls13_start_handshake_msg( ssl, hs_type,
+ buf, buf_len );
+ ```
+ over
+ ```
+ mbedtls_ssl_tls13_start_handshake_msg( ssl, hs_type, buf,
+ buf_len );
+ ```
+ even if it fits.
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
new file mode 100644
index 0000000..6ec2dca
--- /dev/null
+++ b/docs/use-psa-crypto.md
@@ -0,0 +1,204 @@
+This document describes the compile-time configuration option
+`MBEDTLS_USE_PSA_CRYPTO` from a user's perspective, more specifically its
+current effects as well as the parts that aren't covered yet.
+
+Current effects
+===============
+
+General limitations
+-------------------
+
+Compile-time: enabling `MBEDTLS_USE_PSA_CRYPTO` requires
+`MBEDTLS_ECP_RESTARTABLE` and
+`MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` to be disabled.
+
+Effect: `MBEDTLS_USE_PSA_CRYPTO` currently has no effect on TLS 1.3 (which is
+itself experimental and only partially supported so far): TLS 1.3 always uses
+the legacy APIs even when this option is set.
+
+Stability: any API that's only available when `MBEDTLS_USE_PSA_CRYPTO` is
+defined is considered experimental and may change in incompatible ways at any
+time. Said otherwise, these APIs are explicitly excluded from the usual API
+stability promises.
+
+New APIs / API extensions
+-------------------------
+
+Some of these APIs are meant for the application to use in place of
+pre-existing APIs, in order to get access to the benefits; in the sub-sections
+below these are indicated by "Use in (X.509 and) TLS: opt-in", meaning that
+this requires changes to the application code for the (X.509 and) TLS layers
+to pick up the improvements.
+
+Some of these APIs are mostly meant for internal use by the TLS (and X.509)
+layers; they are indicated below by "Use in (X.509 and) TLS: automatic",
+meaning that no changes to the application code are required for the TLS (and
+X.509) layers to pick up the improvements.
+
+### PSA-held (opaque) keys in the PK layer
+
+There is a new API function `mbedtls_pk_setup_opaque()` that can be used to
+wrap a PSA keypair into a PK context. The key can be used for private-key
+operations and its public part can be exported.
+
+Benefits: isolation of long-term secrets, use of PSA Crypto drivers.
+
+Limitations: only for private keys, only ECC. (That is, only ECDSA signature
+generation. Note: currently this will use randomized ECDSA while Mbed TLS uses
+deterministic ECDSA by default.) The following operations are not supported
+with a context set this way, while they would be available with a normal
+`ECKEY` context: `mbedtls_pk_verify()`, `mbedtls_pk_check_pair()`,
+`mbedtls_pk_debug()`.
+
+Use in X.509 and TLS: opt-in. The application needs to construct the PK context
+using the new API in order to get the benefits; it can then pass the
+resulting context to the following existing APIs:
+
+- `mbedtls_ssl_conf_own_cert()` or `mbedtls_ssl_set_hs_own_cert()` to use the
+ key together with a certificate for ECDSA-based key exchanges (note: while
+this is supported on both sides, it's currently only tested client-side);
+- `mbedtls_x509write_csr_set_key()` to generate a CSR (certificate signature
+ request).
+
+In the TLS and X.509 API, there are two other functions which accept a key or
+keypair as a PK context: `mbedtls_x509write_crt_set_subject_key()` and
+`mbedtls_x509write_crt_set_issuer_key()`. Use of opaque contexts here probably
+works but is so far untested.
+
+### PSA-held (opaque) keys for TLS pre-shared keys (PSK)
+
+There are two new API functions `mbedtls_ssl_conf_psk_opaque()` and
+`mbedtls_ssl_set_hs_psk_opaque()`. Call one of these from an application to
+register a PSA key for use with a PSK key exchange.
+
+Benefits: isolation of long-term secrets.
+
+Limitations: the key can only be used with "pure"
+PSK key exchanges (ciphersuites starting with `TLS_PSK_WITH_`), to the
+exclusion of RSA-PSK, DHE-PSK and ECDHE-PSK key exchanges. It is the responsibility of
+the user to make sure that when provisioning an opaque pre-shared key, the
+only PSK ciphersuites that can be negotiated are "pure" PSK; other XXX-PSK key
+exchanges will result in a handshake failure with the handshake function
+returning `MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE`.
+
+Use in TLS: opt-in. The application needs to register the key using the new
+APIs to get the benefits.
+
+### PSA-based operations in the Cipher layer
+
+There is a new API function `mbedtls_cipher_setup_psa()` to set up a context
+that will call PSA to store the key and perform the operations.
+
+Benefits: use of PSA Crypto drivers; partial isolation of short-term secrets
+(still generated outside of PSA, but then held by PSA).
+
+Limitations: the key is still passed in the clear by the application. The
+multi-part APIs are not supported, only the one-shot APIs. The only modes
+supported are ECB, CBC without padding, GCM and CCM (this excludes stream
+ciphers and ChachaPoly); the only cipher supported is AES (this excludes Aria,
+Camellia, and ChachaPoly). (Note: ECB is currently not tested.) (Note: it is
+possible to perform multiple one-shot operations with the same context;
+however this is not unit-tested, only tested via usage in TLS.)
+
+Use in TLS: automatic. Used when the cipher and mode is supported (with
+gracious fallback to the legacy API otherwise) in all places where a cipher is
+used. There are two such places: in `ssl_tls.c` for record protection, and in
+`ssl_ticket.c` for protecting tickets we issue.
+
+Internal changes
+----------------
+
+All of these internal changes are active as soon as `MBEDTLS_USE_PSA_CRYPTO`
+is enabled, no change required on the application side.
+
+### TLS: cipher operations based on PSA
+
+See "PSA-based operations in the Cipher layer" above.
+
+### PK layer: ECDSA verification based on PSA
+
+Scope: `mbedtls_pk_verify()` will call to PSA for ECDSA signature
+verification.
+
+Benefits: use of PSA Crypto drivers.
+
+Use in TLS and X.509: in all places where an ECDSA signature is verified.
+
+### TLS: ECDHE computation based on PSA
+
+Scope: Client-side, for ECDHE-RSA and ECDHE-ECDSA key exchanges, the
+computation of the ECDHE key exchange is done by PSA.
+
+Limitations: client-side only, ECDHE-PSK not covered
+
+Benefits: use of PSA Crypto drivers.
+
+### TLS: handshake hashes and PRF computed with PSA
+
+Scope: with TLS 1.2, the following are computed with PSA:
+- the running handshake hashes;
+- the hash of the ServerKeyExchange part that is signed;
+- the `verify_data` part of the Finished message;
+- the TLS PRF.
+
+Benefits: use of PSA Crypto drivers.
+
+### X.509: some hashes computed with PSA
+
+Scope: the following hashes are computed with PSA:
+- when verifying a certificate chain, hash of the child for verifying the
+ parent's signature;
+- when writing a CSR, hash of the request for self-signing the request.
+
+Benefits: use of PSA Crypto drivers.
+
+Parts that are not covered yet
+==============================
+
+This is only a high-level overview, grouped by theme
+
+TLS: 1.3 experimental support
+-----------------------------
+
+No part of the experimental support for TLS 1.3 is covered at the moment.
+
+TLS: key exchanges / asymmetric crypto
+--------------------------------------
+
+The following key exchanges are not covered at all:
+
+- RSA
+- DHE-RSA
+- DHE-PSK
+- RSA-PSK
+- ECDHE-PSK
+- ECDH-RSA
+- ECDH-ECDSA
+- ECJPAKE
+
+The following key exchanges are only partially covered:
+
+- ECDHE-RSA: RSA operations are not covered and, server-side, the ECDHE
+ operation isn't either
+- ECDHE-ECDSA: server-side, the ECDHE operation isn't covered. (ECDSA
+ signature generation is only covered if using `mbedtls_pk_setup_opaque()`.)
+
+PSK if covered when the application uses `mbedtls_ssl_conf_psk_opaque()` or
+`mbedtls_ssl_set_hs_psk_opaque()`.
+
+TLS: symmetric crypto
+---------------------
+
+- some ciphers not supported via PSA yet: ARIA, Camellia, ChachaPoly (silent
+ fallback to the legacy APIs)
+- the HMAC part of the CBC and NULL ciphersuites
+- the HMAC computation in `ssl_cookie.c`
+
+X.509
+-----
+
+- most hash operations are still done via the legacy API, except the few that
+ are documented above as using PSA
+- RSA PKCS#1 v1.5 signature generation (from PSA-held keys)
+- RSA PKCS#1 v1.5 signature verification
+- RSA-PSS signature verification
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index f45fc17..4746c1c 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -152,9 +152,9 @@
*/
typedef struct mbedtls_asn1_buf
{
- int MBEDTLS_PRIVATE(tag); /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
- size_t MBEDTLS_PRIVATE(len); /**< ASN1 length, in octets. */
- unsigned char *MBEDTLS_PRIVATE(p); /**< ASN1 data, e.g. in ASCII. */
+ int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
+ size_t len; /**< ASN1 length, in octets. */
+ unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
}
mbedtls_asn1_buf;
@@ -163,9 +163,9 @@
*/
typedef struct mbedtls_asn1_bitstring
{
- size_t MBEDTLS_PRIVATE(len); /**< ASN1 length, in octets. */
- unsigned char MBEDTLS_PRIVATE(unused_bits); /**< Number of unused bits at the end of the string */
- unsigned char *MBEDTLS_PRIVATE(p); /**< Raw ASN1 data for the bit string */
+ size_t len; /**< ASN1 length, in octets. */
+ unsigned char unused_bits; /**< Number of unused bits at the end of the string */
+ unsigned char *p; /**< Raw ASN1 data for the bit string */
}
mbedtls_asn1_bitstring;
@@ -174,8 +174,16 @@
*/
typedef struct mbedtls_asn1_sequence
{
- mbedtls_asn1_buf MBEDTLS_PRIVATE(buf); /**< Buffer containing the given ASN.1 item. */
- struct mbedtls_asn1_sequence *MBEDTLS_PRIVATE(next); /**< The next entry in the sequence. */
+ mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
+
+ /** The next entry in the sequence.
+ *
+ * The details of memory management for sequences are not documented and
+ * may change in future versions. Set this field to \p NULL when
+ * initializing a structure, and do not modify it except via Mbed TLS
+ * library functions.
+ */
+ struct mbedtls_asn1_sequence *next;
}
mbedtls_asn1_sequence;
@@ -184,10 +192,24 @@
*/
typedef struct mbedtls_asn1_named_data
{
- mbedtls_asn1_buf MBEDTLS_PRIVATE(oid); /**< The object identifier. */
- mbedtls_asn1_buf MBEDTLS_PRIVATE(val); /**< The named value. */
- struct mbedtls_asn1_named_data *MBEDTLS_PRIVATE(next); /**< The next entry in the sequence. */
- unsigned char MBEDTLS_PRIVATE(next_merged); /**< Merge next item into the current one? */
+ mbedtls_asn1_buf oid; /**< The object identifier. */
+ mbedtls_asn1_buf val; /**< The named value. */
+
+ /** The next entry in the sequence.
+ *
+ * The details of memory management for named data sequences are not
+ * documented and may change in future versions. Set this field to \p NULL
+ * when initializing a structure, and do not modify it except via Mbed TLS
+ * library functions.
+ */
+ struct mbedtls_asn1_named_data *next;
+
+ /** Merge next item into the current one?
+ *
+ * This field exists for the sake of Mbed TLS's X.509 certificate parsing
+ * code and may change in future versions of the library.
+ */
+ unsigned char MBEDTLS_PRIVATE(next_merged);
}
mbedtls_asn1_named_data;
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 9c9a2e8..b4630f6 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -258,6 +258,13 @@
/**
* Cipher information. Allows calling cipher functions
* in a generic way.
+ *
+ * \note The library does not support custom cipher info structures,
+ * only built-in structures returned by the functions
+ * mbedtls_cipher_info_from_string(),
+ * mbedtls_cipher_info_from_type(),
+ * mbedtls_cipher_info_from_values(),
+ * mbedtls_cipher_info_from_psa().
*/
typedef struct mbedtls_cipher_info_t
{
@@ -415,6 +422,82 @@
const mbedtls_cipher_mode_t mode );
/**
+ * \brief Retrieve the identifier for a cipher info structure.
+ *
+ * \param[in] info The cipher info structure to query.
+ * This may be \c NULL.
+ *
+ * \return The full cipher identifier (\c MBEDTLS_CIPHER_xxx).
+ * \return #MBEDTLS_CIPHER_NONE if \p info is \c NULL.
+ */
+static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type(
+ const mbedtls_cipher_info_t *info )
+{
+ if( info == NULL )
+ return( MBEDTLS_CIPHER_NONE );
+ else
+ return( info->MBEDTLS_PRIVATE(type) );
+}
+
+/**
+ * \brief Retrieve the operation mode for a cipher info structure.
+ *
+ * \param[in] info The cipher info structure to query.
+ * This may be \c NULL.
+ *
+ * \return The cipher mode (\c MBEDTLS_MODE_xxx).
+ * \return #MBEDTLS_MODE_NONE if \p info is \c NULL.
+ */
+static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode(
+ const mbedtls_cipher_info_t *info )
+{
+ if( info == NULL )
+ return( MBEDTLS_MODE_NONE );
+ else
+ return( info->MBEDTLS_PRIVATE(mode) );
+}
+
+/**
+ * \brief Retrieve the key size for a cipher info structure.
+ *
+ * \param[in] info The cipher info structure to query.
+ * This may be \c NULL.
+ *
+ * \return The key length in bits.
+ * For variable-sized ciphers, this is the default length.
+ * For DES, this includes the parity bits.
+ * \return \c 0 if \p info is \c NULL.
+ */
+static inline size_t mbedtls_cipher_info_get_key_bitlen(
+ const mbedtls_cipher_info_t *info )
+{
+ if( info == NULL )
+ return( 0 );
+ else
+ return( info->MBEDTLS_PRIVATE(key_bitlen) );
+}
+
+/**
+ * \brief Retrieve the human-readable name for a
+ * cipher info structure.
+ *
+ * \param[in] info The cipher info structure to query.
+ * This may be \c NULL.
+ *
+ * \return The cipher name, which is a human readable string,
+ * with static storage duration.
+ * \return \c NULL if \c info is \p NULL.
+ */
+static inline const char *mbedtls_cipher_info_get_name(
+ const mbedtls_cipher_info_t *info )
+{
+ if( info == NULL )
+ return( NULL );
+ else
+ return( info->MBEDTLS_PRIVATE(name) );
+}
+
+/**
* \brief This function initializes a \p cipher_context as NONE.
*
* \param ctx The context to be initialized. This must not be \c NULL.
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 9080cd1..3b01b78 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -586,7 +586,7 @@
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1
-#endif /* MBEDTLSS_PKCS1_V15 */
+#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
#define PSA_WANT_ALG_RSA_OAEP 1
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 384d060..b2a2e32 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -147,13 +147,17 @@
/**
* Curve information, for use by other modules.
+ *
+ * The fields of this structure are part of the public API and can be
+ * accessed directly by applications. Future versions of the library may
+ * add extra fields or reorder existing fields.
*/
typedef struct mbedtls_ecp_curve_info
{
- mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id); /*!< An internal identifier. */
- uint16_t MBEDTLS_PRIVATE(tls_id); /*!< The TLS NamedCurve identifier. */
- uint16_t MBEDTLS_PRIVATE(bit_size); /*!< The curve size in bits. */
- const char *MBEDTLS_PRIVATE(name); /*!< A human-friendly name. */
+ mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */
+ uint16_t tls_id; /*!< The TLS NamedCurve identifier. */
+ uint16_t bit_size; /*!< The curve size in bits. */
+ const char *name; /*!< A human-friendly name. */
} mbedtls_ecp_curve_info;
/**
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index d470c00..adc317d 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1718,15 +1718,13 @@
* will still continue to work as usual, so enabling this option should not
* break backwards compatibility.
*
- * \warning The PSA Crypto API is in beta stage. While you're welcome to
- * experiment using it, incompatible API changes are still possible, and some
- * parts may not have reached the same quality as the rest of Mbed TLS yet.
+ * \note See docs/use-psa-crypto.md for a complete description of what this
+ * option currently does, and of parts that are not affected by it so far.
*
- * \warning This option enables new Mbed TLS APIs that are dependent on the
- * PSA Crypto API, so can't come with the same stability guarantees as the
- * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for
- * now, access to these APIs is opt-in (via enabling the present option), in
- * order to clearly differentiate them from the stable Mbed TLS APIs.
+ * \warning This option enables new Mbed TLS APIs which are currently
+ * considered experimental and may change in incompatible ways at any time.
+ * That is, the APIs enabled by this option are not covered by the usual
+ * promises of API stability.
*
* Requires: MBEDTLS_PSA_CRYPTO_C.
*
@@ -2592,10 +2590,6 @@
*
* Enable the Platform Security Architecture cryptography API.
*
- * \warning The PSA Crypto API is still beta status. While you're welcome to
- * experiment using it, incompatible API changes are still possible, and some
- * parts may not have reached the same quality as the rest of Mbed TLS yet.
- *
* Module: library/psa_crypto.c
*
* Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
@@ -3179,7 +3173,7 @@
* Maximum number of heap-allocated bytes for the purpose of
* DTLS handshake message reassembly and future message buffering.
*
- * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN
* to account for a reassembled handshake message of maximum size,
* together with its reassembly bitmap.
*
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index c8214a2..0c754b1 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -94,7 +94,13 @@
*/
typedef struct mbedtls_net_context
{
- int MBEDTLS_PRIVATE(fd); /**< The underlying file descriptor */
+ /** The underlying file descriptor.
+ *
+ * This field is only guaranteed to be present on POSIX/Unix-like platforms.
+ * On other platforms, it may have a different type, have a different
+ * meaning, or be absent altogether.
+ */
+ int fd;
}
mbedtls_net_context;
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index ded5222..5f9f29f 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -186,6 +186,10 @@
/**
* \brief Public key information and operations
+ *
+ * \note The library does not support custom pk info structures,
+ * only built-in structures returned by
+ * mbedtls_cipher_info_from_type().
*/
typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index f6f2e58..6f63545 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -369,7 +369,7 @@
if( curve_info == NULL )
return( 0 );
return( PSA_KEY_TYPE_ECC_KEY_PAIR(
- mbedtls_ecc_group_to_psa( curve_info->MBEDTLS_PRIVATE(grp_id), bits ) ) );
+ mbedtls_ecc_group_to_psa( curve_info->grp_id, bits ) ) );
}
#endif /* MBEDTLS_ECP_C */
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index f533859..2349245 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -170,6 +170,37 @@
#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80
/*
+ * TLS 1.3 NamedGroup values
+ *
+ * From RF 8446
+ * enum {
+ * // Elliptic Curve Groups (ECDHE)
+ * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
+ * x25519(0x001D), x448(0x001E),
+ * // Finite Field Groups (DHE)
+ * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
+ * ffdhe6144(0x0103), ffdhe8192(0x0104),
+ * // Reserved Code Points
+ * ffdhe_private_use(0x01FC..0x01FF),
+ * ecdhe_private_use(0xFE00..0xFEFF),
+ * (0xFFFF)
+ * } NamedGroup;
+ *
+ */
+/* Elliptic Curve Groups (ECDHE) */
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP256R1 0x0017
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP384R1 0x0018
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP521R1 0x0019
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_X25519 0x001D
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_X448 0x001E
+/* Finite Field Groups (DHE) */
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE2048 0x0100
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE3072 0x0101
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE4096 0x0102
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE6144 0x0103
+#define MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE8192 0x0104
+
+/*
* TLS 1.3 Key Exchange Modes
*
* Mbed TLS internal identifiers for use with the SSL configuration API
@@ -592,6 +623,7 @@
MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
MBEDTLS_SSL_ENCRYPTED_EXTENSIONS,
+ MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY,
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
}
mbedtls_ssl_states;
@@ -1495,6 +1527,19 @@
int MBEDTLS_PRIVATE(keep_current_message); /*!< drop or reuse current message
on next call to record layer? */
+ /* The following three variables indicate if and, if yes,
+ * what kind of alert is pending to be sent.
+ */
+ unsigned char MBEDTLS_PRIVATE(send_alert); /*!< Determines if a fatal alert
+ should be sent. Values:
+ - \c 0 , no alert is to be sent.
+ - \c 1 , alert is to be sent. */
+ unsigned char MBEDTLS_PRIVATE(alert_type); /*!< Type of alert if send_alert
+ != 0 */
+ int MBEDTLS_PRIVATE(alert_reason); /*!< The error code to be returned
+ to the user once the fatal alert
+ has been sent. */
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint8_t MBEDTLS_PRIVATE(disable_datagram_packing); /*!< Disable packing multiple records
* within a single datagram. */
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index df187cb..9a4be95 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -246,8 +246,8 @@
/** Container for date and time (precision in seconds). */
typedef struct mbedtls_x509_time
{
- int MBEDTLS_PRIVATE(year), MBEDTLS_PRIVATE(mon), MBEDTLS_PRIVATE(day); /**< Date. */
- int MBEDTLS_PRIVATE(hour), MBEDTLS_PRIVATE(min), MBEDTLS_PRIVATE(sec); /**< Time. */
+ int year, mon, day; /**< Date. */
+ int hour, min, sec; /**< Time. */
}
mbedtls_x509_time;
diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h
index 9331827..52bd43c 100644
--- a/include/mbedtls/x509_crl.h
+++ b/include/mbedtls/x509_crl.h
@@ -43,18 +43,30 @@
/**
* Certificate revocation list entry.
* Contains the CA-specific serial numbers and revocation dates.
+ *
+ * Some fields of this structure are publicly readable. Do not modify
+ * them except via Mbed TLS library functions: the effect of modifying
+ * those fields or the data that those fields points to is unspecified.
*/
typedef struct mbedtls_x509_crl_entry
{
- mbedtls_x509_buf MBEDTLS_PRIVATE(raw);
+ /** Direct access to the whole entry inside the containing buffer. */
+ mbedtls_x509_buf raw;
+ /** The serial number of the revoked certificate. */
+ mbedtls_x509_buf serial;
+ /** The revocation date of this entry. */
+ mbedtls_x509_time revocation_date;
+ /** Direct access to the list of CRL entry extensions
+ * (an ASN.1 constructed sequence).
+ *
+ * If there are no extensions, `entry_ext.len == 0` and
+ * `entry_ext.p == NULL`. */
+ mbedtls_x509_buf entry_ext;
- mbedtls_x509_buf MBEDTLS_PRIVATE(serial);
-
- mbedtls_x509_time MBEDTLS_PRIVATE(revocation_date);
-
- mbedtls_x509_buf MBEDTLS_PRIVATE(entry_ext);
-
- struct mbedtls_x509_crl_entry *MBEDTLS_PRIVATE(next);
+ /** Next element in the linked list of entries.
+ * \p NULL indicates the end of the list.
+ * Do not modify this field directly. */
+ struct mbedtls_x509_crl_entry *next;
}
mbedtls_x509_crl_entry;
@@ -64,22 +76,22 @@
*/
typedef struct mbedtls_x509_crl
{
- mbedtls_x509_buf MBEDTLS_PRIVATE(raw); /**< The raw certificate data (DER). */
- mbedtls_x509_buf MBEDTLS_PRIVATE(tbs); /**< The raw certificate body (DER). The part that is To Be Signed. */
+ mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
+ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
- int MBEDTLS_PRIVATE(version); /**< CRL version (1=v1, 2=v2) */
- mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid); /**< CRL signature type identifier */
+ int version; /**< CRL version (1=v1, 2=v2) */
+ mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */
- mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw); /**< The raw issuer data (DER). */
+ mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */
- mbedtls_x509_name MBEDTLS_PRIVATE(issuer); /**< The parsed issuer data (named information object). */
+ mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */
- mbedtls_x509_time MBEDTLS_PRIVATE(this_update);
- mbedtls_x509_time MBEDTLS_PRIVATE(next_update);
+ mbedtls_x509_time this_update;
+ mbedtls_x509_time next_update;
- mbedtls_x509_crl_entry MBEDTLS_PRIVATE(entry); /**< The CRL entries containing the certificate revocation times for this CA. */
+ mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(crl_ext);
+ mbedtls_x509_buf crl_ext;
mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid2);
mbedtls_x509_buf MBEDTLS_PRIVATE(sig);
@@ -87,7 +99,10 @@
mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk); /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
void *MBEDTLS_PRIVATE(sig_opts); /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
- struct mbedtls_x509_crl *MBEDTLS_PRIVATE(next);
+ /** Next element in the linked list of CRL.
+ * \p NULL indicates the end of the list.
+ * Do not modify this field directly. */
+ struct mbedtls_x509_crl *next;
}
mbedtls_x509_crl;
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 49211a9..3c11a99 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -45,36 +45,40 @@
/**
* Container for an X.509 certificate. The certificate may be chained.
+ *
+ * Some fields of this structure are publicly readable. Do not modify
+ * them except via Mbed TLS library functions: the effect of modifying
+ * those fields or the data that those fields points to is unspecified.
*/
typedef struct mbedtls_x509_crt
{
int MBEDTLS_PRIVATE(own_buffer); /**< Indicates if \c raw is owned
* by the structure or not. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(raw); /**< The raw certificate data (DER). */
- mbedtls_x509_buf MBEDTLS_PRIVATE(tbs); /**< The raw certificate body (DER). The part that is To Be Signed. */
+ mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
+ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
- int MBEDTLS_PRIVATE(version); /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
- mbedtls_x509_buf MBEDTLS_PRIVATE(serial); /**< Unique id for certificate issued by a specific CA. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid); /**< Signature algorithm, e.g. sha1RSA */
+ int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
+ mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */
+ mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */
- mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw); /**< The raw issuer data (DER). Used for quick comparison. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(subject_raw); /**< The raw subject data (DER). Used for quick comparison. */
+ mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
+ mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
- mbedtls_x509_name MBEDTLS_PRIVATE(issuer); /**< The parsed issuer data (named information object). */
- mbedtls_x509_name MBEDTLS_PRIVATE(subject); /**< The parsed subject data (named information object). */
+ mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */
+ mbedtls_x509_name subject; /**< The parsed subject data (named information object). */
- mbedtls_x509_time MBEDTLS_PRIVATE(valid_from); /**< Start time of certificate validity. */
- mbedtls_x509_time MBEDTLS_PRIVATE(valid_to); /**< End time of certificate validity. */
+ mbedtls_x509_time valid_from; /**< Start time of certificate validity. */
+ mbedtls_x509_time valid_to; /**< End time of certificate validity. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(pk_raw);
- mbedtls_pk_context MBEDTLS_PRIVATE(pk); /**< Container for the public key context. */
+ mbedtls_x509_buf pk_raw;
+ mbedtls_pk_context pk; /**< Container for the public key context. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_id); /**< Optional X.509 v2/v3 issuer unique identifier. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(subject_id); /**< Optional X.509 v2/v3 subject unique identifier. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(v3_ext); /**< Optional X.509 v3 extensions. */
- mbedtls_x509_sequence MBEDTLS_PRIVATE(subject_alt_names); /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
+ mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
+ mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
+ mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
+ mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
- mbedtls_x509_sequence MBEDTLS_PRIVATE(certificate_policies); /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */
+ mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */
int MBEDTLS_PRIVATE(ext_types); /**< Bit string containing detected and parsed extensions */
int MBEDTLS_PRIVATE(ca_istrue); /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
@@ -82,7 +86,7 @@
unsigned int MBEDTLS_PRIVATE(key_usage); /**< Optional key usage extension value: See the values in x509.h */
- mbedtls_x509_sequence MBEDTLS_PRIVATE(ext_key_usage); /**< Optional list of extended key usage OIDs. */
+ mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
unsigned char MBEDTLS_PRIVATE(ns_cert_type); /**< Optional Netscape certificate type extension value: See the values in x509.h */
@@ -91,7 +95,10 @@
mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk); /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
void *MBEDTLS_PRIVATE(sig_opts); /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
- struct mbedtls_x509_crt *MBEDTLS_PRIVATE(next); /**< Next certificate in the CA-chain. */
+ /** Next certificate in the linked list that constitutes the CA chain.
+ * \p NULL indicates the end of the list.
+ * Do not modify this field directly. */
+ struct mbedtls_x509_crt *next;
}
mbedtls_x509_crt;
@@ -100,6 +107,9 @@
* OtherName ::= SEQUENCE {
* type-id OBJECT IDENTIFIER,
* value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * Future versions of the library may add new fields to this structure or
+ * to its embedded union and structure.
*/
typedef struct mbedtls_x509_san_other_name
{
@@ -108,7 +118,7 @@
* To check the value of the type id, you should use
* \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
*/
- mbedtls_x509_buf MBEDTLS_PRIVATE(type_id); /**< The type id. */
+ mbedtls_x509_buf type_id; /**< The type id. */
union
{
/**
@@ -119,26 +129,30 @@
*/
struct
{
- mbedtls_x509_buf MBEDTLS_PRIVATE(oid); /**< The object identifier. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(val); /**< The named value. */
+ mbedtls_x509_buf oid; /**< The object identifier. */
+ mbedtls_x509_buf val; /**< The named value. */
}
- MBEDTLS_PRIVATE(hardware_module_name);
+ hardware_module_name;
}
- MBEDTLS_PRIVATE(value);
+ value;
}
mbedtls_x509_san_other_name;
/**
- * A structure for holding the parsed Subject Alternative Name, according to type
+ * A structure for holding the parsed Subject Alternative Name,
+ * according to type.
+ *
+ * Future versions of the library may add new fields to this structure or
+ * to its embedded union and structure.
*/
typedef struct mbedtls_x509_subject_alternative_name
{
- int MBEDTLS_PRIVATE(type); /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
+ int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
union {
- mbedtls_x509_san_other_name MBEDTLS_PRIVATE(other_name); /**< The otherName supported type. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(unstructured_name); /**< The buffer for the un constructed types. Only dnsName currently supported */
+ mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
+ mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
}
- MBEDTLS_PRIVATE(san); /**< A union of the supported SAN types */
+ san; /**< A union of the supported SAN types */
}
mbedtls_x509_subject_alternative_name;
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 674f9ce..f80a1a1 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -42,20 +42,24 @@
/**
* Certificate Signing Request (CSR) structure.
+ *
+ * Some fields of this structure are publicly readable. Do not modify
+ * them except via Mbed TLS library functions: the effect of modifying
+ * those fields or the data that those fields point to is unspecified.
*/
typedef struct mbedtls_x509_csr
{
- mbedtls_x509_buf MBEDTLS_PRIVATE(raw); /**< The raw CSR data (DER). */
- mbedtls_x509_buf MBEDTLS_PRIVATE(cri); /**< The raw CertificateRequestInfo body (DER). */
+ mbedtls_x509_buf raw; /**< The raw CSR data (DER). */
+ mbedtls_x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */
- int MBEDTLS_PRIVATE(version); /**< CSR version (1=v1). */
+ int version; /**< CSR version (1=v1). */
- mbedtls_x509_buf MBEDTLS_PRIVATE(subject_raw); /**< The raw subject data (DER). */
- mbedtls_x509_name MBEDTLS_PRIVATE(subject); /**< The parsed subject data (named information object). */
+ mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). */
+ mbedtls_x509_name subject; /**< The parsed subject data (named information object). */
- mbedtls_pk_context MBEDTLS_PRIVATE(pk); /**< Container for the public key context. */
+ mbedtls_pk_context pk; /**< Container for the public key context. */
- mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid);
+ mbedtls_x509_buf sig_oid;
mbedtls_x509_buf MBEDTLS_PRIVATE(sig);
mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md); /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk); /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
diff --git a/library/bn_mul.h b/library/bn_mul.h
index 328e765..b71ddd8 100644
--- a/library/bn_mul.h
+++ b/library/bn_mul.h
@@ -224,7 +224,7 @@
"adcq %%rdx, %%rcx\n" \
"addq $8, %%rdi\n"
-#define MULADDC_STOP \
+#define MULADDC_STOP \
: "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
: "b" (b), "m" (*(const uint64_t (*)[16]) s) \
: "rax", "rdx", "r8" \
@@ -240,18 +240,18 @@
#define MULADDC_CORE \
"ldr x4, [%2], #8 \n\t" \
"ldr x5, [%1] \n\t" \
- "mul x6, x4, %3 \n\t" \
- "umulh x7, x4, %3 \n\t" \
+ "mul x6, x4, %4 \n\t" \
+ "umulh x7, x4, %4 \n\t" \
"adds x5, x5, x6 \n\t" \
"adc x7, x7, xzr \n\t" \
"adds x5, x5, %0 \n\t" \
"adc %0, x7, xzr \n\t" \
"str x5, [%1], #8 \n\t"
-#define MULADDC_STOP \
- : "+r" (c), "+r" (d), "+r" (s) \
- : "r" (b) \
- : "x4", "x5", "x6", "x7", "cc" \
+#define MULADDC_STOP \
+ : "+r" (c), "+r" (d), "+r" (s), "+m" (*(uint64_t (*)[16]) d) \
+ : "r" (b), "m" (*(const uint64_t (*)[16]) s) \
+ : "x4", "x5", "x6", "x7", "cc" \
);
#endif /* Aarch64 */
diff --git a/library/common.h b/library/common.h
index 780ce37..9b10ec8 100644
--- a/library/common.h
+++ b/library/common.h
@@ -318,4 +318,12 @@
}
#endif
+/* Fix MSVC C99 compatible issue
+ * MSVC support __func__ from visual studio 2015( 1900 )
+ * Use MSVC predefine macro to avoid name check fail.
+ */
+#if (defined(_MSC_VER) && ( _MSC_VER <= 1900 ))
+#define /*no-check-names*/ __func__ __FUNCTION__
+#endif
+
#endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/library/ecdh.c b/library/ecdh.c
index 9dfa868..b72bd1f 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -32,6 +32,8 @@
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
+#include "ecdh_misc.h"
+
#include <string.h>
/* Parameter validation macros based on platform_util.h */
@@ -726,4 +728,84 @@
#endif
}
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+static int ecdh_tls13_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
+ size_t *olen, int point_format, unsigned char *buf, size_t blen,
+ int ( *f_rng )( void *, unsigned char *, size_t), void *p_rng )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ctx->grp.pbits == 0 )
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+ if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
+ f_rng, p_rng ) ) != 0 )
+ return( ret );
+
+ ret = mbedtls_ecp_point_write_binary( &ctx->grp, &ctx->Q, point_format,
+ olen, buf, blen );
+ if( ret != 0 )
+ return( ret );
+
+ return( 0 );
+}
+
+int mbedtls_ecdh_tls13_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
+ unsigned char *buf, size_t blen,
+ int ( *f_rng )( void *, unsigned char *, size_t ),
+ void *p_rng )
+{
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( olen != NULL );
+ ECDH_VALIDATE_RET( buf != NULL );
+ ECDH_VALIDATE_RET( f_rng != NULL );
+
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+ if( ctx-> restart_enabled )
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+ return( ecdh_tls13_make_params_internal( ctx, olen, ctx->point_format,
+ buf, blen, f_rng, p_rng ) );
+#else
+ switch( ctx->var )
+ {
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#endif
+ case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+ return( ecdh_tls13_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
+ ctx->point_format, buf, blen,
+ f_rng, p_rng ) );
+ default:
+ return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ }
+#endif
+}
+
+/*
+ * Setup context without Everest
+ */
+int mbedtls_ecdh_setup_no_everest( mbedtls_ecdh_context *ctx,
+ mbedtls_ecp_group_id grp_id )
+{
+ ECDH_VALIDATE_RET( ctx != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+ return( ecdh_setup_internal( ctx, grp_id ) );
+#else
+ ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+ ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
+ ctx->grp_id = grp_id;
+ ecdh_init_internal( &ctx->ctx.mbed_ecdh );
+ return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
+#endif
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
#endif /* MBEDTLS_ECDH_C */
diff --git a/library/ecdh_misc.h b/library/ecdh_misc.h
new file mode 100644
index 0000000..d1342f8
--- /dev/null
+++ b/library/ecdh_misc.h
@@ -0,0 +1,51 @@
+/**
+ * \file ecdh_misc.h
+ *
+ * \brief Internal functions shared by the ECDH module
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" ); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if !defined(MBEDTLS_ECDH_MISC_H)
+#define MBEDTLS_ECDH_MISC_H
+
+#include "mbedtls/ecdh.h"
+#include "mbedtls/ecp.h"
+
+#if defined(MBEDTLS_ECDH_C)
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+/*
+ * Setup context without Everest
+ */
+int mbedtls_ecdh_setup_no_everest( mbedtls_ecdh_context *ctx,
+ mbedtls_ecp_group_id grp_id );
+
+/*
+ * TLS 1.3 version of mbedtls_ecdh_make_params in ecdh.h
+ */
+int mbedtls_ecdh_tls13_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
+ unsigned char *buf, size_t blen,
+ int ( *f_rng )( void *, unsigned char *, size_t ),
+ void *p_rng );
+
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#endif /* MBEDTLS_ECDH_C */
+
+#endif /* !MBEDTLS_ECDH_MISC_H */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 7035c27..a1128ed 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -649,6 +649,16 @@
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
mbedtls_ssl_tls_prf_cb *tls_prf;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ uint16_t offered_group_id; /* The NamedGroup value for the group
+ * that is being used for ephemeral
+ * key exchange.
+ *
+ * On the client: Defaults to the first
+ * entry in the client's group list,
+ * but can be overwritten by the HRR. */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
size_t pmslen; /*!< premaster length */
@@ -1332,6 +1342,22 @@
int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
+/*
+ * Send pending alert
+ */
+int mbedtls_ssl_handle_pending_alert( mbedtls_ssl_context *ssl );
+
+/*
+ * Set pending fatal alert flag.
+ */
+void mbedtls_ssl_pend_fatal_alert( mbedtls_ssl_context *ssl,
+ unsigned char alert_type,
+ int alert_reason );
+
+/* Alias of mbedtls_ssl_pend_fatal_alert */
+#define MBEDTLS_SSL_PEND_FATAL_ALERT( type, user_return_value ) \
+ mbedtls_ssl_pend_fatal_alert( ssl, type, user_return_value )
+
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
#endif
@@ -1348,6 +1374,49 @@
void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+/*
+ * Helper functions around key exchange modes.
+ */
+static inline unsigned mbedtls_ssl_conf_tls13_check_kex_modes( mbedtls_ssl_context *ssl,
+ int kex_mode_mask )
+{
+ return( ( ssl->conf->tls13_kex_modes & kex_mode_mask ) != 0 );
+}
+
+static inline int mbedtls_ssl_conf_tls13_psk_enabled( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
+ MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK ) );
+}
+
+static inline int mbedtls_ssl_conf_tls13_psk_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
+ MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ) );
+}
+
+static inline int mbedtls_ssl_conf_tls13_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
+ MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL ) );
+}
+
+static inline int mbedtls_ssl_conf_tls13_some_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
+ MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL ) );
+}
+
+static inline int mbedtls_ssl_conf_tls13_some_psk_enabled( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_conf_tls13_check_kex_modes( ssl,
+ MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
/**
* ssl utils functions for checking configuration.
*/
@@ -1396,6 +1465,24 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+/*
+ * Helper functions for NamedGroup.
+ */
+static inline int mbedtls_ssl_tls13_named_group_is_ecdhe( uint16_t named_group )
+{
+ return( named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP256R1 ||
+ named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP384R1 ||
+ named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_SECP521R1 ||
+ named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_X25519 ||
+ named_group == MBEDTLS_SSL_TLS13_NAMED_GROUP_X448 );
+}
+
+static inline int mbedtls_ssl_tls13_named_group_is_dhe( uint16_t named_group )
+{
+ return( named_group >= MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE2048 &&
+ named_group <= MBEDTLS_SSL_TLS13_NAMED_GROUP_FFDHE8192 );
+}
+
static inline void mbedtls_ssl_handshake_set_state( mbedtls_ssl_context *ssl,
mbedtls_ssl_states state )
{
@@ -1430,6 +1517,7 @@
unsigned char *buf,
unsigned char *end,
size_t *olen);
+
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 2fe801a..3bf4a60 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -5639,4 +5639,48 @@
}
}
+/*
+ * Send pending fatal alert.
+ * 0, No alert message.
+ * !0, if mbedtls_ssl_send_alert_message() returned in error, the error code it
+ * returned, ssl->alert_reason otherwise.
+ */
+int mbedtls_ssl_handle_pending_alert( mbedtls_ssl_context *ssl )
+{
+ int ret;
+
+ /* No pending alert, return success*/
+ if( ssl->send_alert == 0 )
+ return( 0 );
+
+ ret = mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ ssl->alert_type );
+
+ /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE,
+ * do not clear the alert to be able to send it later.
+ */
+ if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+ {
+ ssl->send_alert = 0;
+ }
+
+ if( ret != 0 )
+ return( ret );
+
+ return( ssl->alert_reason );
+}
+
+/*
+ * Set pending fatal alert flag.
+ */
+void mbedtls_ssl_pend_fatal_alert( mbedtls_ssl_context *ssl,
+ unsigned char alert_type,
+ int alert_reason )
+{
+ ssl->send_alert = 1;
+ ssl->alert_type = alert_type;
+ ssl->alert_reason = alert_reason;
+}
+
#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index bce9a1c..e998111 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -138,16 +138,14 @@
ctx->ticket_lifetime = lifetime;
cipher_info = mbedtls_cipher_info_from_type( cipher);
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( cipher_info->mode != MBEDTLS_MODE_GCM &&
- cipher_info->mode != MBEDTLS_MODE_CCM )
+ if( mbedtls_cipher_info_get_mode( cipher_info ) != MBEDTLS_MODE_GCM &&
+ mbedtls_cipher_info_get_mode( cipher_info ) != MBEDTLS_MODE_CCM )
{
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES )
+ if( mbedtls_cipher_info_get_key_bitlen( cipher_info ) > 8 * MAX_KEY_BYTES )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 3604192..f33f106 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -689,7 +689,7 @@
unsigned char *mac_dec;
size_t mac_key_len = 0;
size_t iv_copy_len;
- unsigned keylen;
+ size_t keylen;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
const mbedtls_cipher_info_t *cipher_info;
const mbedtls_md_info_t *md_info;
@@ -789,14 +789,14 @@
* Determine the appropriate key, IV and MAC length.
*/
- keylen = cipher_info->key_bitlen / 8;
+ keylen = mbedtls_cipher_info_get_key_bitlen( cipher_info ) / 8;
#if defined(MBEDTLS_GCM_C) || \
defined(MBEDTLS_CCM_C) || \
defined(MBEDTLS_CHACHAPOLY_C)
- if( cipher_info->mode == MBEDTLS_MODE_GCM ||
- cipher_info->mode == MBEDTLS_MODE_CCM ||
- cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+ if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_GCM ||
+ mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CCM ||
+ mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
{
size_t explicit_ivlen;
@@ -814,7 +814,7 @@
* sequence number).
*/
transform->ivlen = 12;
- if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+ if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
transform->fixed_ivlen = 12;
else
transform->fixed_ivlen = 4;
@@ -826,8 +826,8 @@
else
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
- if( cipher_info->mode == MBEDTLS_MODE_STREAM ||
- cipher_info->mode == MBEDTLS_MODE_CBC )
+ if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM ||
+ mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
{
/* Initialize HMAC contexts */
if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
@@ -845,7 +845,7 @@
transform->ivlen = cipher_info->iv_size;
/* Minimum length */
- if( cipher_info->mode == MBEDTLS_MODE_STREAM )
+ if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM )
transform->minlen = transform->maclen;
else
{
@@ -1060,7 +1060,7 @@
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
- cipher_info->key_bitlen,
+ (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
MBEDTLS_ENCRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
@@ -1068,7 +1068,7 @@
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
- cipher_info->key_bitlen,
+ (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
MBEDTLS_DECRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
@@ -1076,7 +1076,7 @@
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
- if( cipher_info->mode == MBEDTLS_MODE_CBC )
+ if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
{
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
MBEDTLS_PADDING_NONE ) ) != 0 )
@@ -5170,6 +5170,10 @@
if( ret != 0 )
return( ret );
+ ret = mbedtls_ssl_handle_pending_alert( ssl );
+ if( ret != 0 )
+ goto cleanup;
+
#if defined(MBEDTLS_SSL_CLI_C)
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
{
@@ -5199,6 +5203,19 @@
}
#endif
+ if( ret != 0 )
+ {
+ /* handshake_step return error. And it is same
+ * with alert_reason.
+ */
+ if( ssl->send_alert )
+ {
+ ret = mbedtls_ssl_handle_pending_alert( ssl );
+ goto cleanup;
+ }
+ }
+
+cleanup:
return( ret );
}
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 41c7a4d..633bb8d 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -27,8 +27,11 @@
#include <string.h>
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+
#include "ssl_misc.h"
-#include <mbedtls/debug.h>
+#include "ecdh_misc.h"
#define CLIENT_HELLO_RANDOM_LEN 32
@@ -52,13 +55,11 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported versions extension" ) );
- /*
- * Check space for extension header.
- *
- * extension_type 2
- * extension_data_length 2
- * version_length 1
- * versions 2
+ /* Check if we have space to write the extension:
+ * - extension_type (2 bytes)
+ * - extension_data_length (2 bytes)
+ * - versions_length (1 byte )
+ * - versions (2 bytes)
*/
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 );
@@ -93,35 +94,366 @@
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/*
+ * Functions for writing supported_groups extension.
+ *
+ * Stucture of supported_groups:
+ * enum {
+ * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
+ * x25519(0x001D), x448(0x001E),
+ * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
+ * ffdhe6144(0x0103), ffdhe8192(0x0104),
+ * ffdhe_private_use(0x01FC..0x01FF),
+ * ecdhe_private_use(0xFE00..0xFEFF),
+ * (0xFFFF)
+ * } NamedGroup;
+ * struct {
+ * NamedGroup named_group_list<2..2^16-1>;
+ * } NamedGroupList;
+ */
+#if defined(MBEDTLS_ECDH_C)
+/*
+ * In versions of TLS prior to TLS 1.3, this extension was named
+ * 'elliptic_curves' and only contained elliptic curve groups.
+ */
+static int ssl_tls13_write_named_group_list_ecdhe( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+
+ *olen = 0;
+
+ if( ssl->conf->curve_list == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+ for ( const mbedtls_ecp_group_id *grp_id = ssl->conf->curve_list;
+ *grp_id != MBEDTLS_ECP_DP_NONE;
+ grp_id++ )
+ {
+ const mbedtls_ecp_curve_info *info;
+ info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
+ if( info == NULL )
+ continue;
+
+ if( !mbedtls_ssl_tls13_named_group_is_ecdhe( info->tls_id ) )
+ continue;
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2);
+ MBEDTLS_PUT_UINT16_BE( info->tls_id, p, 0 );
+ p += 2;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "NamedGroup: %s ( %x )",
+ mbedtls_ecp_curve_info_from_tls_id( info->tls_id )->name,
+ info->tls_id ) );
+ }
+
+ *olen = p - buf;
+
+ return( 0 );
+}
+#else
+static int ssl_tls13_write_named_group_list_ecdhe( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ unsigned char *end,
+ size_t *olen )
+{
+ ((void) ssl);
+ ((void) buf);
+ ((void) end);
+ *olen = 0;
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+#endif /* MBEDTLS_ECDH_C */
+
+static int ssl_tls13_write_named_group_list_dhe( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ unsigned char *end,
+ size_t *olen )
+{
+ ((void) ssl);
+ ((void) buf);
+ ((void) end);
+ *olen = 0;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "write_named_group_dhe is not implemented" ) );
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
static int ssl_tls13_write_supported_groups_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{
- ((void) ssl);
- ((void) buf);
- ((void) end);
- ((void) olen);
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ unsigned char *p = buf ;
+ unsigned char *named_group_list_ptr; /* Start of named_group_list */
+ size_t named_group_list_len; /* Length of named_group_list */
+ size_t output_len = 0;
+ int ret_ecdhe, ret_dhe;
+
+ *olen = 0;
+
+ if( !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_groups extension" ) );
+
+ /* Check if we have space for header and length fields:
+ * - extension_type (2 bytes)
+ * - extension_data_length (2 bytes)
+ * - named_group_list_length (2 bytes)
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
+ p += 6;
+
+ named_group_list_ptr = p;
+ ret_ecdhe = ssl_tls13_write_named_group_list_ecdhe( ssl, p, end, &output_len );
+ if( ret_ecdhe != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_named_group_list_ecdhe", ret_ecdhe );
+ }
+ p += output_len;
+
+ ret_dhe = ssl_tls13_write_named_group_list_dhe( ssl, p, end, &output_len );
+ if( ret_dhe != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_named_group_list_dhe", ret_dhe );
+ }
+ p += output_len;
+
+ /* Both ECDHE and DHE failed. */
+ if( ret_ecdhe != 0 && ret_dhe != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Both ECDHE and DHE groups are fail. " ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Length of named_group_list*/
+ named_group_list_len = p - named_group_list_ptr;
+ if( named_group_list_len == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "No group available." ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Write extension_type */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, buf, 0 );
+ /* Write extension_data_length */
+ MBEDTLS_PUT_UINT16_BE( named_group_list_len + 2, buf, 2 );
+ /* Write length of named_group_list */
+ MBEDTLS_PUT_UINT16_BE( named_group_list_len, buf, 4 );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Supported groups extension", buf + 4, named_group_list_len + 2 );
+
+ *olen = p - buf;
+
+ ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
+
+ return( 0 );
}
-static int ssl_tls13_write_key_shares_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- unsigned char *end,
- size_t *olen )
+/*
+ * Functions for writing key_share extension.
+ */
+#if defined(MBEDTLS_ECDH_C)
+static int ssl_tls13_generate_and_write_ecdh_key_exchange(
+ mbedtls_ssl_context *ssl,
+ uint16_t named_group,
+ unsigned char *buf,
+ unsigned char *end,
+ size_t *olen )
{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const mbedtls_ecp_curve_info *curve_info =
+ mbedtls_ecp_curve_info_from_tls_id( named_group );
+
+ if( curve_info == NULL )
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "offer curve %s", curve_info->name ) );
+
+ if( ( ret = mbedtls_ecdh_setup_no_everest( &ssl->handshake->ecdh_ctx,
+ curve_info->grp_id ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_setup_no_everest", ret );
+ return( ret );
+ }
+
+ ret = mbedtls_ecdh_tls13_make_params( &ssl->handshake->ecdh_ctx, olen,
+ buf, end - buf,
+ ssl->conf->f_rng, ssl->conf->p_rng );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_tls13_make_params", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+ MBEDTLS_DEBUG_ECDH_Q );
+ return( 0 );
+}
+#endif /* MBEDTLS_ECDH_C */
+
+static int ssl_tls13_get_default_group_id( mbedtls_ssl_context *ssl,
+ uint16_t *group_id )
+{
+ int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+
+#if defined(MBEDTLS_ECDH_C)
+ /* Pick first available ECDHE group compatible with TLS 1.3 */
+ if( ssl->conf->curve_list == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+ for ( const mbedtls_ecp_group_id *grp_id = ssl->conf->curve_list;
+ *grp_id != MBEDTLS_ECP_DP_NONE;
+ grp_id++ )
+ {
+ const mbedtls_ecp_curve_info *info;
+ info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
+ if( info != NULL &&
+ mbedtls_ssl_tls13_named_group_is_ecdhe( info->tls_id ) )
+ {
+ *group_id = info->tls_id;
+ return( 0 );
+ }
+ }
+#else
((void) ssl);
- ((void) buf);
- ((void) end);
- ((void) olen);
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ ((void) group_id);
+#endif /* MBEDTLS_ECDH_C */
+
+ /*
+ * Add DHE named groups here.
+ * Pick first available DHE group compatible with TLS 1.3
+ */
+
+ return( ret );
+}
+
+/*
+ * ssl_tls13_write_key_share_ext
+ *
+ * Structure of key_share extension in ClientHello:
+ *
+ * struct {
+ * NamedGroup group;
+ * opaque key_exchange<1..2^16-1>;
+ * } KeyShareEntry;
+ * struct {
+ * KeyShareEntry client_shares<0..2^16-1>;
+ * } KeyShareClientHello;
+ */
+static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ unsigned char *client_shares_ptr; /* Start of client_shares */
+ size_t client_shares_len; /* Length of client_shares */
+ uint16_t group_id;
+ int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+ *olen = 0;
+
+ if( !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+ return( 0 );
+
+ /* Check if we have space for header and length fields:
+ * - extension_type (2 bytes)
+ * - extension_data_length (2 bytes)
+ * - client_shares_length (2 bytes)
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
+ p += 6;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello: adding key share extension" ) );
+
+ /* HRR could already have requested something else. */
+ group_id = ssl->handshake->offered_group_id;
+ if( !mbedtls_ssl_tls13_named_group_is_ecdhe( group_id ) &&
+ !mbedtls_ssl_tls13_named_group_is_dhe( group_id ) )
+ {
+ MBEDTLS_SSL_PROC_CHK( ssl_tls13_get_default_group_id( ssl,
+ &group_id ) );
+ }
+
+ /*
+ * Dispatch to type-specific key generation function.
+ *
+ * So far, we're only supporting ECDHE. With the introduction
+ * of PQC KEMs, we'll want to have multiple branches, one per
+ * type of KEM, and dispatch to the corresponding crypto. And
+ * only one key share entry is allowed.
+ */
+ client_shares_ptr = p;
+#if defined(MBEDTLS_ECDH_C)
+ if( mbedtls_ssl_tls13_named_group_is_ecdhe( group_id ) )
+ {
+ /* Pointer to group */
+ unsigned char *group_ptr = p;
+ /* Length of key_exchange */
+ size_t key_exchange_len;
+
+ /* Check there is space for header of KeyShareEntry
+ * - group (2 bytes)
+ * - key_exchange_length (2 bytes)
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
+ p += 4;
+ ret = ssl_tls13_generate_and_write_ecdh_key_exchange( ssl, group_id,
+ p, end,
+ &key_exchange_len );
+ p += key_exchange_len;
+ if( ret != 0 )
+ return( ret );
+
+ /* Write group */
+ MBEDTLS_PUT_UINT16_BE( group_id, group_ptr, 0 );
+ /* Write key_exchange_length */
+ MBEDTLS_PUT_UINT16_BE( key_exchange_len, group_ptr, 2 );
+ }
+ else
+#endif /* MBEDTLS_ECDH_C */
+ if( 0 /* other KEMs? */ )
+ {
+ /* Do something */
+ }
+ else
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+ /* Length of client_shares */
+ client_shares_len = p - client_shares_ptr;
+ if( client_shares_len == 0)
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "No key share defined." ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ /* Write extension_type */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0 );
+ /* Write extension_data_length */
+ MBEDTLS_PUT_UINT16_BE( client_shares_len + 2, buf, 2 );
+ /* Write client_shares_length */
+ MBEDTLS_PUT_UINT16_BE( client_shares_len, buf, 4 );
+
+ /* Update offered_group_id field */
+ ssl->handshake->offered_group_id = group_id;
+
+ /* Output the total length of key_share extension. */
+ *olen = p - buf;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, key_share extension", buf, *olen );
+
+ ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
+
+cleanup:
+
+ return( ret );
}
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-/*
- * Functions for writing ClientHello message.
- */
/* Write cipher_suites
* CipherSuite cipher_suites<2..2^16-2>;
*/
@@ -311,7 +643,7 @@
* 3) Or, in case all ciphers are supported ( which includes #1 and #2
* from above )
*/
- ret = ssl_tls13_write_key_shares_ext( ssl, p, end, &output_len );
+ ret = ssl_tls13_write_key_share_ext( ssl, p, end, &output_len );
if( ret != 0 )
return( ret );
p += output_len;
@@ -340,7 +672,7 @@
return( 0 );
}
-static int ssl_tls13_finalize_client_hello( mbedtls_ssl_context* ssl )
+static int ssl_tls13_finalize_client_hello( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO );
return( 0 );
@@ -369,6 +701,7 @@
/*
* Write ClientHello handshake message.
+ * Handler for MBEDTLS_SSL_CLIENT_HELLO
*/
static int ssl_tls13_write_client_hello( mbedtls_ssl_context *ssl )
{
@@ -404,11 +737,121 @@
return ret;
}
+/*
+ * Handler for MBEDTLS_SSL_SERVER_HELLO
+ */
+static int ssl_tls1_3_process_server_hello( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
+ */
+static int ssl_tls1_3_process_encrypted_extensions( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CERTIFICATE_REQUEST
+ */
+static int ssl_tls1_3_process_certificate_request( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_CERTIFICATE );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE
+ */
+static int ssl_tls1_3_process_server_certificate( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY
+ */
+static int ssl_tls1_3_process_certificate_verify( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_SERVER_FINISHED
+ */
+static int ssl_tls1_3_process_server_finished( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE
+ */
+static int ssl_tls1_3_write_client_certificate( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY
+ */
+static int ssl_tls1_3_write_client_certificate_verify( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_FINISHED
+ */
+static int ssl_tls1_3_write_client_finished( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_FLUSH_BUFFERS );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_FLUSH_BUFFERS
+ */
+static int ssl_tls1_3_flush_buffers( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP );
+ return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP
+ */
+static int ssl_tls1_3_handshake_wrapup( mbedtls_ssl_context *ssl )
+{
+ ((void) ssl);
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
{
int ret = 0;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "tls1_3 client state: %d", ssl->state ) );
switch( ssl->state )
{
@@ -422,9 +865,47 @@
break;
case MBEDTLS_SSL_SERVER_HELLO:
- // Stop here : we haven't finished whole flow
- ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+ ret = ssl_tls1_3_process_server_hello( ssl );
+ break;
+
+ case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
+ ret = ssl_tls1_3_process_encrypted_extensions( ssl );
+ break;
+
+ case MBEDTLS_SSL_CERTIFICATE_REQUEST:
+ ret = ssl_tls1_3_process_certificate_request( ssl );
+ break;
+
+ case MBEDTLS_SSL_SERVER_CERTIFICATE:
+ ret = ssl_tls1_3_process_server_certificate( ssl );
+ break;
+
+ case MBEDTLS_SSL_CERTIFICATE_VERIFY:
+ ret = ssl_tls1_3_process_certificate_verify( ssl );
+ break;
+
+ case MBEDTLS_SSL_SERVER_FINISHED:
+ ret = ssl_tls1_3_process_server_finished( ssl );
+ break;
+
+ case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+ ret = ssl_tls1_3_write_client_certificate( ssl );
+ break;
+
+ case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
+ ret = ssl_tls1_3_write_client_certificate_verify( ssl );
+ break;
+
+ case MBEDTLS_SSL_CLIENT_FINISHED:
+ ret = ssl_tls1_3_write_client_finished( ssl );
+ break;
+
+ case MBEDTLS_SSL_FLUSH_BUFFERS:
+ ret = ssl_tls1_3_flush_buffers( ssl );
+ break;
+
+ case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
+ ret = ssl_tls1_3_handshake_wrapup( ssl );
break;
default:
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index ca4c167..5c20f29 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -24,6 +24,7 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
#include "mbedtls/error.h"
+#include "mbedtls/debug.h"
#include "ssl_misc.h"
@@ -99,17 +100,70 @@
*
* Only if we handle at least one key exchange that needs signatures.
*/
-
int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
unsigned char *end,
size_t *olen )
{
- ((void) ssl);
- ((void) buf);
- ((void) end);
- ((void) olen);
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ unsigned char *p = buf;
+ unsigned char *supported_sig_alg_ptr; /* Start of supported_signature_algorithms */
+ size_t supported_sig_alg_len = 0; /* Length of supported_signature_algorithms */
+
+ *olen = 0;
+
+ /* Skip the extension on the client if all allowed key exchanges
+ * are PSK-based. */
+#if defined(MBEDTLS_SSL_CLI_C)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+ {
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding signature_algorithms extension" ) );
+
+ /* Check if we have space for header and length field:
+ * - extension_type (2 bytes)
+ * - extension_data_length (2 bytes)
+ * - supported_signature_algorithms_length (2 bytes)
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
+ p += 6;
+
+ /*
+ * Write supported_signature_algorithms
+ */
+ supported_sig_alg_ptr = p;
+ for( const uint16_t *sig_alg = ssl->conf->tls13_sig_algs;
+ *sig_alg != MBEDTLS_TLS13_SIG_NONE; sig_alg++ )
+ {
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+ MBEDTLS_PUT_UINT16_BE( *sig_alg, p, 0 );
+ p += 2;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "signature scheme [%x]", *sig_alg ) );
+ }
+
+ /* Length of supported_signature_algorithms */
+ supported_sig_alg_len = p - supported_sig_alg_ptr;
+ if( supported_sig_alg_len == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "No signature algorithms defined." ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Write extension_type */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, buf, 0 );
+ /* Write extension_data_length */
+ MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len + 2, buf, 2 );
+ /* Write length of supported_signature_algorithms */
+ MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len, buf, 4 );
+
+ /* Output the total length of signature algorithms extension. */
+ *olen = p - buf;
+
+ ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
+ return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 0dcd7ed..86f44cb 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -23,11 +23,15 @@
#if defined(MBEDTLS_SSL_SRV_C)
+#include "mbedtls/debug.h"
+
#include "ssl_misc.h"
int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
{
((void) ssl);
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "tls1_3 server state: %d", ssl->state ) );
+
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index a8026a3..5ed2ece 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -124,7 +124,7 @@
while( *list )
{
cipher_info = mbedtls_cipher_info_from_type( *list );
- mbedtls_printf( " %s\n", cipher_info->MBEDTLS_PRIVATE(name) );
+ mbedtls_printf( " %s\n", mbedtls_cipher_info_get_name( cipher_info ) );
list++;
}
@@ -309,7 +309,9 @@
}
- if( mbedtls_cipher_setkey( &cipher_ctx, digest, cipher_info->MBEDTLS_PRIVATE(key_bitlen),
+ if( mbedtls_cipher_setkey( &cipher_ctx,
+ digest,
+ (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
MBEDTLS_ENCRYPT ) != 0 )
{
mbedtls_fprintf( stderr, "mbedtls_cipher_setkey() returned error\n");
@@ -408,7 +410,7 @@
/*
* Check the file size.
*/
- if( cipher_info->MBEDTLS_PRIVATE(mode) != MBEDTLS_MODE_GCM &&
+ if( mbedtls_cipher_info_get_mode( cipher_info ) != MBEDTLS_MODE_GCM &&
( ( filesize - mbedtls_md_get_size( md_info ) ) %
mbedtls_cipher_get_block_size( &cipher_ctx ) ) != 0 )
{
@@ -448,7 +450,9 @@
mbedtls_md_finish( &md_ctx, digest );
}
- if( mbedtls_cipher_setkey( &cipher_ctx, digest, cipher_info->MBEDTLS_PRIVATE(key_bitlen),
+ if( mbedtls_cipher_setkey( &cipher_ctx,
+ digest,
+ (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
MBEDTLS_DECRYPT ) != 0 )
{
mbedtls_fprintf( stderr, "mbedtls_cipher_setkey() returned error\n" );
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index 6b6e951..550a230 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -51,7 +51,7 @@
#define ECPARAMS MBEDTLS_ECP_DP_SECP192R1
#if !defined(ECPARAMS)
-#define ECPARAMS mbedtls_ecp_curve_list()->MBEDTLS_PRIVATE(grp_id)
+#define ECPARAMS mbedtls_ecp_curve_list()->grp_id
#endif
#if !defined(MBEDTLS_ECDSA_C) || !defined(MBEDTLS_SHA256_C) || \
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 4043dfa..7535eee 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -86,7 +86,7 @@
#endif
#if defined(MBEDTLS_ECP_C)
-#define DFL_EC_CURVE mbedtls_ecp_curve_list()->MBEDTLS_PRIVATE(grp_id)
+#define DFL_EC_CURVE mbedtls_ecp_curve_list()->grp_id
#else
#define DFL_EC_CURVE 0
#endif
@@ -219,9 +219,9 @@
#if defined(MBEDTLS_ECP_C)
mbedtls_printf( " available ec_curve values:\n" );
curve_info = mbedtls_ecp_curve_list();
- mbedtls_printf( " %s (default)\n", curve_info->MBEDTLS_PRIVATE(name) );
- while( ( ++curve_info )->MBEDTLS_PRIVATE(name) != NULL )
- mbedtls_printf( " %s\n", curve_info->MBEDTLS_PRIVATE(name) );
+ mbedtls_printf( " %s (default)\n", curve_info->name );
+ while( ( ++curve_info )->name != NULL )
+ mbedtls_printf( " %s\n", curve_info->name );
#endif /* MBEDTLS_ECP_C */
goto exit;
}
@@ -270,7 +270,7 @@
{
if( ( curve_info = mbedtls_ecp_curve_info_from_name( q ) ) == NULL )
goto usage;
- opt.ec_curve = curve_info->MBEDTLS_PRIVATE(grp_id);
+ opt.ec_curve = curve_info->grp_id;
}
#endif
else if( strcmp( p, "filename" ) == 0 )
@@ -391,7 +391,7 @@
{
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( key );
mbedtls_printf( "curve: %s\n",
- mbedtls_ecp_curve_info_from_grp_id( ecp->MBEDTLS_PRIVATE(grp).id )->MBEDTLS_PRIVATE(name) );
+ mbedtls_ecp_curve_info_from_grp_id( ecp->MBEDTLS_PRIVATE(grp).id )->name );
mbedtls_mpi_write_file( "X_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL );
mbedtls_mpi_write_file( "Y_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL );
mbedtls_mpi_write_file( "D: ", &ecp->MBEDTLS_PRIVATE(d) , 16, NULL );
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index f257049..5d1cccb 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -226,7 +226,7 @@
mbedtls_ssl_cache_set );
#endif
- mbedtls_ssl_conf_ca_chain( &conf, srvcert.MBEDTLS_PRIVATE(next), NULL );
+ mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
{
printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 1e0bef6..97bfe68 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -246,13 +246,13 @@
addr.sin_addr.s_addr = *((char *) &ret) == ret ? ADDR_LE : ADDR_BE;
ret = 0;
- if( ( server_fd.MBEDTLS_PRIVATE(fd) = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
+ if( ( server_fd.fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
ret = socket_failed;
goto exit;
}
- if( connect( server_fd.MBEDTLS_PRIVATE(fd),
+ if( connect( server_fd.fd,
(const struct sockaddr *) &addr, sizeof( addr ) ) < 0 )
{
ret = connect_failed;
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 542a334..694fc3b 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -190,7 +190,7 @@
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
- mbedtls_ssl_conf_ca_chain( &conf, srvcert.MBEDTLS_PRIVATE(next), NULL );
+ mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
{
mbedtls_printf( " failed! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index ace657c..95557fb 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -212,7 +212,7 @@
mbedtls_ssl_cache_set );
#endif
- mbedtls_ssl_conf_ca_chain( &conf, srvcert.MBEDTLS_PRIVATE(next), NULL );
+ mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index aab15db..3d8f37b 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -331,7 +331,7 @@
mbedtls_printf( "%s\n", buf );
- cur = cur->MBEDTLS_PRIVATE(next);
+ cur = cur->next;
}
/*
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 9a20d63..763f868 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -514,7 +514,7 @@
}
ret = mbedtls_x509_dn_gets( issuer_name, sizeof(issuer_name),
- &issuer_crt.MBEDTLS_PRIVATE(subject) );
+ &issuer_crt.subject );
if( ret < 0 )
{
mbedtls_strerror( ret, buf, 1024 );
@@ -548,7 +548,7 @@
}
ret = mbedtls_x509_dn_gets( subject_name, sizeof(subject_name),
- &csr.MBEDTLS_PRIVATE(subject) );
+ &csr.subject );
if( ret < 0 )
{
mbedtls_strerror( ret, buf, 1024 );
@@ -558,7 +558,7 @@
}
opt.subject_name = subject_name;
- subject_key = &csr.MBEDTLS_PRIVATE(pk);
+ subject_key = &csr.pk;
mbedtls_printf( " ok\n" );
}
@@ -602,7 +602,7 @@
//
if( strlen( opt.issuer_crt ) )
{
- if( mbedtls_pk_check_pair( &issuer_crt.MBEDTLS_PRIVATE(pk), issuer_key,
+ if( mbedtls_pk_check_pair( &issuer_crt.pk, issuer_key,
mbedtls_ctr_drbg_random, &ctr_drbg ) != 0 )
{
mbedtls_printf( " failed\n ! issuer_key does not match "
diff --git a/tests/compat.sh b/tests/compat.sh
index c2bef26..f4c611a 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -236,60 +236,46 @@
G_CIPHERS=""
}
+check_translation()
+{
+ if [ $1 -ne 0 ]; then
+ echo "translate_ciphers.py failed with exit code $1" >&2
+ echo "$2" >&2
+ exit 1
+ fi
+}
+
# Ciphersuites that can be used with all peers.
# Since we currently have three possible peers, each ciphersuite should appear
# three times: in each peer's list (with the name that this peer uses).
add_common_ciphersuites()
{
+ CIPHERS=""
case $TYPE in
"ECDSA")
if [ `minor_ver "$MODE"` -gt 0 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-ECDHE-ECDSA-WITH-NULL-SHA \
TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA \
TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA \
TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA \
"
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-ECDSA:+NULL:+SHA1 \
- +ECDHE-ECDSA:+3DES-CBC:+SHA1 \
- +ECDHE-ECDSA:+AES-128-CBC:+SHA1 \
- +ECDHE-ECDSA:+AES-256-CBC:+SHA1 \
- "
- O_CIPHERS="$O_CIPHERS \
- ECDHE-ECDSA-NULL-SHA \
- ECDHE-ECDSA-DES-CBC3-SHA \
- ECDHE-ECDSA-AES128-SHA \
- ECDHE-ECDSA-AES256-SHA \
- "
fi
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 \
TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 \
TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 \
"
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-ECDSA:+AES-128-CBC:+SHA256 \
- +ECDHE-ECDSA:+AES-256-CBC:+SHA384 \
- +ECDHE-ECDSA:+AES-128-GCM:+AEAD \
- +ECDHE-ECDSA:+AES-256-GCM:+AEAD \
- "
- O_CIPHERS="$O_CIPHERS \
- ECDHE-ECDSA-AES128-SHA256 \
- ECDHE-ECDSA-AES256-SHA384 \
- ECDHE-ECDSA-AES128-GCM-SHA256 \
- ECDHE-ECDSA-AES256-GCM-SHA384 \
- "
fi
;;
"RSA")
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
TLS-DHE-RSA-WITH-AES-256-CBC-SHA \
TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA \
@@ -303,58 +289,18 @@
TLS-RSA-WITH-NULL-MD5 \
TLS-RSA-WITH-NULL-SHA \
"
- G_CIPHERS="$G_CIPHERS \
- +DHE-RSA:+AES-128-CBC:+SHA1 \
- +DHE-RSA:+AES-256-CBC:+SHA1 \
- +DHE-RSA:+CAMELLIA-128-CBC:+SHA1 \
- +DHE-RSA:+CAMELLIA-256-CBC:+SHA1 \
- +DHE-RSA:+3DES-CBC:+SHA1 \
- +RSA:+AES-256-CBC:+SHA1 \
- +RSA:+CAMELLIA-256-CBC:+SHA1 \
- +RSA:+AES-128-CBC:+SHA1 \
- +RSA:+CAMELLIA-128-CBC:+SHA1 \
- +RSA:+3DES-CBC:+SHA1 \
- +RSA:+NULL:+MD5 \
- +RSA:+NULL:+SHA1 \
- "
- O_CIPHERS="$O_CIPHERS \
- DHE-RSA-AES128-SHA \
- DHE-RSA-AES256-SHA \
- DHE-RSA-CAMELLIA128-SHA \
- DHE-RSA-CAMELLIA256-SHA \
- EDH-RSA-DES-CBC3-SHA \
- AES256-SHA \
- CAMELLIA256-SHA \
- AES128-SHA \
- CAMELLIA128-SHA \
- DES-CBC3-SHA \
- NULL-MD5 \
- NULL-SHA \
- "
if [ `minor_ver "$MODE"` -gt 0 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA \
TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA \
TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA \
TLS-ECDHE-RSA-WITH-NULL-SHA \
"
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-RSA:+AES-128-CBC:+SHA1 \
- +ECDHE-RSA:+AES-256-CBC:+SHA1 \
- +ECDHE-RSA:+3DES-CBC:+SHA1 \
- +ECDHE-RSA:+NULL:+SHA1 \
- "
- O_CIPHERS="$O_CIPHERS \
- ECDHE-RSA-AES256-SHA \
- ECDHE-RSA-AES128-SHA \
- ECDHE-RSA-DES-CBC3-SHA \
- ECDHE-RSA-NULL-SHA \
- "
fi
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-RSA-WITH-AES-128-CBC-SHA256 \
TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 \
TLS-RSA-WITH-AES-256-CBC-SHA256 \
@@ -367,62 +313,36 @@
TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 \
TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 \
TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 \
- "
- G_CIPHERS="$G_CIPHERS \
- +RSA:+AES-128-CBC:+SHA256 \
- +DHE-RSA:+AES-128-CBC:+SHA256 \
- +RSA:+AES-256-CBC:+SHA256 \
- +DHE-RSA:+AES-256-CBC:+SHA256 \
- +ECDHE-RSA:+AES-128-CBC:+SHA256 \
- +ECDHE-RSA:+AES-256-CBC:+SHA384 \
- +RSA:+AES-128-GCM:+AEAD \
- +RSA:+AES-256-GCM:+AEAD \
- +DHE-RSA:+AES-128-GCM:+AEAD \
- +DHE-RSA:+AES-256-GCM:+AEAD \
- +ECDHE-RSA:+AES-128-GCM:+AEAD \
- +ECDHE-RSA:+AES-256-GCM:+AEAD \
- "
- O_CIPHERS="$O_CIPHERS \
- NULL-SHA256 \
- AES128-SHA256 \
- DHE-RSA-AES128-SHA256 \
- AES256-SHA256 \
- DHE-RSA-AES256-SHA256 \
- ECDHE-RSA-AES128-SHA256 \
- ECDHE-RSA-AES256-SHA384 \
- AES128-GCM-SHA256 \
- DHE-RSA-AES128-GCM-SHA256 \
- AES256-GCM-SHA384 \
- DHE-RSA-AES256-GCM-SHA384 \
- ECDHE-RSA-AES128-GCM-SHA256 \
- ECDHE-RSA-AES256-GCM-SHA384 \
+ TLS-RSA-WITH-NULL-SHA256 \
"
fi
;;
"PSK")
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-PSK-WITH-3DES-EDE-CBC-SHA \
TLS-PSK-WITH-AES-128-CBC-SHA \
TLS-PSK-WITH-AES-256-CBC-SHA \
"
- G_CIPHERS="$G_CIPHERS \
- +PSK:+3DES-CBC:+SHA1 \
- +PSK:+AES-128-CBC:+SHA1 \
- +PSK:+AES-256-CBC:+SHA1 \
- "
- O_CIPHERS="$O_CIPHERS \
- PSK-3DES-EDE-CBC-SHA \
- PSK-AES128-CBC-SHA \
- PSK-AES256-CBC-SHA \
- "
;;
esac
+
+ M_CIPHERS="$M_CIPHERS $CIPHERS"
+
+ T=$(./scripts/translate_ciphers.py g $CIPHERS)
+ check_translation $? "$T"
+ G_CIPHERS="$G_CIPHERS $T"
+
+ T=$(./scripts/translate_ciphers.py o $CIPHERS)
+ check_translation $? "$T"
+ O_CIPHERS="$O_CIPHERS $T"
}
# Ciphersuites usable only with Mbed TLS and OpenSSL
-# Each ciphersuite should appear two times, once with its OpenSSL name, once
-# with its Mbed TLS name.
+# A list of ciphersuites in the Mbed TLS convention is compiled and
+# appended to the list of Mbed TLS ciphersuites $M_CIPHERS. The same list
+# is translated to the OpenSSL naming convention and appended to the list of
+# OpenSSL ciphersuites $O_CIPHERS.
#
# NOTE: for some reason RSA-PSK doesn't work with OpenSSL,
# so RSA-PSK ciphersuites need to go in other sections, see
@@ -432,28 +352,23 @@
# GnuTLS in 3.5.0 and the CI only has 3.4.x so far.
add_openssl_ciphersuites()
{
+ CIPHERS=""
case $TYPE in
"ECDSA")
if [ `minor_ver "$MODE"` -gt 0 ]
then
- M_CIPHERS="$M_CIPHERS \
- TLS-ECDH-ECDSA-WITH-NULL-SHA \
+ CIPHERS="$CIPHERS \
+ TLS-ECDH-ECDSA-WITH-NULL-SHA \
TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA \
TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA \
TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA \
"
- O_CIPHERS="$O_CIPHERS \
- ECDH-ECDSA-NULL-SHA \
- ECDH-ECDSA-DES-CBC3-SHA \
- ECDH-ECDSA-AES128-SHA \
- ECDH-ECDSA-AES256-SHA \
- "
fi
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
- TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256 \
+ CIPHERS="$CIPHERS \
+ TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256 \
TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384 \
TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256 \
TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384 \
@@ -461,31 +376,18 @@
TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256 \
TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256 \
"
- O_CIPHERS="$O_CIPHERS \
- ECDH-ECDSA-AES128-SHA256 \
- ECDH-ECDSA-AES256-SHA384 \
- ECDH-ECDSA-AES128-GCM-SHA256 \
- ECDH-ECDSA-AES256-GCM-SHA384 \
- ECDHE-ECDSA-ARIA256-GCM-SHA384 \
- ECDHE-ECDSA-ARIA128-GCM-SHA256 \
- ECDHE-ECDSA-CHACHA20-POLY1305 \
- "
fi
;;
"RSA")
- M_CIPHERS="$M_CIPHERS \
- TLS-RSA-WITH-DES-CBC-SHA \
+ CIPHERS="$CIPHERS \
+ TLS-RSA-WITH-DES-CBC-SHA \
TLS-DHE-RSA-WITH-DES-CBC-SHA \
"
- O_CIPHERS="$O_CIPHERS \
- DES-CBC-SHA \
- EDH-RSA-DES-CBC-SHA \
- "
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
- TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384 \
+ CIPHERS="$CIPHERS \
+ TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384 \
TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384 \
TLS-RSA-WITH-ARIA-256-GCM-SHA384 \
TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256 \
@@ -494,24 +396,14 @@
TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256 \
TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256 \
"
- O_CIPHERS="$O_CIPHERS \
- ECDHE-ARIA256-GCM-SHA384 \
- DHE-RSA-ARIA256-GCM-SHA384 \
- ARIA256-GCM-SHA384 \
- ECDHE-ARIA128-GCM-SHA256 \
- DHE-RSA-ARIA128-GCM-SHA256 \
- ARIA128-GCM-SHA256 \
- DHE-RSA-CHACHA20-POLY1305 \
- ECDHE-RSA-CHACHA20-POLY1305 \
- "
fi
;;
"PSK")
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
- TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384 \
+ CIPHERS="$CIPHERS \
+ TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384 \
TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256 \
TLS-PSK-WITH-ARIA-256-GCM-SHA384 \
TLS-PSK-WITH-ARIA-128-GCM-SHA256 \
@@ -519,66 +411,47 @@
TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256 \
TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256 \
"
- O_CIPHERS="$O_CIPHERS \
- DHE-PSK-ARIA256-GCM-SHA384 \
- DHE-PSK-ARIA128-GCM-SHA256 \
- PSK-ARIA256-GCM-SHA384 \
- PSK-ARIA128-GCM-SHA256 \
- DHE-PSK-CHACHA20-POLY1305 \
- ECDHE-PSK-CHACHA20-POLY1305 \
- PSK-CHACHA20-POLY1305 \
- "
fi
;;
esac
+
+ M_CIPHERS="$M_CIPHERS $CIPHERS"
+
+ T=$(./scripts/translate_ciphers.py o $CIPHERS)
+ check_translation $? "$T"
+ O_CIPHERS="$O_CIPHERS $T"
}
# Ciphersuites usable only with Mbed TLS and GnuTLS
-# Each ciphersuite should appear two times, once with its GnuTLS name, once
-# with its Mbed TLS name.
+# A list of ciphersuites in the Mbed TLS convention is compiled and
+# appended to the list of Mbed TLS ciphersuites $M_CIPHERS. The same list
+# is translated to the GnuTLS naming convention and appended to the list of
+# GnuTLS ciphersuites $G_CIPHERS.
add_gnutls_ciphersuites()
{
+ CIPHERS=""
case $TYPE in
"ECDSA")
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-ECDHE-ECDSA-WITH-AES-128-CCM \
- TLS-ECDHE-ECDSA-WITH-AES-256-CCM \
- TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8 \
- TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8 \
- "
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-ECDSA:+CAMELLIA-128-CBC:+SHA256 \
- +ECDHE-ECDSA:+CAMELLIA-256-CBC:+SHA384 \
- +ECDHE-ECDSA:+CAMELLIA-128-GCM:+AEAD \
- +ECDHE-ECDSA:+CAMELLIA-256-GCM:+AEAD \
- +ECDHE-ECDSA:+AES-128-CCM:+AEAD \
- +ECDHE-ECDSA:+AES-256-CCM:+AEAD \
- +ECDHE-ECDSA:+AES-128-CCM-8:+AEAD \
- +ECDHE-ECDSA:+AES-256-CCM-8:+AEAD \
+ CIPHERS="$CIPHERS \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-ECDHE-ECDSA-WITH-AES-128-CCM \
+ TLS-ECDHE-ECDSA-WITH-AES-256-CCM \
+ TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8 \
+ TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8 \
"
fi
;;
"RSA")
- if [ `minor_ver "$MODE"` -gt 0 ]
- then
- M_CIPHERS="$M_CIPHERS \
- TLS-RSA-WITH-NULL-SHA256 \
- "
- G_CIPHERS="$G_CIPHERS \
- +RSA:+NULL:+SHA256 \
- "
- fi
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384 \
TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
@@ -600,45 +473,18 @@
TLS-DHE-RSA-WITH-AES-128-CCM-8 \
TLS-DHE-RSA-WITH-AES-256-CCM-8 \
"
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-RSA:+CAMELLIA-128-CBC:+SHA256 \
- +ECDHE-RSA:+CAMELLIA-256-CBC:+SHA384 \
- +RSA:+CAMELLIA-128-CBC:+SHA256 \
- +RSA:+CAMELLIA-256-CBC:+SHA256 \
- +DHE-RSA:+CAMELLIA-128-CBC:+SHA256 \
- +DHE-RSA:+CAMELLIA-256-CBC:+SHA256 \
- +ECDHE-RSA:+CAMELLIA-128-GCM:+AEAD \
- +ECDHE-RSA:+CAMELLIA-256-GCM:+AEAD \
- +DHE-RSA:+CAMELLIA-128-GCM:+AEAD \
- +DHE-RSA:+CAMELLIA-256-GCM:+AEAD \
- +RSA:+CAMELLIA-128-GCM:+AEAD \
- +RSA:+CAMELLIA-256-GCM:+AEAD \
- +RSA:+AES-128-CCM:+AEAD \
- +RSA:+AES-256-CCM:+AEAD \
- +RSA:+AES-128-CCM-8:+AEAD \
- +RSA:+AES-256-CCM-8:+AEAD \
- +DHE-RSA:+AES-128-CCM:+AEAD \
- +DHE-RSA:+AES-256-CCM:+AEAD \
- +DHE-RSA:+AES-128-CCM-8:+AEAD \
- +DHE-RSA:+AES-256-CCM-8:+AEAD \
- "
fi
;;
"PSK")
- M_CIPHERS="$M_CIPHERS \
- TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA \
- TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
- TLS-DHE-PSK-WITH-AES-256-CBC-SHA \
- "
- G_CIPHERS="$G_CIPHERS \
- +DHE-PSK:+3DES-CBC:+SHA1 \
- +DHE-PSK:+AES-128-CBC:+SHA1 \
- +DHE-PSK:+AES-256-CBC:+SHA1 \
+ CIPHERS="$CIPHERS \
+ TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA \
+ TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
+ TLS-DHE-PSK-WITH-AES-256-CBC-SHA \
"
if [ `minor_ver "$MODE"` -gt 0 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA \
TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \
TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA \
@@ -646,18 +492,10 @@
TLS-RSA-PSK-WITH-AES-256-CBC-SHA \
TLS-RSA-PSK-WITH-AES-128-CBC-SHA \
"
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-PSK:+3DES-CBC:+SHA1 \
- +ECDHE-PSK:+AES-128-CBC:+SHA1 \
- +ECDHE-PSK:+AES-256-CBC:+SHA1 \
- +RSA-PSK:+3DES-CBC:+SHA1 \
- +RSA-PSK:+AES-256-CBC:+SHA1 \
- +RSA-PSK:+AES-128-CBC:+SHA1 \
- "
fi
if [ `minor_ver "$MODE"` -ge 3 ]
then
- M_CIPHERS="$M_CIPHERS \
+ CIPHERS="$CIPHERS \
TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \
@@ -703,55 +541,15 @@
TLS-RSA-PSK-WITH-AES-256-GCM-SHA384 \
TLS-RSA-PSK-WITH-AES-128-GCM-SHA256 \
"
- G_CIPHERS="$G_CIPHERS \
- +ECDHE-PSK:+AES-256-CBC:+SHA384 \
- +ECDHE-PSK:+CAMELLIA-256-CBC:+SHA384 \
- +ECDHE-PSK:+AES-128-CBC:+SHA256 \
- +ECDHE-PSK:+CAMELLIA-128-CBC:+SHA256 \
- +PSK:+AES-128-CBC:+SHA256 \
- +PSK:+AES-256-CBC:+SHA384 \
- +DHE-PSK:+AES-128-CBC:+SHA256 \
- +DHE-PSK:+AES-256-CBC:+SHA384 \
- +RSA-PSK:+AES-256-CBC:+SHA384 \
- +RSA-PSK:+AES-128-CBC:+SHA256 \
- +DHE-PSK:+CAMELLIA-128-CBC:+SHA256 \
- +DHE-PSK:+CAMELLIA-256-CBC:+SHA384 \
- +PSK:+CAMELLIA-128-CBC:+SHA256 \
- +PSK:+CAMELLIA-256-CBC:+SHA384 \
- +RSA-PSK:+CAMELLIA-256-CBC:+SHA384 \
- +RSA-PSK:+CAMELLIA-128-CBC:+SHA256 \
- +PSK:+AES-128-GCM:+AEAD \
- +PSK:+AES-256-GCM:+AEAD \
- +DHE-PSK:+AES-128-GCM:+AEAD \
- +DHE-PSK:+AES-256-GCM:+AEAD \
- +PSK:+AES-128-CCM:+AEAD \
- +PSK:+AES-256-CCM:+AEAD \
- +DHE-PSK:+AES-128-CCM:+AEAD \
- +DHE-PSK:+AES-256-CCM:+AEAD \
- +PSK:+AES-128-CCM-8:+AEAD \
- +PSK:+AES-256-CCM-8:+AEAD \
- +DHE-PSK:+AES-128-CCM-8:+AEAD \
- +DHE-PSK:+AES-256-CCM-8:+AEAD \
- +RSA-PSK:+CAMELLIA-128-GCM:+AEAD \
- +RSA-PSK:+CAMELLIA-256-GCM:+AEAD \
- +PSK:+CAMELLIA-128-GCM:+AEAD \
- +PSK:+CAMELLIA-256-GCM:+AEAD \
- +DHE-PSK:+CAMELLIA-128-GCM:+AEAD \
- +DHE-PSK:+CAMELLIA-256-GCM:+AEAD \
- +RSA-PSK:+AES-256-GCM:+AEAD \
- +RSA-PSK:+AES-128-GCM:+AEAD \
- +ECDHE-PSK:+NULL:+SHA384 \
- +ECDHE-PSK:+NULL:+SHA256 \
- +PSK:+NULL:+SHA256 \
- +PSK:+NULL:+SHA384 \
- +DHE-PSK:+NULL:+SHA256 \
- +DHE-PSK:+NULL:+SHA384 \
- +RSA-PSK:+NULL:+SHA256 \
- +RSA-PSK:+NULL:+SHA384 \
- "
fi
;;
esac
+
+ M_CIPHERS="$M_CIPHERS $CIPHERS"
+
+ T=$(./scripts/translate_ciphers.py g $CIPHERS)
+ check_translation $? "$T"
+ G_CIPHERS="$G_CIPHERS $T"
}
# Ciphersuites usable only with Mbed TLS (not currently supported by another
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 9944a85..f30795c 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -841,7 +841,7 @@
component_check_names () {
msg "Check: declared and exported names (builds the library)" # < 3s
- tests/scripts/check-names.sh -v
+ tests/scripts/check_names.py -v
}
component_check_test_cases () {
@@ -2565,6 +2565,8 @@
make
msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, without padding"
make test
+ msg "ssl-opt.sh (TLS 1.3 experimental)"
+ if_build_succeeded tests/ssl-opt.sh
}
component_test_tls13_experimental_with_padding () {
@@ -2579,6 +2581,31 @@
if_build_succeeded tests/ssl-opt.sh
}
+component_test_tls13_experimental_with_ecp_restartable () {
+ msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with ecp_restartable"
+ scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+ scripts/config.py set MBEDTLS_ECP_RESTARTABLE
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+ msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with ecp_restartable"
+ make test
+ msg "ssl-opt.sh (TLS 1.3 experimental)"
+ if_build_succeeded tests/ssl-opt.sh
+}
+
+component_test_tls13_experimental_with_everest () {
+ msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with Everest"
+ scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+ scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
+ scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+ msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with Everest"
+ make test
+ msg "ssl-opt.sh (TLS 1.3 experimental)"
+ if_build_succeeded tests/ssl-opt.sh
+}
+
component_build_mingw () {
msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs
@@ -2743,12 +2770,15 @@
tests/scripts/check-python-files.sh
}
-component_check_generate_test_code () {
- msg "uint test: generate_test_code.py"
+component_check_test_helpers () {
+ msg "unit test: generate_test_code.py"
# unittest writes out mundane stuff like number or tests run on stderr.
# Our convention is to reserve stderr for actual errors, and write
# harmless info on stdout so it can be suppress with --quiet.
./tests/scripts/test_generate_test_code.py 2>&1
+
+ msg "unit test: translate_ciphers.py"
+ python3 -m unittest tests/scripts/translate_ciphers.py 2>&1
}
################################################################
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
deleted file mode 100755
index 2a06adc..0000000
--- a/tests/scripts/check-names.sh
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ $# -ne 0 ] && [ "$1" = "--help" ]; then
- cat <<EOF
-$0 [-v]
-This script confirms that the naming of all symbols and identifiers in mbed
-TLS are consistent with the house style and are also self-consistent.
-
- -v If the script fails unexpectedly, print a command trace.
-EOF
- exit
-fi
-
-trace=
-if [ $# -ne 0 ] && [ "$1" = "-v" ]; then
- shift
- trace='-x'
- exec 2>check-names.err
- trap 'echo "FAILED UNEXPECTEDLY, status=$?";
- cat check-names.err' EXIT
- set -x
-fi
-
-printf "Analysing source code...\n"
-
-sh $trace tests/scripts/list-macros.sh
-tests/scripts/list-enum-consts.pl
-sh $trace tests/scripts/list-identifiers.sh
-sh $trace tests/scripts/list-symbols.sh
-
-FAIL=0
-
-printf "\nExported symbols declared in header: "
-UNDECLARED=$( diff exported-symbols identifiers | sed -n -e 's/^< //p' )
-if [ "x$UNDECLARED" = "x" ]; then
- echo "PASS"
-else
- echo "FAIL"
- echo "$UNDECLARED"
- FAIL=1
-fi
-
-diff macros identifiers | sed -n -e 's/< //p' > actual-macros
-
-for THING in actual-macros enum-consts; do
- printf 'Names of %s: ' "$THING"
- test -r $THING
- BAD=$( grep -E -v '^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
- UNDERSCORES=$( grep -E '.*__.*' $THING || true )
-
- if [ "x$BAD" = "x" ] && [ "x$UNDERSCORES" = "x" ]; then
- echo "PASS"
- else
- echo "FAIL"
- echo "$BAD"
- echo "$UNDERSCORES"
- FAIL=1
- fi
-done
-
-for THING in identifiers; do
- printf 'Names of %s: ' "$THING"
- test -r $THING
- BAD=$( grep -E -v '^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$' $THING || true )
- if [ "x$BAD" = "x" ]; then
- echo "PASS"
- else
- echo "FAIL"
- echo "$BAD"
- FAIL=1
- fi
-done
-
-printf "Likely typos: "
-sort -u actual-macros enum-consts > _caps
-HEADERS=$( ls include/mbedtls/*.h include/psa/*.h | egrep -v 'compat-2\.x\.h' )
-HEADERS="$HEADERS library/*.h"
-HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
-LIBRARY="$( ls library/*.c )"
-LIBRARY="$LIBRARY 3rdparty/everest/library/everest.c 3rdparty/everest/library/x25519.c"
-NL='
-'
-cat $HEADERS $LIBRARY \
- | grep -v -e '//no-check-names' -e '#error' \
- | sed -n 's/MBED..._[A-Z0-9_]*/\'"$NL"'&\'"$NL"/gp \
- | grep MBEDTLS | sort -u > _MBEDTLS_XXX
-TYPOS=$( diff _caps _MBEDTLS_XXX | sed -n 's/^> //p' \
- | egrep -v 'XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$' || true )
-rm _MBEDTLS_XXX _caps
-if [ "x$TYPOS" = "x" ]; then
- echo "PASS"
-else
- echo "FAIL"
- echo "$TYPOS"
- FAIL=1
-fi
-
-if [ -n "$trace" ]; then
- set +x
- trap - EXIT
- rm check-names.err
-fi
-
-printf "\nOverall: "
-if [ "$FAIL" -eq 0 ]; then
- rm macros actual-macros enum-consts identifiers exported-symbols
- echo "PASSED"
- exit 0
-else
- echo "FAILED"
- exit 1
-fi
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
new file mode 100755
index 0000000..a9aa118
--- /dev/null
+++ b/tests/scripts/check_names.py
@@ -0,0 +1,865 @@
+#!/usr/bin/env python3
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This script confirms that the naming of all symbols and identifiers in Mbed TLS
+are consistent with the house style and are also self-consistent. It only runs
+on Linux and macOS since it depends on nm.
+
+It contains two major Python classes, CodeParser and NameChecker. They both have
+a comprehensive "run-all" function (comprehensive_parse() and perform_checks())
+but the individual functions can also be used for specific needs.
+
+CodeParser makes heavy use of regular expressions to parse the code, and is
+dependent on the current code formatting. Many Python C parser libraries require
+preprocessed C code, which means no macro parsing. Compiler tools are also not
+very helpful when we want the exact location in the original source (which
+becomes impossible when e.g. comments are stripped).
+
+NameChecker performs the following checks:
+
+- All exported and available symbols in the library object files, are explicitly
+ declared in the header files. This uses the nm command.
+- All macros, constants, and identifiers (function names, struct names, etc)
+ follow the required regex pattern.
+- Typo checking: All words that begin with MBED exist as macros or constants.
+
+The script returns 0 on success, 1 on test failure, and 2 if there is a script
+error. It must be run from Mbed TLS root.
+"""
+
+import abc
+import argparse
+import glob
+import textwrap
+import os
+import sys
+import traceback
+import re
+import enum
+import shutil
+import subprocess
+import logging
+
+# Naming patterns to check against. These are defined outside the NameCheck
+# class for ease of modification.
+MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
+CONSTANTS_PATTERN = MACRO_PATTERN
+IDENTIFIER_PATTERN = r"^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$"
+
+class Match(): # pylint: disable=too-few-public-methods
+ """
+ A class representing a match, together with its found position.
+
+ Fields:
+ * filename: the file that the match was in.
+ * line: the full line containing the match.
+ * line_no: the line number.
+ * pos: a tuple of (start, end) positions on the line where the match is.
+ * name: the match itself.
+ """
+ def __init__(self, filename, line, line_no, pos, name):
+ # pylint: disable=too-many-arguments
+ self.filename = filename
+ self.line = line
+ self.line_no = line_no
+ self.pos = pos
+ self.name = name
+
+ def __str__(self):
+ """
+ Return a formatted code listing representation of the erroneous line.
+ """
+ gutter = format(self.line_no, "4d")
+ underline = self.pos[0] * " " + (self.pos[1] - self.pos[0]) * "^"
+
+ return (
+ " {0} |\n".format(" " * len(gutter)) +
+ " {0} | {1}".format(gutter, self.line) +
+ " {0} | {1}\n".format(" " * len(gutter), underline)
+ )
+
+class Problem(abc.ABC): # pylint: disable=too-few-public-methods
+ """
+ An abstract parent class representing a form of static analysis error.
+ It extends an Abstract Base Class, which means it is not instantiable, and
+ it also mandates certain abstract methods to be implemented in subclasses.
+ """
+ # Class variable to control the quietness of all problems
+ quiet = False
+ def __init__(self):
+ self.textwrapper = textwrap.TextWrapper()
+ self.textwrapper.width = 80
+ self.textwrapper.initial_indent = " > "
+ self.textwrapper.subsequent_indent = " "
+
+ def __str__(self):
+ """
+ Unified string representation method for all Problems.
+ """
+ if self.__class__.quiet:
+ return self.quiet_output()
+ return self.verbose_output()
+
+ @abc.abstractmethod
+ def quiet_output(self):
+ """
+ The output when --quiet is enabled.
+ """
+ pass
+
+ @abc.abstractmethod
+ def verbose_output(self):
+ """
+ The default output with explanation and code snippet if appropriate.
+ """
+ pass
+
+class SymbolNotInHeader(Problem): # pylint: disable=too-few-public-methods
+ """
+ A problem that occurs when an exported/available symbol in the object file
+ is not explicitly declared in header files. Created with
+ NameCheck.check_symbols_declared_in_header()
+
+ Fields:
+ * symbol_name: the name of the symbol.
+ """
+ def __init__(self, symbol_name):
+ self.symbol_name = symbol_name
+ Problem.__init__(self)
+
+ def quiet_output(self):
+ return "{0}".format(self.symbol_name)
+
+ def verbose_output(self):
+ return self.textwrapper.fill(
+ "'{0}' was found as an available symbol in the output of nm, "
+ "however it was not declared in any header files."
+ .format(self.symbol_name))
+
+class PatternMismatch(Problem): # pylint: disable=too-few-public-methods
+ """
+ A problem that occurs when something doesn't match the expected pattern.
+ Created with NameCheck.check_match_pattern()
+
+ Fields:
+ * pattern: the expected regex pattern
+ * match: the Match object in question
+ """
+ def __init__(self, pattern, match):
+ self.pattern = pattern
+ self.match = match
+ Problem.__init__(self)
+
+
+ def quiet_output(self):
+ return (
+ "{0}:{1}:{2}"
+ .format(self.match.filename, self.match.line_no, self.match.name)
+ )
+
+ def verbose_output(self):
+ return self.textwrapper.fill(
+ "{0}:{1}: '{2}' does not match the required pattern '{3}'."
+ .format(
+ self.match.filename,
+ self.match.line_no,
+ self.match.name,
+ self.pattern
+ )
+ ) + "\n" + str(self.match)
+
+class Typo(Problem): # pylint: disable=too-few-public-methods
+ """
+ A problem that occurs when a word using MBED doesn't appear to be defined as
+ constants nor enum values. Created with NameCheck.check_for_typos()
+
+ Fields:
+ * match: the Match object of the MBED name in question.
+ """
+ def __init__(self, match):
+ self.match = match
+ Problem.__init__(self)
+
+ def quiet_output(self):
+ return (
+ "{0}:{1}:{2}"
+ .format(self.match.filename, self.match.line_no, self.match.name)
+ )
+
+ def verbose_output(self):
+ return self.textwrapper.fill(
+ "{0}:{1}: '{2}' looks like a typo. It was not found in any "
+ "macros or any enums. If this is not a typo, put "
+ "//no-check-names after it."
+ .format(self.match.filename, self.match.line_no, self.match.name)
+ ) + "\n" + str(self.match)
+
+class CodeParser():
+ """
+ Class for retrieving files and parsing the code. This can be used
+ independently of the checks that NameChecker performs, for example for
+ list_internal_identifiers.py.
+ """
+ def __init__(self, log):
+ self.log = log
+ self.check_repo_path()
+
+ # Memo for storing "glob expression": set(filepaths)
+ self.files = {}
+
+ # Globally excluded filenames
+ self.excluded_files = ["**/bn_mul", "**/compat-2.x.h"]
+
+ @staticmethod
+ def check_repo_path():
+ """
+ Check that the current working directory is the project root, and throw
+ an exception if not.
+ """
+ if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
+ raise Exception("This script must be run from Mbed TLS root")
+
+ def comprehensive_parse(self):
+ """
+ Comprehensive ("default") function to call each parsing function and
+ retrieve various elements of the code, together with the source location.
+
+ Returns a dict of parsed item key to the corresponding List of Matches.
+ """
+ self.log.info("Parsing source code...")
+ self.log.debug(
+ "The following files are excluded from the search: {}"
+ .format(str(self.excluded_files))
+ )
+
+ all_macros = self.parse_macros([
+ "include/mbedtls/*.h",
+ "include/psa/*.h",
+ "library/*.h",
+ "tests/include/test/drivers/*.h",
+ "3rdparty/everest/include/everest/everest.h",
+ "3rdparty/everest/include/everest/x25519.h"
+ ])
+ enum_consts = self.parse_enum_consts([
+ "include/mbedtls/*.h",
+ "library/*.h",
+ "3rdparty/everest/include/everest/everest.h",
+ "3rdparty/everest/include/everest/x25519.h"
+ ])
+ identifiers = self.parse_identifiers([
+ "include/mbedtls/*.h",
+ "include/psa/*.h",
+ "library/*.h",
+ "3rdparty/everest/include/everest/everest.h",
+ "3rdparty/everest/include/everest/x25519.h"
+ ])
+ mbed_words = self.parse_mbed_words([
+ "include/mbedtls/*.h",
+ "include/psa/*.h",
+ "library/*.h",
+ "3rdparty/everest/include/everest/everest.h",
+ "3rdparty/everest/include/everest/x25519.h",
+ "library/*.c",
+ "3rdparty/everest/library/everest.c",
+ "3rdparty/everest/library/x25519.c"
+ ])
+ symbols = self.parse_symbols()
+
+ # Remove identifier macros like mbedtls_printf or mbedtls_calloc
+ identifiers_justname = [x.name for x in identifiers]
+ actual_macros = []
+ for macro in all_macros:
+ if macro.name not in identifiers_justname:
+ actual_macros.append(macro)
+
+ self.log.debug("Found:")
+ # Aligns the counts on the assumption that none exceeds 4 digits
+ self.log.debug(" {:4} Total Macros".format(len(all_macros)))
+ self.log.debug(" {:4} Non-identifier Macros".format(len(actual_macros)))
+ self.log.debug(" {:4} Enum Constants".format(len(enum_consts)))
+ self.log.debug(" {:4} Identifiers".format(len(identifiers)))
+ self.log.debug(" {:4} Exported Symbols".format(len(symbols)))
+ return {
+ "macros": actual_macros,
+ "enum_consts": enum_consts,
+ "identifiers": identifiers,
+ "symbols": symbols,
+ "mbed_words": mbed_words
+ }
+
+ def get_files(self, include_wildcards, exclude_wildcards):
+ """
+ Get all files that match any of the UNIX-style wildcards. While the
+ check_names script is designed only for use on UNIX/macOS (due to nm),
+ this function alone would work fine on Windows even with forward slashes
+ in the wildcard.
+
+ Args:
+ * include_wildcards: a List of shell-style wildcards to match filepaths.
+ * exclude_wildcards: a List of shell-style wildcards to exclude.
+
+ Returns a List of relative filepaths.
+ """
+ accumulator = set()
+
+ # exclude_wildcards may be None. Also, consider the global exclusions.
+ exclude_wildcards = (exclude_wildcards or []) + self.excluded_files
+
+ # Internal function to hit the memoisation cache or add to it the result
+ # of a glob operation. Used both for inclusion and exclusion since the
+ # only difference between them is whether they perform set union or
+ # difference on the return value of this function.
+ def hit_cache(wildcard):
+ if wildcard not in self.files:
+ self.files[wildcard] = set(glob.glob(wildcard, recursive=True))
+ return self.files[wildcard]
+
+ for include_wildcard in include_wildcards:
+ accumulator = accumulator.union(hit_cache(include_wildcard))
+
+ for exclude_wildcard in exclude_wildcards:
+ accumulator = accumulator.difference(hit_cache(exclude_wildcard))
+
+ return list(accumulator)
+
+ def parse_macros(self, include, exclude=None):
+ """
+ Parse all macros defined by #define preprocessor directives.
+
+ Args:
+ * include: A List of glob expressions to look for files through.
+ * exclude: A List of glob expressions for excluding files.
+
+ Returns a List of Match objects for the found macros.
+ """
+ macro_regex = re.compile(r"# *define +(?P<macro>\w+)")
+ exclusions = (
+ "asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_"
+ )
+
+ files = self.get_files(include, exclude)
+ self.log.debug("Looking for macros in {} files".format(len(files)))
+
+ macros = []
+ for header_file in files:
+ with open(header_file, "r", encoding="utf-8") as header:
+ for line_no, line in enumerate(header):
+ for macro in macro_regex.finditer(line):
+ if macro.group("macro").startswith(exclusions):
+ continue
+
+ macros.append(Match(
+ header_file,
+ line,
+ line_no,
+ macro.span("macro"),
+ macro.group("macro")))
+
+ return macros
+
+ def parse_mbed_words(self, include, exclude=None):
+ """
+ Parse all words in the file that begin with MBED, in and out of macros,
+ comments, anything.
+
+ Args:
+ * include: A List of glob expressions to look for files through.
+ * exclude: A List of glob expressions for excluding files.
+
+ Returns a List of Match objects for words beginning with MBED.
+ """
+ # Typos of TLS are common, hence the broader check below than MBEDTLS.
+ mbed_regex = re.compile(r"\bMBED.+?_[A-Z0-9_]*")
+ exclusions = re.compile(r"// *no-check-names|#error")
+
+ files = self.get_files(include, exclude)
+ self.log.debug("Looking for MBED words in {} files".format(len(files)))
+
+ mbed_words = []
+ for filename in files:
+ with open(filename, "r", encoding="utf-8") as fp:
+ for line_no, line in enumerate(fp):
+ if exclusions.search(line):
+ continue
+
+ for name in mbed_regex.finditer(line):
+ mbed_words.append(Match(
+ filename,
+ line,
+ line_no,
+ name.span(0),
+ name.group(0)))
+
+ return mbed_words
+
+ def parse_enum_consts(self, include, exclude=None):
+ """
+ Parse all enum value constants that are declared.
+
+ Args:
+ * include: A List of glob expressions to look for files through.
+ * exclude: A List of glob expressions for excluding files.
+
+ Returns a List of Match objects for the findings.
+ """
+ files = self.get_files(include, exclude)
+ self.log.debug("Looking for enum consts in {} files".format(len(files)))
+
+ # Emulate a finite state machine to parse enum declarations.
+ # OUTSIDE_KEYWORD = outside the enum keyword
+ # IN_BRACES = inside enum opening braces
+ # IN_BETWEEN = between enum keyword and opening braces
+ states = enum.Enum("FSM", ["OUTSIDE_KEYWORD", "IN_BRACES", "IN_BETWEEN"])
+ enum_consts = []
+ for header_file in files:
+ state = states.OUTSIDE_KEYWORD
+ with open(header_file, "r", encoding="utf-8") as header:
+ for line_no, line in enumerate(header):
+ # Match typedefs and brackets only when they are at the
+ # beginning of the line -- if they are indented, they might
+ # be sub-structures within structs, etc.
+ if (state == states.OUTSIDE_KEYWORD and
+ re.search(r"^(typedef +)?enum +{", line)):
+ state = states.IN_BRACES
+ elif (state == states.OUTSIDE_KEYWORD and
+ re.search(r"^(typedef +)?enum", line)):
+ state = states.IN_BETWEEN
+ elif (state == states.IN_BETWEEN and
+ re.search(r"^{", line)):
+ state = states.IN_BRACES
+ elif (state == states.IN_BRACES and
+ re.search(r"^}", line)):
+ state = states.OUTSIDE_KEYWORD
+ elif (state == states.IN_BRACES and
+ not re.search(r"^ *#", line)):
+ enum_const = re.search(r"^ *(?P<enum_const>\w+)", line)
+ if not enum_const:
+ continue
+
+ enum_consts.append(Match(
+ header_file,
+ line,
+ line_no,
+ enum_const.span("enum_const"),
+ enum_const.group("enum_const")))
+
+ return enum_consts
+
+ def parse_identifiers(self, include, exclude=None):
+ """
+ Parse all lines of a header where a function/enum/struct/union/typedef
+ identifier is declared, based on some regex and heuristics. Highly
+ dependent on formatting style.
+
+ Args:
+ * include: A List of glob expressions to look for files through.
+ * exclude: A List of glob expressions for excluding files.
+
+ Returns a List of Match objects with identifiers.
+ """
+ identifier_regex = re.compile(
+ # Match " something(a" or " *something(a". Functions.
+ # Assumptions:
+ # - function definition from return type to one of its arguments is
+ # all on one line
+ # - function definition line only contains alphanumeric, asterisk,
+ # underscore, and open bracket
+ r".* \**(\w+) *\( *\w|"
+ # Match "(*something)(".
+ r".*\( *\* *(\w+) *\) *\(|"
+ # Match names of named data structures.
+ r"(?:typedef +)?(?:struct|union|enum) +(\w+)(?: *{)?$|"
+ # Match names of typedef instances, after closing bracket.
+ r"}? *(\w+)[;[].*"
+ )
+ # The regex below is indented for clarity.
+ exclusion_lines = re.compile(
+ r"^("
+ r"extern +\"C\"|" # pylint: disable=bad-continuation
+ r"(typedef +)?(struct|union|enum)( *{)?$|"
+ r"} *;?$|"
+ r"$|"
+ r"//|"
+ r"#"
+ r")"
+ )
+
+ files = self.get_files(include, exclude)
+ self.log.debug("Looking for identifiers in {} files".format(len(files)))
+
+ identifiers = []
+ for header_file in files:
+ with open(header_file, "r", encoding="utf-8") as header:
+ in_block_comment = False
+ # The previous line variable is used for concatenating lines
+ # when identifiers are formatted and spread across multiple
+ # lines.
+ previous_line = ""
+
+ for line_no, line in enumerate(header):
+ # Skip parsing this line if a block comment ends on it,
+ # but don't skip if it has just started -- there is a chance
+ # it ends on the same line.
+ if re.search(r"/\*", line):
+ in_block_comment = not in_block_comment
+ if re.search(r"\*/", line):
+ in_block_comment = not in_block_comment
+ continue
+
+ if in_block_comment:
+ previous_line = ""
+ continue
+
+ if exclusion_lines.search(line):
+ previous_line = ""
+ continue
+
+ # If the line contains only space-separated alphanumeric
+ # characters (or underscore, asterisk, or, open bracket),
+ # and nothing else, high chance it's a declaration that
+ # continues on the next line
+ if re.search(r"^([\w\*\(]+\s+)+$", line):
+ previous_line += line
+ continue
+
+ # If previous line seemed to start an unfinished declaration
+ # (as above), concat and treat them as one.
+ if previous_line:
+ line = previous_line.strip() + " " + line.strip() + "\n"
+ previous_line = ""
+
+ # Skip parsing if line has a space in front = heuristic to
+ # skip function argument lines (highly subject to formatting
+ # changes)
+ if line[0] == " ":
+ continue
+
+ identifier = identifier_regex.search(line)
+
+ if not identifier:
+ continue
+
+ # Find the group that matched, and append it
+ for group in identifier.groups():
+ if not group:
+ continue
+
+ identifiers.append(Match(
+ header_file,
+ line,
+ line_no,
+ identifier.span(),
+ group))
+
+ return identifiers
+
+ def parse_symbols(self):
+ """
+ Compile the Mbed TLS libraries, and parse the TLS, Crypto, and x509
+ object files using nm to retrieve the list of referenced symbols.
+ Exceptions thrown here are rethrown because they would be critical
+ errors that void several tests, and thus needs to halt the program. This
+ is explicitly done for clarity.
+
+ Returns a List of unique symbols defined and used in the libraries.
+ """
+ self.log.info("Compiling...")
+ symbols = []
+
+ # Back up the config and atomically compile with the full configratuion.
+ shutil.copy(
+ "include/mbedtls/mbedtls_config.h",
+ "include/mbedtls/mbedtls_config.h.bak"
+ )
+ try:
+ # Use check=True in all subprocess calls so that failures are raised
+ # as exceptions and logged.
+ subprocess.run(
+ ["python3", "scripts/config.py", "full"],
+ universal_newlines=True,
+ check=True
+ )
+ my_environment = os.environ.copy()
+ my_environment["CFLAGS"] = "-fno-asynchronous-unwind-tables"
+ # Run make clean separately to lib to prevent unwanted behavior when
+ # make is invoked with parallelism.
+ subprocess.run(
+ ["make", "clean"],
+ universal_newlines=True,
+ check=True
+ )
+ subprocess.run(
+ ["make", "lib"],
+ env=my_environment,
+ universal_newlines=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ check=True
+ )
+
+ # Perform object file analysis using nm
+ symbols = self.parse_symbols_from_nm([
+ "library/libmbedcrypto.a",
+ "library/libmbedtls.a",
+ "library/libmbedx509.a"
+ ])
+
+ subprocess.run(
+ ["make", "clean"],
+ universal_newlines=True,
+ check=True
+ )
+ except subprocess.CalledProcessError as error:
+ self.log.debug(error.output)
+ raise error
+ finally:
+ # Put back the original config regardless of there being errors.
+ # Works also for keyboard interrupts.
+ shutil.move(
+ "include/mbedtls/mbedtls_config.h.bak",
+ "include/mbedtls/mbedtls_config.h"
+ )
+
+ return symbols
+
+ def parse_symbols_from_nm(self, object_files):
+ """
+ Run nm to retrieve the list of referenced symbols in each object file.
+ Does not return the position data since it is of no use.
+
+ Args:
+ * object_files: a List of compiled object filepaths to search through.
+
+ Returns a List of unique symbols defined and used in any of the object
+ files.
+ """
+ nm_undefined_regex = re.compile(r"^\S+: +U |^$|^\S+:$")
+ nm_valid_regex = re.compile(r"^\S+( [0-9A-Fa-f]+)* . _*(?P<symbol>\w+)")
+ exclusions = ("FStar", "Hacl")
+
+ symbols = []
+
+ # Gather all outputs of nm
+ nm_output = ""
+ for lib in object_files:
+ nm_output += subprocess.run(
+ ["nm", "-og", lib],
+ universal_newlines=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ check=True
+ ).stdout
+
+ for line in nm_output.splitlines():
+ if not nm_undefined_regex.search(line):
+ symbol = nm_valid_regex.search(line)
+ if (symbol and not symbol.group("symbol").startswith(exclusions)):
+ symbols.append(symbol.group("symbol"))
+ else:
+ self.log.error(line)
+
+ return symbols
+
+class NameChecker():
+ """
+ Representation of the core name checking operation performed by this script.
+ """
+ def __init__(self, parse_result, log):
+ self.parse_result = parse_result
+ self.log = log
+
+ def perform_checks(self, quiet=False):
+ """
+ A comprehensive checker that performs each check in order, and outputs
+ a final verdict.
+
+ Args:
+ * quiet: whether to hide detailed problem explanation.
+ """
+ self.log.info("=============")
+ Problem.quiet = quiet
+ problems = 0
+ problems += self.check_symbols_declared_in_header()
+
+ pattern_checks = [
+ ("macros", MACRO_PATTERN),
+ ("enum_consts", CONSTANTS_PATTERN),
+ ("identifiers", IDENTIFIER_PATTERN)
+ ]
+ for group, check_pattern in pattern_checks:
+ problems += self.check_match_pattern(group, check_pattern)
+
+ problems += self.check_for_typos()
+
+ self.log.info("=============")
+ if problems > 0:
+ self.log.info("FAIL: {0} problem(s) to fix".format(str(problems)))
+ if quiet:
+ self.log.info("Remove --quiet to see explanations.")
+ else:
+ self.log.info("Use --quiet for minimal output.")
+ return 1
+ else:
+ self.log.info("PASS")
+ return 0
+
+ def check_symbols_declared_in_header(self):
+ """
+ Perform a check that all detected symbols in the library object files
+ are properly declared in headers.
+ Assumes parse_names_in_source() was called before this.
+
+ Returns the number of problems that need fixing.
+ """
+ problems = []
+
+ for symbol in self.parse_result["symbols"]:
+ found_symbol_declared = False
+ for identifier_match in self.parse_result["identifiers"]:
+ if symbol == identifier_match.name:
+ found_symbol_declared = True
+ break
+
+ if not found_symbol_declared:
+ problems.append(SymbolNotInHeader(symbol))
+
+ self.output_check_result("All symbols in header", problems)
+ return len(problems)
+
+ def check_match_pattern(self, group_to_check, check_pattern):
+ """
+ Perform a check that all items of a group conform to a regex pattern.
+ Assumes parse_names_in_source() was called before this.
+
+ Args:
+ * group_to_check: string key to index into self.parse_result.
+ * check_pattern: the regex to check against.
+
+ Returns the number of problems that need fixing.
+ """
+ problems = []
+
+ for item_match in self.parse_result[group_to_check]:
+ if not re.search(check_pattern, item_match.name):
+ problems.append(PatternMismatch(check_pattern, item_match))
+ # Double underscore should not be used for names
+ if re.search(r".*__.*", item_match.name):
+ problems.append(
+ PatternMismatch("no double underscore allowed", item_match))
+
+ self.output_check_result(
+ "Naming patterns of {}".format(group_to_check),
+ problems)
+ return len(problems)
+
+ def check_for_typos(self):
+ """
+ Perform a check that all words in the soure code beginning with MBED are
+ either defined as macros, or as enum constants.
+ Assumes parse_names_in_source() was called before this.
+
+ Returns the number of problems that need fixing.
+ """
+ problems = []
+
+ # Set comprehension, equivalent to a list comprehension wrapped by set()
+ all_caps_names = {
+ match.name
+ for match
+ in self.parse_result["macros"] + self.parse_result["enum_consts"]}
+ typo_exclusion = re.compile(r"XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$")
+
+ for name_match in self.parse_result["mbed_words"]:
+ found = name_match.name in all_caps_names
+
+ # Since MBEDTLS_PSA_ACCEL_XXX defines are defined by the
+ # PSA driver, they will not exist as macros. However, they
+ # should still be checked for typos using the equivalent
+ # BUILTINs that exist.
+ if "MBEDTLS_PSA_ACCEL_" in name_match.name:
+ found = name_match.name.replace(
+ "MBEDTLS_PSA_ACCEL_",
+ "MBEDTLS_PSA_BUILTIN_") in all_caps_names
+
+ if not found and not typo_exclusion.search(name_match.name):
+ problems.append(Typo(name_match))
+
+ self.output_check_result("Likely typos", problems)
+ return len(problems)
+
+ def output_check_result(self, name, problems):
+ """
+ Write out the PASS/FAIL status of a performed check depending on whether
+ there were problems.
+
+ Args:
+ * name: the name of the test
+ * problems: a List of encountered Problems
+ """
+ if problems:
+ self.log.info("{}: FAIL\n".format(name))
+ for problem in problems:
+ self.log.warning(str(problem))
+ else:
+ self.log.info("{}: PASS".format(name))
+
+def main():
+ """
+ Perform argument parsing, and create an instance of CodeParser and
+ NameChecker to begin the core operation.
+ """
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=(
+ "This script confirms that the naming of all symbols and identifiers "
+ "in Mbed TLS are consistent with the house style and are also "
+ "self-consistent.\n\n"
+ "Expected to be run from the MbedTLS root directory.")
+ )
+ parser.add_argument(
+ "-v", "--verbose",
+ action="store_true",
+ help="show parse results"
+ )
+ parser.add_argument(
+ "-q", "--quiet",
+ action="store_true",
+ help="hide unnecessary text, explanations, and highlighs"
+ )
+
+ args = parser.parse_args()
+
+ # Configure the global logger, which is then passed to the classes below
+ log = logging.getLogger()
+ log.setLevel(logging.DEBUG if args.verbose else logging.INFO)
+ log.addHandler(logging.StreamHandler())
+
+ try:
+ code_parser = CodeParser(log)
+ parse_result = code_parser.comprehensive_parse()
+ except Exception: # pylint: disable=broad-except
+ traceback.print_exc()
+ sys.exit(2)
+
+ name_checker = NameChecker(parse_result, log)
+ return_code = name_checker.perform_checks(quiet=args.quiet)
+
+ sys.exit(return_code)
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/scripts/list-enum-consts.pl b/tests/scripts/list-enum-consts.pl
deleted file mode 100755
index 6d93693..0000000
--- a/tests/scripts/list-enum-consts.pl
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use warnings;
-use strict;
-
-use utf8;
-use open qw(:std utf8);
-
--d 'include/mbedtls' or die "$0: must be run from root\n";
-
-@ARGV = grep { ! /compat-2\.x\.h/ } <include/mbedtls/*.h>;
-push @ARGV, "3rdparty/everest/include/everest/everest.h";
-push @ARGV, "3rdparty/everest/include/everest/x25519.h";
-push @ARGV, glob("library/*.h");
-
-my @consts;
-my $state = 'out';
-while (<>)
-{
- if( $state eq 'out' and /^(typedef )?enum \{/ ) {
- $state = 'in';
- } elsif( $state eq 'out' and /^(typedef )?enum/ ) {
- $state = 'start';
- } elsif( $state eq 'start' and /{/ ) {
- $state = 'in';
- } elsif( $state eq 'in' and /}/ ) {
- $state = 'out';
- } elsif( $state eq 'in' and not /^#/) {
- s/=.*//; s!/\*.*!!; s/,.*//; s/\s+//g; chomp;
- push @consts, $_ if $_;
- }
-}
-
-open my $fh, '>', 'enum-consts' or die;
-print $fh "$_\n" for sort @consts;
-close $fh or die;
-
-printf "%8d enum-consts\n", scalar @consts;
diff --git a/tests/scripts/list-identifiers.sh b/tests/scripts/list-identifiers.sh
index 9698fc8..9b93080 100755
--- a/tests/scripts/list-identifiers.sh
+++ b/tests/scripts/list-identifiers.sh
@@ -1,8 +1,11 @@
#!/bin/bash
#
# Create a file named identifiers containing identifiers from internal header
-# files or all header files, based on --internal flag.
+# files, based on the --internal flag.
# Outputs the line count of the file to stdout.
+# A very thin wrapper around list_internal_identifiers.py for backwards
+# compatibility.
+# Must be run from Mbed TLS root.
#
# Usage: list-identifiers.sh [ -i | --internal ]
#
@@ -24,7 +27,7 @@
set -eu
if [ -d include/mbedtls ]; then :; else
- echo "$0: must be run from root" >&2
+ echo "$0: Must be run from Mbed TLS root" >&2
exit 1
fi
@@ -47,32 +50,17 @@
if [ $INTERNAL ]
then
- HEADERS=$( ls include/mbedtls/*_internal.h library/*.h | egrep -v 'compat-2\.x\.h' )
+ tests/scripts/list_internal_identifiers.py
+ wc -l identifiers
else
- HEADERS=$( ls include/mbedtls/*.h include/psa/*.h library/*.h | egrep -v 'compat-2\.x\.h' )
- HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
+ cat <<EOF
+Sorry, this script has to be called with --internal.
+
+This script exists solely for backwards compatibility with the previous
+iteration of list-identifiers.sh, of which only the --internal option remains in
+use. It is a thin wrapper around list_internal_identifiers.py.
+
+check-names.sh, which used to depend on this script, has been replaced with
+check_names.py and is now self-complete.
+EOF
fi
-
-rm -f identifiers
-
-grep '^[^ /#{]' $HEADERS | \
- sed -e 's/^[^:]*://' | \
- egrep -v '^(extern "C"|(typedef )?(struct|union|enum)( {)?$|};?$)' \
- > _decls
-
-if true; then
-sed -n -e 's/.* \**\([a-zA-Z_][a-zA-Z0-9_]*\)(.*/\1/p' \
- -e 's/.*(\*\(.*\))(.*/\1/p' _decls
-grep -v '(' _decls | sed -e 's/\([a-zA-Z0-9_]*\)[;[].*/\1/' -e 's/.* \**//'
-fi > _identifiers
-
-if [ $( wc -l < _identifiers ) -eq $( wc -l < _decls ) ]; then
- rm _decls
- egrep -v '^(u?int(16|32|64)_t)$' _identifiers | sort > identifiers
- rm _identifiers
-else
- echo "$0: oops, lost some identifiers" 2>&1
- exit 1
-fi
-
-wc -l identifiers
diff --git a/tests/scripts/list-macros.sh b/tests/scripts/list-macros.sh
deleted file mode 100755
index 2e62359..0000000
--- a/tests/scripts/list-macros.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ -d include/mbedtls ]; then :; else
- echo "$0: must be run from root" >&2
- exit 1
-fi
-
-HEADERS=$( ls include/mbedtls/*.h include/psa/*.h tests/include/test/drivers/*.h | egrep -v 'compat-2\.x\.h' )
-HEADERS="$HEADERS library/*.h"
-HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
-
-sed -n -e 's/.*#define \([a-zA-Z0-9_]*\).*/\1/p' $HEADERS \
- | egrep -v '^(asm|inline|EMIT|_CRT_SECURE_NO_DEPRECATE)$|^MULADDC_' \
- | sort -u > macros
-
-# For include/mbedtls/config_psa.h need to ignore the MBEDTLS_xxx define
-# in that file since they may not be defined in include/psa/crypto_config.h
-# This line renames the potentially missing defines to ones that should
-# be present.
-sed -ne 's/^MBEDTLS_PSA_BUILTIN_/MBEDTLS_PSA_ACCEL_/p' <macros >>macros
-
-wc -l macros
diff --git a/tests/scripts/list-symbols.sh b/tests/scripts/list-symbols.sh
deleted file mode 100755
index 4a5d035..0000000
--- a/tests/scripts/list-symbols.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ -d include/mbedtls ]; then :; else
- echo "$0: must be run from root" >&2
- exit 1
-fi
-
-if grep -i cmake Makefile >/dev/null; then
- echo "$0: not compatible with cmake" >&2
- exit 1
-fi
-
-cp include/mbedtls/mbedtls_config.h include/mbedtls/mbedtls_config.h.bak
-scripts/config.py full
-make clean
-make_ret=
-CFLAGS=-fno-asynchronous-unwind-tables make lib \
- >list-symbols.make.log 2>&1 ||
- {
- make_ret=$?
- echo "Build failure: CFLAGS=-fno-asynchronous-unwind-tables make lib"
- cat list-symbols.make.log >&2
- }
-rm list-symbols.make.log
-mv include/mbedtls/mbedtls_config.h.bak include/mbedtls/mbedtls_config.h
-if [ -n "$make_ret" ]; then
- exit "$make_ret"
-fi
-
-if uname | grep -F Darwin >/dev/null; then
- nm -gUj library/libmbed*.a 2>/dev/null | sed -n -e 's/^_//p' | grep -v -e ^FStar -e ^Hacl
-elif uname | grep -F Linux >/dev/null; then
- nm -og library/libmbed*.a | grep -v '^[^ ]*: *U \|^$\|^[^ ]*:$' | sed 's/^[^ ]* . //' | grep -v -e ^FStar -e ^Hacl
-fi | sort > exported-symbols
-make clean
-
-wc -l exported-symbols
diff --git a/tests/scripts/list_internal_identifiers.py b/tests/scripts/list_internal_identifiers.py
new file mode 100755
index 0000000..779a16f
--- /dev/null
+++ b/tests/scripts/list_internal_identifiers.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This script generates a file called identifiers that contains all Mbed TLS
+identifiers found on internal headers. This is the equivalent of what was
+previously `list-identifiers.sh --internal`, and is useful for generating an
+exclusion file list for ABI/API checking, since we do not promise compatibility
+for them.
+
+It uses the CodeParser class from check_names.py to perform the parsing.
+
+The script returns 0 on success, 1 if there is a script error.
+Must be run from Mbed TLS root.
+"""
+
+import argparse
+import logging
+from check_names import CodeParser
+
+def main():
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=(
+ "This script writes a list of parsed identifiers in internal "
+ "headers to \"identifiers\". This is useful for generating a list "
+ "of names to exclude from API/ABI compatibility checking. "))
+
+ parser.parse_args()
+
+ name_check = CodeParser(logging.getLogger())
+ result = name_check.parse_identifiers([
+ "include/mbedtls/*_internal.h",
+ "library/*.h"
+ ])
+ result.sort(key=lambda x: x.name)
+
+ identifiers = ["{}\n".format(match.name) for match in result]
+ with open("identifiers", "w", encoding="utf-8") as f:
+ f.writelines(identifiers)
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/scripts/translate_ciphers.py b/tests/scripts/translate_ciphers.py
new file mode 100755
index 0000000..d5f847f
--- /dev/null
+++ b/tests/scripts/translate_ciphers.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+
+# translate_ciphers.py
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Translate ciphersuite names in Mbed TLS format to OpenSSL and GNUTLS
+standards.
+
+To test the translation functions run:
+python3 -m unittest translate_cipher.py
+"""
+
+import re
+import argparse
+import unittest
+
+class TestTranslateCiphers(unittest.TestCase):
+ """
+ Ensure translate_ciphers.py translates and formats ciphersuite names
+ correctly
+ """
+ def test_translate_all_cipher_names(self):
+ """
+ Translate MbedTLS ciphersuite names to their OpenSSL and
+ GnuTLS counterpart. Use only a small subset of ciphers
+ that exercise each step of the translate functions
+ """
+ ciphers = [
+ ("TLS-ECDHE-ECDSA-WITH-NULL-SHA",
+ "+ECDHE-ECDSA:+NULL:+SHA1",
+ "ECDHE-ECDSA-NULL-SHA"),
+ ("TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "+ECDHE-ECDSA:+AES-128-GCM:+AEAD",
+ "ECDHE-ECDSA-AES128-GCM-SHA256"),
+ ("TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "+DHE-RSA:+3DES-CBC:+SHA1",
+ "EDH-RSA-DES-CBC3-SHA"),
+ ("TLS-RSA-WITH-AES-256-CBC-SHA",
+ "+RSA:+AES-256-CBC:+SHA1",
+ "AES256-SHA"),
+ ("TLS-PSK-WITH-3DES-EDE-CBC-SHA",
+ "+PSK:+3DES-CBC:+SHA1",
+ "PSK-3DES-EDE-CBC-SHA"),
+ ("TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ None,
+ "ECDHE-ECDSA-CHACHA20-POLY1305"),
+ ("TLS-ECDHE-ECDSA-WITH-AES-128-CCM",
+ "+ECDHE-ECDSA:+AES-128-CCM:+AEAD",
+ None),
+ ("TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
+ None,
+ "ECDHE-ARIA256-GCM-SHA384"),
+ ]
+
+ for m, g_exp, o_exp in ciphers:
+
+ if g_exp is not None:
+ g = translate_gnutls(m)
+ self.assertEqual(g, g_exp)
+
+ if o_exp is not None:
+ o = translate_ossl(m)
+ self.assertEqual(o, o_exp)
+
+def translate_gnutls(m_cipher):
+ """
+ Translate m_cipher from Mbed TLS ciphersuite naming convention
+ and return the GnuTLS naming convention
+ """
+
+ m_cipher = re.sub(r'\ATLS-', '+', m_cipher)
+ m_cipher = m_cipher.replace("-WITH-", ":+")
+ m_cipher = m_cipher.replace("-EDE", "")
+
+ # SHA in Mbed TLS == SHA1 GnuTLS,
+ # if the last 3 chars are SHA append 1
+ if m_cipher[-3:] == "SHA":
+ m_cipher = m_cipher+"1"
+
+ # CCM or CCM-8 should be followed by ":+AEAD"
+ # Replace "GCM:+SHAxyz" with "GCM:+AEAD"
+ if "CCM" in m_cipher or "GCM" in m_cipher:
+ m_cipher = re.sub(r"GCM-SHA\d\d\d", "GCM", m_cipher)
+ m_cipher = m_cipher+":+AEAD"
+
+ # Replace the last "-" with ":+"
+ else:
+ index = m_cipher.rindex("-")
+ m_cipher = m_cipher[:index] + ":+" + m_cipher[index+1:]
+
+ return m_cipher
+
+def translate_ossl(m_cipher):
+ """
+ Translate m_cipher from Mbed TLS ciphersuite naming convention
+ and return the OpenSSL naming convention
+ """
+
+ m_cipher = re.sub(r'^TLS-', '', m_cipher)
+ m_cipher = m_cipher.replace("-WITH", "")
+
+ # Remove the "-" from "ABC-xyz"
+ m_cipher = m_cipher.replace("AES-", "AES")
+ m_cipher = m_cipher.replace("CAMELLIA-", "CAMELLIA")
+ m_cipher = m_cipher.replace("ARIA-", "ARIA")
+
+ # Remove "RSA" if it is at the beginning
+ m_cipher = re.sub(r'^RSA-', r'', m_cipher)
+
+ # For all circumstances outside of PSK
+ if "PSK" not in m_cipher:
+ m_cipher = m_cipher.replace("-EDE", "")
+ m_cipher = m_cipher.replace("3DES-CBC", "DES-CBC3")
+
+ # Remove "CBC" if it is not prefixed by DES
+ m_cipher = re.sub(r'(?<!DES-)CBC-', r'', m_cipher)
+
+ # ECDHE-RSA-ARIA does not exist in OpenSSL
+ m_cipher = m_cipher.replace("ECDHE-RSA-ARIA", "ECDHE-ARIA")
+
+ # POLY1305 should not be followed by anything
+ if "POLY1305" in m_cipher:
+ index = m_cipher.rindex("POLY1305")
+ m_cipher = m_cipher[:index+8]
+
+ # If DES is being used, Replace DHE with EDH
+ if "DES" in m_cipher and "DHE" in m_cipher and "ECDHE" not in m_cipher:
+ m_cipher = m_cipher.replace("DHE", "EDH")
+
+ return m_cipher
+
+def format_ciphersuite_names(mode, names):
+ t = {"g": translate_gnutls, "o": translate_ossl}[mode]
+ return " ".join(t(c) for c in names)
+
+def main(target, names):
+ print(format_ciphersuite_names(target, names))
+
+if __name__ == "__main__":
+ PARSER = argparse.ArgumentParser()
+ PARSER.add_argument('target', metavar='TARGET', choices=['o', 'g'])
+ PARSER.add_argument('names', metavar='NAMES', nargs='+')
+ ARGS = PARSER.parse_args()
+ main(ARGS.target, ARGS.names)
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 3e199e2..66c6485 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1322,6 +1322,11 @@
O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT"
fi
+if [ -n "${OPENSSL_NEXT:-}" ]; then
+ O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
+ O_NEXT_CLI="$O_NEXT_CLI -connect localhost:+SRV_PORT"
+fi
+
if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
G_NEXT_SRV="$G_NEXT_SRV -p $SRV_PORT"
fi
@@ -8655,11 +8660,53 @@
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
run_test "TLS1.3: handshake dispatch test: tls1_3 only" \
- "$P_SRV min_version=tls1_3 max_version=tls1_3" \
- "$P_CLI min_version=tls1_3 max_version=tls1_3" \
+ "$P_SRV debug_level=2 min_version=tls1_3 max_version=tls1_3" \
+ "$P_CLI debug_level=2 min_version=tls1_3 max_version=tls1_3" \
1 \
- -s "SSL - The requested feature is not available" \
- -c "SSL - The requested feature is not available"
+ -s "tls1_3 server state: 0" \
+ -c "tls1_3 client state: 0"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+run_test "TLS1.3: Test client hello msg work - openssl" \
+ "$O_NEXT_SRV -tls1_3 -msg" \
+ "$P_CLI debug_level=2 min_version=tls1_3 max_version=tls1_3" \
+ 1 \
+ -c "SSL - The requested feature is not available" \
+ -s "ServerHello" \
+ -c "tls1_3 client state: 0" \
+ -c "tls1_3 client state: 2" \
+ -c "tls1_3 client state: 19" \
+ -c "tls1_3 client state: 5" \
+ -c "tls1_3 client state: 3" \
+ -c "tls1_3 client state: 9" \
+ -c "tls1_3 client state: 13" \
+ -c "tls1_3 client state: 7" \
+ -c "tls1_3 client state: 20" \
+ -c "tls1_3 client state: 11" \
+ -c "tls1_3 client state: 14" \
+ -c "tls1_3 client state: 15"
+
+requires_gnutls_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+run_test "TLS1.3: Test client hello msg work - gnutls" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --debug=4" \
+ "$P_CLI debug_level=2 min_version=tls1_3 max_version=tls1_3" \
+ 1 \
+ -c "SSL - The requested feature is not available" \
+ -s "SERVER HELLO was queued" \
+ -c "tls1_3 client state: 0" \
+ -c "tls1_3 client state: 2" \
+ -c "tls1_3 client state: 19" \
+ -c "tls1_3 client state: 5" \
+ -c "tls1_3 client state: 3" \
+ -c "tls1_3 client state: 9" \
+ -c "tls1_3 client state: 13" \
+ -c "tls1_3 client state: 7" \
+ -c "tls1_3 client state: 20" \
+ -c "tls1_3 client state: 11" \
+ -c "tls1_3 client state: 14" \
+ -c "tls1_3 client state: 15"
# Test heap memory usage after handshake
requires_config_enabled MBEDTLS_MEMORY_DEBUG
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 674349f..c809d9a 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -13,6 +13,59 @@
#define MBEDTLS_CIPHER_AUTH_CRYPT
#endif
+/* Check the internal consistency of a cipher info structure, and
+ * check it against mbedtls_cipher_info_from_xxx(). */
+static int check_cipher_info( mbedtls_cipher_type_t type,
+ const mbedtls_cipher_info_t *info )
+{
+ size_t key_bitlen;
+
+ TEST_ASSERT( info != NULL );
+ TEST_EQUAL( type, mbedtls_cipher_info_get_type( info ) );
+ TEST_EQUAL( type, info->type );
+ TEST_ASSERT( mbedtls_cipher_info_from_type( type ) == info );
+
+ TEST_EQUAL( info->mode, mbedtls_cipher_info_get_mode( info ) );
+
+ /* Insist that get_name() return the string from the structure and
+ * not a copy. A copy would have an unknown storage duration. */
+ TEST_ASSERT( mbedtls_cipher_info_get_name( info ) == info->name );
+ TEST_ASSERT( mbedtls_cipher_info_from_string( info->name ) == info );
+
+ key_bitlen = mbedtls_cipher_info_get_key_bitlen( info );
+ if( info->type == MBEDTLS_CIPHER_NULL )
+ TEST_ASSERT( key_bitlen == 0 );
+ else if( info->mode == MBEDTLS_MODE_XTS )
+ {
+ TEST_ASSERT( key_bitlen == 256 ||
+ key_bitlen == 384 ||
+ key_bitlen == 512 );
+ }
+ else if( ! strncmp( info->name, "DES-EDE3-", 9 ) )
+ {
+ TEST_ASSERT( key_bitlen == 192 );
+ }
+ else if( ! strncmp( info->name, "DES-EDE-", 8 ) )
+ {
+ TEST_ASSERT( key_bitlen == 128 );
+ }
+ else if( ! strncmp( info->name, "DES-", 4 ) )
+ {
+ TEST_ASSERT( key_bitlen == 64 );
+ }
+ else
+ {
+ TEST_ASSERT( key_bitlen == 128 ||
+ key_bitlen == 192 ||
+ key_bitlen == 256 );
+ }
+
+ return( 1 );
+
+exit:
+ return( 0 );
+}
+
#if defined(MBEDTLS_CIPHER_AUTH_CRYPT)
/* Helper for resetting key/direction
*
@@ -81,7 +134,13 @@
const int *cipher_type;
for( cipher_type = mbedtls_cipher_list(); *cipher_type != 0; cipher_type++ )
- TEST_ASSERT( mbedtls_cipher_info_from_type( *cipher_type ) != NULL );
+ {
+ const mbedtls_cipher_info_t *info =
+ mbedtls_cipher_info_from_type( *cipher_type );
+ mbedtls_test_set_step( *cipher_type );
+ if( ! check_cipher_info( *cipher_type, info ) )
+ goto exit;
+ }
}
/* END_CASE */
@@ -309,6 +368,8 @@
cipher_info = mbedtls_cipher_info_from_type( cipher_id );
TEST_ASSERT( NULL != cipher_info );
TEST_ASSERT( mbedtls_cipher_info_from_string( cipher_string ) == cipher_info );
+ TEST_ASSERT( strcmp( mbedtls_cipher_info_get_name( cipher_info ),
+ cipher_string ) == 0 );
/* Initialise enc and dec contexts */
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
diff --git a/tests/suites/test_suite_net.function b/tests/suites/test_suite_net.function
index f429fc9..513b723 100644
--- a/tests/suites/test_suite_net.function
+++ b/tests/suites/test_suite_net.function
@@ -9,11 +9,11 @@
#endif
#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE)
-#include <sys/fcntl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <fcntl.h>
#include <unistd.h>
#endif