Merge pull request #976 from Mbed-TLS/merge-dev

Merge development into restricted
This commit is contained in:
Dave Rodgman 2022-12-05 16:21:17 +00:00 committed by GitHub
commit 4705f2d8a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
169 changed files with 9601 additions and 1898 deletions

View File

@ -25,8 +25,40 @@ jobs:
- tests/scripts/all.sh -k build_arm_linux_gnueabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
- name: full configuration
os: linux
dist: focal
addons:
apt:
packages:
- clang-10
- gnutls-bin
script:
- tests/scripts/all.sh -k test_full_cmake_gcc_asan
# Do a manual build+test sequence rather than using all.sh,
# because there's no all.sh component that does what we want,
# which is a build with Clang >= 10 and ASan, running all the SSL
# testing.
# - The clang executable in the default PATH is Clang 7 on
# Travis's focal instances, but we want Clang >= 10.
# - Running all the SSL testing requires a specific set of
# OpenSSL and GnuTLS versions and we don't want to bother
# with those on Travis.
# So we explicitly select clang-10 as the compiler, and we
# have ad hoc restrictions on SSL testing based on what is
# passing at the time of writing. We will remove these limitations
# gradually.
- make generated_files
- make CC=clang-10 CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all -O2' LDFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
- make test
- programs/test/selftest
- tests/scripts/test_psa_constant_names.py
- tests/ssl-opt.sh
# Modern OpenSSL does not support fixed ECDH or null ciphers.
- tests/compat.sh -p OpenSSL -e 'NULL\|ECDH-'
- tests/scripts/travis-log-failure.sh
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
- name: Windows
os: windows

View File

@ -1,20 +1,19 @@
Features
* Some crypto modules that previously depended on MD or a low-level hash
module, either unconditionally (RSA, PK, PKCS5, PKCS12, EC J-PAKE), or
for some features (PEM for encrypted files), are now able to use PSA
Crypto instead when the legacy API is not available. This means it is
now possible to use all features from those modules in configurations
where the built-in implementations of hashes are excluded and the hashes
are only provided by PSA drivers. In these configurations, you need to
call `psa_crypto_init()` before you call any function from those
modules; this is not required in configurations where the built-in
implementation is still available. Note that some crypto modules and
features still depend on the built-in implementation of hashes:
MBEDTLS_HKDF_C (but the PSA HKDF function do not depend on it),
MBEDTLS_ENTROPY_C, MBEDTLS_HMAC_DRBG_C and MBEDTLS_ECDSA_DETERMINISTIC.
In particular, for now, compiling without built-in hashes requires use
of MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
* When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 no
longer depend on MD. This means it is now possible to use them in
configurations where the built-in implementations of hashes are excluded
and the hashes are only provided by PSA drivers.
* Some modules can now use PSA drivers for hashes, including with no
built-in implementation present, but only in some configurations.
- RSA OAEP and PSS (PKCS#1 v2.1), PKCS5, PKCS12 and EC J-PAKE now use
hashes from PSA when (and only when) MBEDTLS_MD_C is disabled.
- PEM parsing of encrypted files now uses MD-5 from PSA when (and only
when) MBEDTLS_MD5_C is disabled.
See the documentation of the corresponding macros in mbedtls_config.h for
details.
Note that some modules are not able to use hashes from PSA yet, including
the entropy module. As a consequence, for now the only way to build with
all hashes only provided by drivers (no built-in hash) is to use
MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
* When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 now
properly negotiate/accept hashes based on their availability in PSA.
As a consequence, they now work in configurations where the built-in
implementations of (some) hashes are excluded and those hashes are only
provided by PSA drivers. (See previous entry for limitation on RSA-PSS
though: that module only use hashes from PSA when MBEDTLS_MD_C is off).

View File

@ -0,0 +1,16 @@
Features
* Add support for DTLS Connection ID as defined by RFC 9146, controlled by
MBEDTLS_SSL_DTLS_CONNECTION_ID (enabled by default) and configured with
mbedtls_ssl_set_cid().
Changes
* Previously the macro MBEDTLS_SSL_DTLS_CONNECTION_ID implemented version 05
of the draft, and was marked experimental and disabled by default. It is
now no longer experimental, and implements the final version from RFC 9146,
which is not interoperable with the draft-05 version. If you need to
communicate with peers that use earlier versions of Mbed TLS, you
need to define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT to 1, but then you
won't be able to communicate with peers that use the standard (non-draft)
version. If you need to interoperate with both classes of peers with the
same build of Mbed TLS, please let us know about your situation on the
mailing list or GitHub.

View File

@ -0,0 +1,5 @@
Features
* The TLS 1.2 EC J-PAKE key exchange can now use the PSA Crypto API.
Additional PSA key slots will be allocated in the process of such key
exchange for builds that enable MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED and
MBEDTLS_USE_PSA_CRYPTO.

View File

@ -0,0 +1,5 @@
Changes
* Calling AEAD tag-specific functions for non-AEAD algorithms (which
should not be done - they are documented for use only by AES-GCM and
ChaCha20+Poly1305) now returns MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
instead of success (0).

View File

@ -0,0 +1,5 @@
Bugfix
* Fix a bug whereby the the list of signature algorithms sent as part of the
TLS 1.2 server certificate request would get corrupted, meaning the first
algorithm would not get sent and an entry consisting of two random bytes
would be sent instead. Found by Serban Bejan and Dudek Sebastian.

View File

@ -0,0 +1,4 @@
Bugfix
* Fix bug in error reporting in dh_genprime.c where upon failure,
the error code returned by mbedtls_mpi_write_file() is overwritten
and therefore not printed.

View File

@ -0,0 +1,5 @@
Bugfix
* Fix a bug in which mbedtls_x509_crt_info() would produce non-printable
bytes when parsing certificates containing a binary RFC 4108
HardwareModuleName as a Subject Alternative Name extension. Hardware
serial numbers are now rendered in hex format. Fixes #6262.

View File

@ -0,0 +1,6 @@
Features
* Shared code to free x509 structs like mbedtls_x509_named_data
New deprecations
* Deprecate mbedtls_asn1_free_named_data().
Use mbedtls_asn1_free_named_data_list()
or mbedtls_asn1_free_named_data_list_shallow()

View File

@ -0,0 +1,3 @@
Bugfix
* Move some SSL-specific code out of libmbedcrypto where it had been placed
accidentally.

View File

@ -0,0 +1,4 @@
Bugfix
* Fix undefined behavior (typically harmless in practice) of
mbedtls_mpi_add_mpi(), mbedtls_mpi_add_abs() and mbedtls_mpi_add_int()
when both operands are 0 and the left operand is represented with 0 limbs.

View File

@ -0,0 +1,4 @@
Bugfix
* Fix undefined behavior (typically harmless in practice) when some bignum
functions receive the most negative value of mbedtls_mpi_sint. Credit
to OSS-Fuzz. Fixes #6597.

View File

@ -0,0 +1,6 @@
Bugfix
* In the bignum module, operations of the form (-A) - (+A) or (-A) - (-A)
with A > 0 created an unintended representation of the value 0 which was
not processed correctly by some bignum operations. Fix this. This had no
consequence on cryptography code, but might affect applications that call
bignum directly and use negative numbers.

View File

@ -0,0 +1,13 @@
Features
* Added partial support for parsing the PKCS7 cryptographic message syntax,
as defined in RFC 2315. Currently, support is limited to the following:
- Only the signed data content type, version 1 is supported.
- Only DER encoding is supported.
- Only a single digest algorithm per message is supported.
- Only 0 or 1, certificate is supported per message, which must be in
X509 format.
- There is no support for certificate-revocation lists.
- The authenticated and unauthenticated attribute fields of SignerInfo
must be empty.
Many thanks to Daniel Axtens, Nayna Jain, and Nick Child from IBM for
contributing this feature.

View File

@ -0,0 +1,3 @@
Bugfix
* Fix undefined behavior (typically harmless in practice) in PSA ECB
encryption and decryption.

View File

@ -0,0 +1,5 @@
Features
* Add a driver dispatch layer for raw key agreement, enabling alternative
implementations of raw key agreement through the key_agreement driver
entry point. This entry point is specified in the proposed PSA driver
interface, but had not yet been implemented.

View File

@ -13,6 +13,7 @@
# - the set of tests skipped in the driver-only build is the same as in an
# equivalent software-based configuration, or the difference is small enough,
# justified, and a github issue is created to track it.
# This part is verified by tests/scripts/analyze_outcomes.py
#
# WARNING: this script checks out a commit other than the head of the current
# branch; it checks out the current branch again when running successfully,
@ -26,30 +27,12 @@
# re-running this script (for example "get numbers before this PR").
# ----- BEGIN edit this -----
# The component in all.sh that builds and tests with drivers.
DRIVER_COMPONENT=test_psa_crypto_config_accel_hash_use_psa
# A similar configuration to that of the component, except without drivers,
# for comparison.
reference_config () {
# start with full
scripts/config.py full
# use PSA config and disable driver-less algs as in the component
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING
# disable options as in the component
# (no need to disable whole modules, we'll just skip their test suite)
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
}
# Space-separated list of test suites to ignore:
# if SSS is in that list, test_suite_SSS and test_suite_SSS.* are ignored.
IGNORE="md mdx shax" # accelerated
IGNORE="$IGNORE entropy hmac_drbg random" # disabled (ext. RNG)
IGNORE="$IGNORE psa_crypto_init" # needs internal RNG
IGNORE="$IGNORE hkdf" # disabled in the all.sh component tested
# Compare only "reference vs driver" or also "before vs after"?
BEFORE_AFTER=1 # 0 or 1
# ----- END edit this -----
set -eu
@ -65,38 +48,27 @@ record() {
make check
}
if [ "$BEFORE_AFTER" -eq 1 ]; then
# save current HEAD
HEAD=$(git branch --show-current)
# save current HEAD
HEAD=$(git branch --show-current)
# get the numbers before this PR for default and full
cleanup
git checkout $(git merge-base HEAD development)
record "before-default"
cleanup
scripts/config.py full
record "before-full"
# get the numbers now for default and full
cleanup
git checkout $HEAD
record "after-default"
cleanup
scripts/config.py full
record "after-full"
fi
# get the numbers now for driver-only and reference
# get the numbers before this PR for default and full
cleanup
reference_config
record "reference"
git checkout $(git merge-base HEAD development)
record "before-default"
cleanup
export MBEDTLS_TEST_OUTCOME_FILE="$PWD/outcome-drivers.csv"
export SKIP_SSL_OPT_COMPAT_SH=1
tests/scripts/all.sh -k test_psa_crypto_config_accel_hash_use_psa
scripts/config.py full
record "before-full"
# get the numbers now for default and full
cleanup
git checkout $HEAD
record "after-default"
cleanup
scripts/config.py full
record "after-full"
# analysis
@ -156,8 +128,5 @@ compare_builds () {
}
populate_suites
if [ "$BEFORE_AFTER" -eq 1 ]; then
compare_builds before-default after-default
compare_builds before-full after-full
fi
compare_builds reference drivers
compare_builds before-default after-default
compare_builds before-full after-full

View File

@ -478,3 +478,175 @@ outbound message on server side as well.
* state change: the state change is done in the main state handler to ease
the navigation of the state machine transitions.
Writing and reading early or 0-RTT data
---------------------------------------
An application function to write and send a buffer of data to a server through
TLS may plausibly look like:
```
int write_data( mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written )
{
*data_written = 0;
while( *data_written < data_to_write_len )
{
ret = mbedtls_ssl_write( ssl, data_to_write + *data_written,
data_to_write_len - *data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
return( ret );
}
*data_written += ret;
}
return( 0 );
}
```
where ssl is the SSL context to use, data_to_write the address of the data
buffer and data_to_write_len the number of data bytes. The handshake may
not be completed, not even started for the SSL context ssl when the function is
called and in that case the mbedtls_ssl_write() API takes care transparently of
completing the handshake before to write and send data to the server. The
mbedtls_ssl_write() may not been able to write and send all data in one go thus
the need for a loop calling it as long as there are still data to write and
send.
An application function to write and send early data and only early data,
data sent during the first flight of client messages while the handshake is in
its initial phase, would look completely similar but the call to
mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write().
```
int write_early_data( mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written )
{
*data_written = 0;
while( *data_written < data_to_write_len )
{
ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written,
data_to_write_len - *data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
return( ret );
}
*data_written += ret;
}
return( 0 );
}
```
Note that compared to write_data(), write_early_data() can also return
MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled
specifically by the user of write_early_data(). A fresh SSL context (typically
just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would
be expected when calling `write_early_data`.
All together, code to write and send a buffer of data as long as possible as
early data and then as standard post-handshake application data could
plausibly look like:
```
ret = write_early_data( ssl, data_to_write, data_to_write_len,
&early_data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
{
goto error;
}
ret = write_data( ssl, data_to_write + early_data_written,
data_to_write_len - early_data_written, &data_written );
if( ret < 0 )
goto error;
data_written += early_data_written;
```
Finally, taking into account that the server may reject early data, application
code to write and send a buffer of data could plausibly look like:
```
ret = write_early_data( ssl, data_to_write, data_to_write_len,
&early_data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
{
goto error;
}
/*
* Make sure the handshake is completed as it is a requisite to
* mbedtls_ssl_get_early_data_status().
*/
while( !mbedtls_ssl_is_handshake_over( ssl ) )
{
ret = mbedtls_ssl_handshake( ssl );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
goto error;
}
}
ret = mbedtls_ssl_get_early_data_status( ssl );
if( ret < 0 )
goto error;
if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED )
early_data_written = 0;
ret = write_data( ssl, data_to_write + early_data_written,
data_to_write_len - early_data_written, &data_written );
if( ret < 0 )
goto error;
data_written += early_data_written;
```
Basically, the same holds for reading early data on the server side without the
complication of possible rejection. An application function to read early data
into a given buffer could plausibly look like:
```
int read_early_data( mbedtls_ssl_context *ssl,
unsigned char *buffer,
size_t buffer_size,
size_t *data_len )
{
*data_len = 0;
while( *data_len < buffer_size )
{
ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len,
buffer_size - *data_len );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
return( ret );
}
*data_len += ret;
}
return( 0 );
}
```
with again calls to read_early_data() expected to be done with a fresh SSL
context.

View File

@ -86,7 +86,6 @@ is enabled, no change required on the application side.
Current exceptions:
- EC J-PAKE (when `MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED` is defined)
- finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
DHE-PSK)

View File

@ -61,11 +61,6 @@
/** Invalid input data. */
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -24,6 +24,7 @@
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#include <stddef.h>
@ -38,8 +39,9 @@
/**
* \name ASN1 Error codes
* These error codes are OR'ed to X509 error codes for
* These error codes are combined with other error codes for
* higher error granularity.
* e.g. X.509 and PKCS #7 error codes
* ASN1 is a standard to specify data structures.
* \{
*/
@ -606,25 +608,41 @@ int mbedtls_asn1_get_alg_null( unsigned char **p,
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
const char *oid, size_t len );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/**
* \brief Free a mbedtls_asn1_named_data entry
*
* \deprecated This function is deprecated and will be removed in a
* future version of the library.
* Please use mbedtls_asn1_free_named_data_list()
* or mbedtls_asn1_free_named_data_list_shallow().
*
* \param entry The named data entry to free.
* This function calls mbedtls_free() on
* `entry->oid.p` and `entry->val.p`.
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
void MBEDTLS_DEPRECATED mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Free all entries in a mbedtls_asn1_named_data list.
*
* \param head Pointer to the head of the list of named data entries to free.
* This function calls mbedtls_asn1_free_named_data() and
* mbedtls_free() on each list element and
* sets \c *head to \c NULL.
* This function calls mbedtls_free() on
* `entry->oid.p` and `entry->val.p` and then on `entry`
* for each list entry, and sets \c *head to \c NULL.
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
/**
* \brief Free all shallow entries in a mbedtls_asn1_named_data list,
* but do not free internal pointer targets.
*
* \param name Head of the list of named data entries to free.
* This function calls mbedtls_free() on each list element.
*/
void mbedtls_asn1_free_named_data_list_shallow( mbedtls_asn1_named_data *name );
/** \} name Functions to parse ASN.1 data structures */
/** \} addtogroup asn1_module */

View File

@ -179,6 +179,20 @@
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#endif /* !MBEDTLS_HAVE_INT64 */
/** \typedef mbedtls_mpi_uint
* \brief The type of machine digits in a bignum, called _limbs_.
*
* This is always an unsigned integer type with no padding bits. The size
* is platform-dependent.
*/
/** \typedef mbedtls_mpi_sint
* \brief The signed type corresponding to #mbedtls_mpi_uint.
*
* This is always an signed integer type with no padding bits. The size
* is platform-dependent.
*/
#ifdef __cplusplus
extern "C" {
#endif
@ -188,9 +202,27 @@ extern "C" {
*/
typedef struct mbedtls_mpi
{
int MBEDTLS_PRIVATE(s); /*!< Sign: -1 if the mpi is negative, 1 otherwise */
size_t MBEDTLS_PRIVATE(n); /*!< total # of limbs */
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); /*!< pointer to limbs */
/** Sign: -1 if the mpi is negative, 1 otherwise.
*
* The number 0 must be represented with `s = +1`. Although many library
* functions treat all-limbs-zero as equivalent to a valid representation
* of 0 regardless of the sign bit, there are exceptions, so bignum
* functions and external callers must always set \c s to +1 for the
* number zero.
*
* Note that this implies that calloc() or `... = {0}` does not create
* a valid MPI representation. You must call mbedtls_mpi_init().
*/
int MBEDTLS_PRIVATE(s);
/** Total number of limbs in \c p. */
size_t MBEDTLS_PRIVATE(n);
/** Pointer to limbs.
*
* This may be \c NULL if \c n is 0.
*/
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p);
}
mbedtls_mpi;
@ -758,11 +790,11 @@ int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A,
*
* \param Q The destination MPI for the quotient.
* This may be \c NULL if the value of the
* quotient is not needed.
* quotient is not needed. This must not alias A or B.
* \param R The destination MPI for the remainder value.
* This may be \c NULL if the value of the
* remainder is not needed.
* \param A The dividend. This must point to an initialized MPi.
* remainder is not needed. This must not alias A or B.
* \param A The dividend. This must point to an initialized MPI.
* \param B The divisor. This must point to an initialized MPI.
*
* \return \c 0 if successful.
@ -779,10 +811,10 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
*
* \param Q The destination MPI for the quotient.
* This may be \c NULL if the value of the
* quotient is not needed.
* quotient is not needed. This must not alias A.
* \param R The destination MPI for the remainder value.
* This may be \c NULL if the value of the
* remainder is not needed.
* remainder is not needed. This must not alias A.
* \param A The dividend. This must point to an initialized MPi.
* \param b The divisor.
*
@ -837,6 +869,7 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A,
* \brief Perform a sliding-window exponentiation: X = A^E mod N
*
* \param X The destination MPI. This must point to an initialized MPI.
* This must not alias E or N.
* \param A The base of the exponentiation.
* This must point to an initialized MPI.
* \param E The exponent MPI. This must point to an initialized MPI.

View File

@ -53,6 +53,12 @@
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
/* Define `inline` on some non-C99-compliant compilers. */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/mbedtls_config.h"
#else

View File

@ -842,10 +842,10 @@
"but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
#endif
/* Early data requires PSK related mode defined */
#if defined(MBEDTLS_SSL_EARLY_DATA) && \
( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \
!defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED))
( !defined(MBEDTLS_SSL_SESSION_TICKETS) || \
( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \
!defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) ) )
#error "MBEDTLS_SSL_EARLY_DATA defined, but not all prerequisites"
#endif
@ -903,6 +903,19 @@
#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && \
!defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0
#if defined(MBEDTLS_DEPRECATED_REMOVED)
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS"
#elif defined(MBEDTLS_DEPRECATED_WARNING)
#warning "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS"
#endif
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0 */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites"
@ -1062,6 +1075,14 @@
#error "MBEDTLS_SSL_TRUNCATED_HMAC was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4341"
#endif
#if defined(MBEDTLS_PKCS7_C) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \
( !defined(MBEDTLS_OID_C) ) || ( !defined(MBEDTLS_PK_PARSE_C) ) || \
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) ||\
( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || ( !defined(MBEDTLS_BIGNUM_C) ) || \
( !defined(MBEDTLS_MD_C) ) )
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
#endif
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the

View File

@ -46,11 +46,6 @@
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/** The selected feature is not available. */
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080
/** Bad input parameters. */

View File

@ -113,7 +113,7 @@ void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
* \param curve The identifier of the elliptic curve to use,
* for example #MBEDTLS_ECP_DP_SECP256R1.
* \param secret The pre-shared secret (passphrase). This must be
* a readable buffer of length \p len Bytes. It need
* a readable not empty buffer of length \p len Bytes. It need
* only be valid for the duration of this call.
* \param len The length of the pre-shared secret \p secret.
*

View File

@ -26,11 +26,6 @@
#include <stddef.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/**
* Error code layout.
*
@ -96,6 +91,7 @@
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* PKCS7 5 12 (Started from 0x5300)
* SSL 5 2 (Started from 0x5F00)
* CIPHER 6 8 (Started from 0x6080)
* SSL 6 22 (Started from top, plus 0x6000)

View File

@ -30,6 +30,7 @@
#include <stdint.h>
#include <stddef.h>
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#define MBEDTLS_ERR_LMS_BAD_INPUT_DATA -0x0011 /**< Bad data has been input to an LMS function */

View File

@ -1146,6 +1146,11 @@
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS#1 v2.1 operation.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
*
* This enables support for RSAES-OAEP and RSASSA-PSS operations.
*/
#define MBEDTLS_PKCS1_V21
@ -1320,21 +1325,16 @@
/**
* \def MBEDTLS_SSL_DTLS_CONNECTION_ID
*
* Enable support for the DTLS Connection ID extension
* (version draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
* Enable support for the DTLS Connection ID (CID) extension,
* which allows to identify DTLS connections across changes
* in the underlying transport.
* in the underlying transport. The CID functionality is described
* in RFC 9146.
*
* Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`,
* mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and
* `mbedtls_ssl_conf_cid()`. See the corresponding documentation for
* more information.
*
* \warning The Connection ID extension is still in draft state.
* We make no stability promises for the availability
* or the shape of the API controlled by this option.
*
* The maximum lengths of outgoing and incoming CIDs can be configured
* through the options
* - MBEDTLS_SSL_CID_OUT_LEN_MAX
@ -1344,7 +1344,30 @@
*
* Uncomment to enable the Connection ID extension.
*/
//#define MBEDTLS_SSL_DTLS_CONNECTION_ID
#define MBEDTLS_SSL_DTLS_CONNECTION_ID
/**
* \def MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
*
* Defines whether RFC 9146 (default) or the legacy version
* (version draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
* is used.
*
* Set the value to 0 for the standard version, and
* 1 for the legacy draft version.
*
* \deprecated Support for the legacy version of the DTLS
* Connection ID feature is deprecated. Please
* switch to the standardized version defined
* in RFC 9146 enabled by utilizing
* MBEDTLS_SSL_DTLS_CONNECTION_ID without use
* of MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT.
*
* Requires: MBEDTLS_SSL_DTLS_CONNECTION_ID
*/
#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0
/**
* \def MBEDTLS_SSL_ASYNC_PRIVATE
@ -1637,7 +1660,8 @@
*
* Enable support for RFC 8446 TLS 1.3 early data.
*
* Requires: MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or
* Requires: MBEDTLS_SSL_SESSION_TICKETS and either
* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or
* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
*
* Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3
@ -2432,6 +2456,11 @@
*
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any EC J-PAKE operations.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
*/
#define MBEDTLS_ECJPAKE_C
@ -2776,10 +2805,31 @@
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS5 operation.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
*
* This module adds support for the PKCS#5 functions.
*/
#define MBEDTLS_PKCS5_C
/**
* \def MBEDTLS_PKCS7_C
*
* Enable PKCS7 core for using PKCS7 formatted signatures.
* RFC Link - https://tools.ietf.org/html/rfc2315
*
* Module: library/pkcs7.c
*
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C,
* MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C,
* MBEDTLS_BIGNUM_C, MBEDTLS_MD_C
*
* This module is required for the PKCS7 parsing modules.
*/
#define MBEDTLS_PKCS7_C
/**
* \def MBEDTLS_PKCS12_C
*
@ -2795,6 +2845,11 @@
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS12 operation.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
*
* This module enables PKCS#12 functions.
*/
#define MBEDTLS_PKCS12_C
@ -3660,17 +3715,6 @@
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
/** \def MBEDTLS_TLS_EXT_CID
*
* At the time of writing, the CID extension has not been assigned its
* final value. Set this configuration option to make Mbed TLS use a
* different value.
*
* A future minor revision of Mbed TLS may change the default value of
* this option to match evolving standards and usage.
*/
//#define MBEDTLS_TLS_EXT_CID 254
/**
* Complete list of ciphersuites to use, in order of preference.
*

View File

@ -220,6 +220,7 @@
#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07" /**< pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } */
#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */
@ -300,6 +301,16 @@
#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
/*
* PKCS#7 OIDs
*/
#define MBEDTLS_OID_PKCS7_DATA MBEDTLS_OID_PKCS7 "\x01" /**< Content type is Data OBJECT IDENTIFIER ::= {pkcs-7 1} */
#define MBEDTLS_OID_PKCS7_SIGNED_DATA MBEDTLS_OID_PKCS7 "\x02" /**< Content type is Signed Data OBJECT IDENTIFIER ::= {pkcs-7 2} */
#define MBEDTLS_OID_PKCS7_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x03" /**< Content type is Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 3} */
#define MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x04" /**< Content type is Signed and Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 4} */
#define MBEDTLS_OID_PKCS7_DIGESTED_DATA MBEDTLS_OID_PKCS7 "\x05" /**< Content type is Digested Data OBJECT IDENTIFIER ::= {pkcs-7 5} */
#define MBEDTLS_OID_PKCS7_ENCRYPTED_DATA MBEDTLS_OID_PKCS7 "\x06" /**< Content type is Encrypted Data OBJECT IDENTIFIER ::= {pkcs-7 6} */
/*
* PKCS#8 OIDs
*/

View File

@ -27,11 +27,6 @@
#include <stddef.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/**
* \name PEM Error codes
* These error codes are returned in case of errors reading the

View File

@ -44,11 +44,6 @@
#include "psa/crypto.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/** Memory allocation failed. */
#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80
/** Type mismatch, eg attempt to encrypt with an ECDSA key */

241
include/mbedtls/pkcs7.h Normal file
View File

@ -0,0 +1,241 @@
/**
* \file pkcs7.h
*
* \brief PKCS7 generic defines and structures
* https://tools.ietf.org/html/rfc2315
*/
/*
* 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.
*/
/**
* Note: For the time being, this implementation of the PKCS7 cryptographic
* message syntax is a partial implementation of RFC 2315.
* Differences include:
* - The RFC specifies 6 different content types. The only type currently
* supported in Mbed TLS is the signed data content type.
* - The only supported PKCS7 Signed Data syntax version is version 1
* - The RFC specifies support for BER. This implementation is limited to
* DER only.
* - The RFC specifies that multiple digest algorithms can be specified
* in the Signed Data type. Only one digest algorithm is supported in Mbed TLS.
* - The RFC specifies the Signed Data type can contain multiple X509 or PKCS6
* certificates. In Mbed TLS, this list can only contain 0 or 1 certificates
* and they must be in X509 format.
* - The RFC specifies the Signed Data type can contain
* certificate-revocation lists (crls). This implementation has no support
* for crls so it is assumed to be an empty list.
* - The RFC allows for SignerInfo structure to optionally contain
* unauthenticatedAttributes and authenticatedAttributes. In Mbed TLS it is
* assumed these fields are empty.
*/
#ifndef MBEDTLS_PKCS7_H
#define MBEDTLS_PKCS7_H
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include "mbedtls/asn1.h"
#include "mbedtls/x509.h"
#include "mbedtls/x509_crt.h"
/**
* \name PKCS7 Module Error codes
* \{
*/
#define MBEDTLS_ERR_PKCS7_INVALID_FORMAT -0x5300 /**< The format is invalid, e.g. different type expected. */
#define MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE -0x5380 /**< Unavailable feature, e.g. anything other than signed data. */
#define MBEDTLS_ERR_PKCS7_INVALID_VERSION -0x5400 /**< The PKCS7 version element is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x5480 /**< The PKCS7 content info invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_ALG -0x5500 /**< The algorithm tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CERT -0x5580 /**< The certificate tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE -0x5600 /**< Error parsing the signature */
#define MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO -0x5680 /**< Error parsing the signer's info */
#define MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA -0x5700 /**< Input invalid. */
#define MBEDTLS_ERR_PKCS7_ALLOC_FAILED -0x5780 /**< Allocation of memory failed. */
#define MBEDTLS_ERR_PKCS7_VERIFY_FAIL -0x5800 /**< Verification Failed */
#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID -0x5880 /**< The PKCS7 date issued/expired dates are invalid */
/* \} name */
/**
* \name PKCS7 Supported Version
* \{
*/
#define MBEDTLS_PKCS7_SUPPORTED_VERSION 0x01
/* \} name */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Type-length-value structure that allows for ASN1 using DER.
*/
typedef mbedtls_asn1_buf mbedtls_pkcs7_buf;
/**
* Container for ASN1 named information objects.
* It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.).
*/
typedef mbedtls_asn1_named_data mbedtls_pkcs7_name;
/**
* Container for a sequence of ASN.1 items
*/
typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence;
/**
* PKCS7 types
*/
typedef enum {
MBEDTLS_PKCS7_NONE=0,
MBEDTLS_PKCS7_DATA,
MBEDTLS_PKCS7_SIGNED_DATA,
MBEDTLS_PKCS7_ENVELOPED_DATA,
MBEDTLS_PKCS7_SIGNED_AND_ENVELOPED_DATA,
MBEDTLS_PKCS7_DIGESTED_DATA,
MBEDTLS_PKCS7_ENCRYPTED_DATA,
}
mbedtls_pkcs7_type;
/**
* Structure holding PKCS7 signer info
*/
typedef struct mbedtls_pkcs7_signer_info
{
int MBEDTLS_PRIVATE(version);
mbedtls_x509_buf MBEDTLS_PRIVATE(serial);
mbedtls_x509_name MBEDTLS_PRIVATE(issuer);
mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw);
mbedtls_x509_buf MBEDTLS_PRIVATE(alg_identifier);
mbedtls_x509_buf MBEDTLS_PRIVATE(sig_alg_identifier);
mbedtls_x509_buf MBEDTLS_PRIVATE(sig);
struct mbedtls_pkcs7_signer_info *MBEDTLS_PRIVATE(next);
}
mbedtls_pkcs7_signer_info;
/**
* Structure holding attached data as part of PKCS7 signed data format
*/
typedef struct mbedtls_pkcs7_data
{
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(oid);
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(data);
}
mbedtls_pkcs7_data;
/**
* Structure holding the signed data section
*/
typedef struct mbedtls_pkcs7_signed_data
{
int MBEDTLS_PRIVATE(version);
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(digest_alg_identifiers);
struct mbedtls_pkcs7_data MBEDTLS_PRIVATE(content);
int MBEDTLS_PRIVATE(no_of_certs);
mbedtls_x509_crt MBEDTLS_PRIVATE(certs);
int MBEDTLS_PRIVATE(no_of_crls);
mbedtls_x509_crl MBEDTLS_PRIVATE(crl);
int MBEDTLS_PRIVATE(no_of_signers);
mbedtls_pkcs7_signer_info MBEDTLS_PRIVATE(signers);
}
mbedtls_pkcs7_signed_data;
/**
* Structure holding PKCS7 structure, only signed data for now
*/
typedef struct mbedtls_pkcs7
{
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw);
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(content_type_oid);
mbedtls_pkcs7_signed_data MBEDTLS_PRIVATE(signed_data);
}
mbedtls_pkcs7;
/**
* \brief Initialize pkcs7 structure.
*
* \param pkcs7 pkcs7 structure.
*/
void mbedtls_pkcs7_init( mbedtls_pkcs7 *pkcs7 );
/**
* \brief Parse a single DER formatted pkcs7 content.
*
* \param pkcs7 The pkcs7 structure to be filled by parser for the output.
* \param buf The buffer holding the DER encoded pkcs7.
* \param buflen The size in Bytes of \p buf.
*
* \note This function makes an internal copy of the PKCS7 buffer
* \p buf. In particular, \p buf may be destroyed or reused
* after this call returns.
*
* \return The \c mbedtls_pkcs7_type of \p buf, if successful.
* \return A negative error code on failure.
*/
int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
const size_t buflen );
/**
* \brief Verification of PKCS7 signature.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param cert Certificate containing key to verify signature.
* \param data Plain data on which signature has to be verified.
* \param datalen Length of the data.
*
* \note This function internally calculates the hash on the supplied
* plain data for signature verification.
*
* \return A negative error code on failure.
*/
int mbedtls_pkcs7_signed_data_verify( mbedtls_pkcs7 *pkcs7,
const mbedtls_x509_crt *cert,
const unsigned char *data,
size_t datalen );
/**
* \brief Verification of PKCS7 signature.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param cert Certificate containing key to verify signature.
* \param hash Hash of the plain data on which signature has to be verified.
* \param hashlen Length of the hash.
*
* \note This function is different from mbedtls_pkcs7_signed_data_verify()
* in a way that it directly recieves the hash of the data.
*
* \return A negative error code on failure.
*/
int mbedtls_pkcs7_signed_hash_verify( mbedtls_pkcs7 *pkcs7,
const mbedtls_x509_crt *cert,
const unsigned char *hash, size_t hashlen);
/**
* \brief Unallocate all PKCS7 data and zeroize the memory.
* It doesn't free pkcs7 itself. It should be done by the caller.
*
* \param pkcs7 PKCS7 structure to free.
*/
void mbedtls_pkcs7_free( mbedtls_pkcs7 *pkcs7 );
#ifdef __cplusplus
}
#endif
#endif /* pkcs7.h */

View File

@ -96,12 +96,16 @@
/* Error space gap */
/** Processing of the Certificate handshake message failed. */
#define MBEDTLS_ERR_SSL_BAD_CERTIFICATE -0x7A00
/** Received NewSessionTicket Post Handshake Message */
/* Error space gap */
/**
* Received NewSessionTicket Post Handshake Message.
* This error code is experimental and may be changed or removed without notice.
*/
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
/* Error space gap */
/* Error space gap */
/* Error space gap */
/* Error space gap */
/** Not possible to read early data */
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
/** Not possible to write early data */
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00
/* Error space gap */
/* Error space gap */
/* Error space gap */
@ -404,6 +408,14 @@
/** \} name SECTION: Module settings */
/*
* Default to standard CID mode
*/
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
!defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT)
#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0
#endif
/*
* Length of the verify data for secure renegotiation
*/
@ -572,15 +584,10 @@
#define MBEDTLS_TLS_EXT_SIG_ALG_CERT 50 /* RFC 8446 TLS 1.3 */
#define MBEDTLS_TLS_EXT_KEY_SHARE 51 /* RFC 8446 TLS 1.3 */
/* The value of the CID extension is still TBD as of
* draft-ietf-tls-dtls-connection-id-05
* (https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05).
*
* A future minor revision of Mbed TLS may change the default value of
* this option to match evolving standards and usage.
*/
#if !defined(MBEDTLS_TLS_EXT_CID)
#define MBEDTLS_TLS_EXT_CID 254 /* TBD */
#if MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
#define MBEDTLS_TLS_EXT_CID 54 /* RFC 9146 DTLS 1.2 CID */
#else
#define MBEDTLS_TLS_EXT_CID 254 /* Pre-RFC 9146 DTLS 1.2 CID */
#endif
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */
@ -661,7 +668,7 @@ typedef enum
MBEDTLS_SSL_SERVER_FINISHED,
MBEDTLS_SSL_FLUSH_BUFFERS,
MBEDTLS_SSL_HANDSHAKE_WRAPUP,
MBEDTLS_SSL_HANDSHAKE_OVER,
MBEDTLS_SSL_NEW_SESSION_TICKET,
MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
MBEDTLS_SSL_HELLO_RETRY_REQUEST,
@ -671,7 +678,9 @@ typedef enum
MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO,
MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO,
MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST,
MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH,
MBEDTLS_SSL_HANDSHAKE_OVER,
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET,
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH,
}
mbedtls_ssl_states;
@ -801,6 +810,21 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
typedef uint8_t mbedtls_ssl_tls13_ticket_flags;
#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK /* 1U << 0 */
#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL /* 1U << 2 */
#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA ( 1U << 3 )
#define MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK \
( MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION | \
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION | \
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA )
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
/**
* \brief Callback type: server-side session cache getter
*
@ -1783,6 +1807,10 @@ struct mbedtls_ssl_context
* and #MBEDTLS_SSL_CID_DISABLED. */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
int MBEDTLS_PRIVATE(early_data_status);
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/** Callback to export key block and master secret */
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */
@ -2049,8 +2077,9 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
* \brief Configure the use of the Connection ID (CID)
* extension in the next handshake.
*
* Reference: draft-ietf-tls-dtls-connection-id-05
* Reference: RFC 9146 (or draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
* for legacy version)
*
* The DTLS CID extension allows the reliable association of
* DTLS records to DTLS connections across changes in the
@ -3824,9 +3853,10 @@ void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
* \note The SSL context needs to be already set up. The right place
* to call this function is between \c mbedtls_ssl_setup() or
* \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
* Password cannot be empty (see RFC 8236).
*
* \param ssl SSL context
* \param pw EC J-PAKE password (pre-shared secret)
* \param pw EC J-PAKE password (pre-shared secret). It cannot be empty
* \param pw_len length of pw in bytes
*
* \return 0 on success, or a negative error code.
@ -4624,7 +4654,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
*/
static inline int mbedtls_ssl_is_handshake_over( mbedtls_ssl_context *ssl )
{
return( ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_HANDSHAKE_OVER );
return( ssl->MBEDTLS_PRIVATE( state ) >= MBEDTLS_SSL_HANDSHAKE_OVER );
}
/**
@ -4864,6 +4894,151 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
*/
int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_SRV_C)
/**
* \brief Read at most 'len' application data bytes while performing
* the handshake (early data).
*
* \note This function behaves mainly as mbedtls_ssl_read(). The
* specification of mbedtls_ssl_read() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS 1.2) applies to this
* function and the present documentation is restricted to the
* differences with mbedtls_ssl_read().
*
* \param ssl SSL context
* \param buf buffer that will hold the data
* \param len maximum number of bytes to read
*
* \return One additional specific return value:
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA.
*
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it
* is not possible to read early data for the SSL context
* \p ssl.
*
* It may have been possible and it is not possible
* anymore because the server received the End of Early Data
* message or the maximum number of allowed early data for the
* PSK in use has been reached.
*
* It may never have been possible and will never be possible
* for the SSL context \p ssl because the use of early data
* is disabled for that context or more generally the context
* is not suitably configured to enable early data or the
* client does not use early data or the first call to the
* function was done while the handshake was already too
* advanced to gather and accept early data.
*
* It is not possible to read early data for the SSL context
* \p ssl but this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
* mbedtls_ssl_handshake().
*
* \note When a server wants to retrieve early data, it is expected
* that this function starts the handshake for the SSL context
* \p ssl. But this is not mandatory.
*
*/
int mbedtls_ssl_read_early_data( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len );
#endif /* MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_CLI_C)
/**
* \brief Try to write exactly 'len' application data bytes while
* performing the handshake (early data).
*
* \note This function behaves mainly as mbedtls_ssl_write(). The
* specification of mbedtls_ssl_write() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS1.2) applies to this
* function and the present documentation is restricted to the
* differences with mbedtls_ssl_write().
*
* \param ssl SSL context
* \param buf buffer holding the data
* \param len how many bytes must be written
*
* \return One additional specific return value:
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA.
*
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA is returned when it
* is not possible to write early data for the SSL context
* \p ssl.
*
* It may have been possible and it is not possible
* anymore because the client received the server Finished
* message, the server rejected early data or the maximum
* number of allowed early data for the PSK in use has been
* reached.
*
* It may never have been possible and will never be possible
* for the SSL context \p ssl because the use of early data
* is disabled for that context or more generally the context
* is not suitably configured to enable early data or the first
* call to the function was done while the handshake was
* already completed.
*
* It is not possible to write early data for the SSL context
* \p ssl but this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
* mbedtls_ssl_handshake().
*
* \note This function may write early data only if the SSL context
* has been configured for the handshake with a PSK for which
* early data is allowed.
*
* \note To maximize the number of early data that can be written in
* the course of the handshake, it is expected that this
* function starts the handshake for the SSL context \p ssl.
* But this is not mandatory.
*
* \note This function does not provide any information on whether
* the server has accepted or will accept early data or not.
* When it returns a positive value, it just means that it
* has written early data to the server. To know whether the
* server has accepted early data or not, you should call
* mbedtls_ssl_get_early_data_status() with the handshake
* completed.
*/
int mbedtls_ssl_write_early_data( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len );
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2
/**
* \brief Get the status of the negotiation of the use of early data.
*
* \param ssl The SSL context to query
*
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called
* from the server-side.
*
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called
* prior to completion of the handshake.
*
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT if the client has
* not indicated the use of early data to the server.
*
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has
* indicated the use of early data and the server has accepted
* it.
*
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED if the client has
* indicated the use of early data but the server has rejected
* it. In this situation, the client may want to re-send the
* early data it may have tried to send by calling
* mbedtls_ssl_write_early_data() as ordinary post-handshake
* application data by calling mbedtls_ssl_write().
*
*/
int mbedtls_ssl_get_early_data_status( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_CLI_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
/**
* \brief Free referenced items in an SSL context and clear memory
*

View File

@ -1829,7 +1829,7 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation );
*/
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, \
MBEDTLS_SVC_KEY_ID_INIT, \
NULL, 0 , \
PSA_PAKE_ROLE_NONE, {0}, 0, 0, \
{.dummy = 0}}
#else
@ -1920,7 +1920,8 @@ struct psa_pake_operation_s
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
unsigned int MBEDTLS_PRIVATE(input_step);
unsigned int MBEDTLS_PRIVATE(output_step);
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(password);
uint8_t* MBEDTLS_PRIVATE(password);
size_t MBEDTLS_PRIVATE(password_len);
psa_pake_role_t MBEDTLS_PRIVATE(role);
uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_PAKE_BUFFER_SIZE]);
size_t MBEDTLS_PRIVATE(buffer_length);

View File

@ -45,11 +45,6 @@
/* PSA requires several types which C99 provides in stdint.h. */
#include <stdint.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
/* Building for the PSA Crypto service on a PSA platform, a key owner is a PSA

View File

@ -49,8 +49,6 @@ set(src_crypto
md.c
md5.c
memory_buffer_alloc.c
mps_reader.c
mps_trace.c
nist_kw.c
oid.c
padlock.c
@ -84,7 +82,6 @@ set(src_crypto
sha1.c
sha256.c
sha512.c
ssl_debug_helpers_generated.c
threading.c
timing.c
version.c
@ -92,6 +89,7 @@ set(src_crypto
)
set(src_x509
pkcs7.c
x509.c
x509_create.c
x509_crl.c
@ -103,11 +101,14 @@ set(src_x509
set(src_tls
debug.c
mps_reader.c
mps_trace.c
net_sockets.c
ssl_cache.c
ssl_ciphersuites.c
ssl_client.c
ssl_cookie.c
ssl_debug_helpers_generated.c
ssl_msg.c
ssl_ticket.c
ssl_tls.c

View File

@ -114,8 +114,6 @@ OBJS_CRYPTO= \
md.o \
md5.o \
memory_buffer_alloc.o \
mps_reader.o \
mps_trace.o \
nist_kw.o \
oid.o \
padlock.o \
@ -149,7 +147,6 @@ OBJS_CRYPTO= \
sha1.o \
sha256.o \
sha512.o \
ssl_debug_helpers_generated.o \
threading.o \
timing.o \
version.o \
@ -168,15 +165,19 @@ OBJS_X509= \
x509_csr.o \
x509write_crt.o \
x509write_csr.o \
pkcs7.o \
# This line is intentionally left blank
OBJS_TLS= \
debug.o \
mps_reader.o \
mps_trace.o \
net_sockets.o \
ssl_cache.o \
ssl_ciphersuites.o \
ssl_client.o \
ssl_cookie.o \
ssl_debug_helpers_generated.o \
ssl_msg.o \
ssl_ticket.o \
ssl_tls.o \

View File

@ -37,11 +37,6 @@
#include "mbedtls/platform_util.h"
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/* Parameter validation macros */
#define ARIA_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA )

View File

@ -314,7 +314,6 @@ void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
while( seq != NULL )
{
mbedtls_asn1_sequence *next = seq->next;
mbedtls_platform_zeroize( seq, sizeof( *seq ) );
mbedtls_free( seq );
seq = next;
}
@ -432,6 +431,7 @@ int mbedtls_asn1_get_alg_null( unsigned char **p,
return( 0 );
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
{
if( cur == NULL )
@ -442,6 +442,7 @@ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
{
@ -450,11 +451,21 @@ void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
while( ( cur = *head ) != NULL )
{
*head = cur->next;
mbedtls_asn1_free_named_data( cur );
mbedtls_free( cur->oid.p );
mbedtls_free( cur->val.p );
mbedtls_free( cur );
}
}
void mbedtls_asn1_free_named_data_list_shallow( mbedtls_asn1_named_data *name )
{
for( mbedtls_asn1_named_data *next; name != NULL; name = next )
{
next = name->next;
mbedtls_free( name );
}
}
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
const char *oid, size_t len )
{

View File

@ -252,6 +252,17 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
memcpy( Y, &T, sizeof( mbedtls_mpi ) );
}
static inline mbedtls_mpi_uint mpi_sint_abs( mbedtls_mpi_sint z )
{
if( z >= 0 )
return( z );
/* Take care to handle the most negative value (-2^(biL-1)) correctly.
* A naive -z would have undefined behavior.
* Write this in a way that makes popular compilers happy (GCC, Clang,
* MSVC). */
return( (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z );
}
/*
* Set value from integer
*/
@ -263,7 +274,7 @@ int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
memset( X->p, 0, X->n * ciL );
X->p[0] = ( z < 0 ) ? -z : z;
X->p[0] = mpi_sint_abs( z );
X->s = ( z < 0 ) ? -1 : 1;
cleanup:
@ -853,7 +864,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( X != NULL );
*p = ( z < 0 ) ? -z : z;
*p = mpi_sint_abs( z );
Y.s = ( z < 0 ) ? -1 : 1;
Y.n = 1;
Y.p = p;
@ -889,6 +900,11 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
if( B->p[j - 1] != 0 )
break;
/* Exit early to avoid undefined behavior on NULL+0 when X->n == 0
* and B is 0 (of any size). */
if( j == 0 )
return( 0 );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
/* j is the number of non-zero limbs of B. Add those to X. */
@ -952,17 +968,15 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
carry = mbedtls_mpi_core_sub( X->p, A->p, B->p, n );
if( carry != 0 )
{
/* Propagate the carry to the first nonzero limb of X. */
for( ; n < X->n && X->p[n] == 0; n++ )
--X->p[n];
/* If we ran out of space for the carry, it means that the result
* is negative. */
if( n == X->n )
/* Propagate the carry through the rest of X. */
carry = mbedtls_mpi_core_sub_int( X->p + n, X->p + n, carry, X->n - n );
/* If we have further carry/borrow, the result is negative. */
if( carry != 0 )
{
ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
goto cleanup;
}
--X->p[n];
}
/* X should always be positive as a result of unsigned subtractions. */
@ -972,10 +986,12 @@ cleanup:
return( ret );
}
/*
* Signed addition: X = A + B
/* Common function for signed addition and subtraction.
* Calculate A + B * flip_B where flip_B is 1 or -1.
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
static int add_sub_mpi( mbedtls_mpi *X,
const mbedtls_mpi *A, const mbedtls_mpi *B,
int flip_B )
{
int ret, s;
MPI_VALIDATE_RET( X != NULL );
@ -983,16 +999,21 @@ int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
MPI_VALIDATE_RET( B != NULL );
s = A->s;
if( A->s * B->s < 0 )
if( A->s * B->s * flip_B < 0 )
{
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
int cmp = mbedtls_mpi_cmp_abs( A, B );
if( cmp >= 0 )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
X->s = s;
/* If |A| = |B|, the result is 0 and we must set the sign bit
* to +1 regardless of which of A or B was negative. Otherwise,
* since |A| > |B|, the sign is the sign of A. */
X->s = cmp == 0 ? 1 : s;
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
/* Since |A| < |B|, the sign is the opposite of A. */
X->s = -s;
}
}
@ -1007,39 +1028,20 @@ cleanup:
return( ret );
}
/*
* Signed addition: X = A + B
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
return( add_sub_mpi( X, A, B, 1 ) );
}
/*
* Signed subtraction: X = A - B
*/
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
int ret, s;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
s = A->s;
if( A->s * B->s > 0 )
{
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
X->s = s;
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
X->s = -s;
}
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
X->s = s;
}
cleanup:
return( ret );
return( add_sub_mpi( X, A, B, -1 ) );
}
/*
@ -1052,7 +1054,7 @@ int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
p[0] = mpi_sint_abs( b );
B.s = ( b < 0 ) ? -1 : 1;
B.n = 1;
B.p = p;
@ -1070,7 +1072,7 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
p[0] = mpi_sint_abs( b );
B.s = ( b < 0 ) ? -1 : 1;
B.n = 1;
B.p = p;
@ -1408,7 +1410,7 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
p[0] = mpi_sint_abs( b );
B.s = ( b < 0 ) ? -1 : 1;
B.n = 1;
B.p = p;

View File

@ -540,6 +540,7 @@ cleanup:
return( ret );
}
MBEDTLS_STATIC_TESTABLE
void mbedtls_mpi_core_ct_uint_table_lookup( mbedtls_mpi_uint *dest,
const mbedtls_mpi_uint *table,
size_t limbs,
@ -582,6 +583,162 @@ cleanup:
/* BEGIN MERGE SLOT 1 */
static size_t exp_mod_get_window_size( size_t Ebits )
{
size_t wsize = ( Ebits > 671 ) ? 6 : ( Ebits > 239 ) ? 5 :
( Ebits > 79 ) ? 4 : 1;
#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
wsize = MBEDTLS_MPI_WINDOW_SIZE;
#endif
return( wsize );
}
static void exp_mod_precompute_window( const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N,
size_t AN_limbs,
mbedtls_mpi_uint mm,
const mbedtls_mpi_uint *RR,
size_t welem,
mbedtls_mpi_uint *Wtable,
mbedtls_mpi_uint *temp )
{
/* W[0] = 1 (in Montgomery presentation) */
memset( Wtable, 0, AN_limbs * ciL );
Wtable[0] = 1;
mbedtls_mpi_core_montmul( Wtable, Wtable, RR, AN_limbs, N, AN_limbs, mm, temp );
/* W[1] = A * R^2 * R^-1 mod N = A * R mod N */
mbedtls_mpi_uint *W1 = Wtable + AN_limbs;
mbedtls_mpi_core_montmul( W1, A, RR, AN_limbs, N, AN_limbs, mm, temp );
/* W[i+1] = W[i] * W[1], i >= 2 */
mbedtls_mpi_uint *Wprev = W1;
for( size_t i = 2; i < welem; i++ )
{
mbedtls_mpi_uint *Wcur = Wprev + AN_limbs;
mbedtls_mpi_core_montmul( Wcur, Wprev, W1, AN_limbs, N, AN_limbs, mm, temp );
Wprev = Wcur;
}
}
/* Exponentiation: X := A^E mod N.
*
* As in other bignum functions, assume that AN_limbs and E_limbs are nonzero.
*
* RR must contain 2^{2*biL} mod N.
*
* The algorithm is a variant of Left-to-right k-ary exponentiation: HAC 14.82
* (The difference is that the body in our loop processes a single bit instead
* of a full window.)
*/
int mbedtls_mpi_core_exp_mod( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N,
size_t AN_limbs,
const mbedtls_mpi_uint *E,
size_t E_limbs,
const mbedtls_mpi_uint *RR )
{
const size_t wsize = exp_mod_get_window_size( E_limbs * biL );
const size_t welem = ( (size_t) 1 ) << wsize;
/* Allocate memory pool and set pointers to parts of it */
const size_t table_limbs = welem * AN_limbs;
const size_t temp_limbs = 2 * AN_limbs + 1;
const size_t select_limbs = AN_limbs;
const size_t total_limbs = table_limbs + temp_limbs + select_limbs;
/* heap allocated memory pool */
mbedtls_mpi_uint *mempool =
mbedtls_calloc( total_limbs, sizeof(mbedtls_mpi_uint) );
if( mempool == NULL )
{
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
}
/* pointers to temporaries within memory pool */
mbedtls_mpi_uint *const Wtable = mempool;
mbedtls_mpi_uint *const Wselect = Wtable + table_limbs;
mbedtls_mpi_uint *const temp = Wselect + select_limbs;
/*
* Window precomputation
*/
const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init( N );
/* Set Wtable[i] = A^(2^i) (in Montgomery representation) */
exp_mod_precompute_window( A, N, AN_limbs,
mm, RR,
welem, Wtable, temp );
/*
* Fixed window exponentiation
*/
/* X = 1 (in Montgomery presentation) initially */
memcpy( X, Wtable, AN_limbs * ciL );
/* We'll process the bits of E from most significant
* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
* (limb_index=0, E_bit_index=0). */
size_t E_limb_index = E_limbs;
size_t E_bit_index = 0;
/* At any given time, window contains window_bits bits from E.
* window_bits can go up to wsize. */
size_t window_bits = 0;
mbedtls_mpi_uint window = 0;
do
{
/* Square */
mbedtls_mpi_core_montmul( X, X, X, AN_limbs, N, AN_limbs, mm, temp );
/* Move to the next bit of the exponent */
if( E_bit_index == 0 )
{
--E_limb_index;
E_bit_index = biL - 1;
}
else
{
--E_bit_index;
}
/* Insert next exponent bit into window */
++window_bits;
window <<= 1;
window |= ( E[E_limb_index] >> E_bit_index ) & 1;
/* Clear window if it's full. Also clear the window at the end,
* when we've finished processing the exponent. */
if( window_bits == wsize ||
( E_bit_index == 0 && E_limb_index == 0 ) )
{
/* Select Wtable[window] without leaking window through
* memory access patterns. */
mbedtls_mpi_core_ct_uint_table_lookup( Wselect, Wtable,
AN_limbs, welem, window );
/* Multiply X by the selected element. */
mbedtls_mpi_core_montmul( X, X, Wselect, AN_limbs, N, AN_limbs, mm,
temp );
window = 0;
window_bits = 0;
}
}
while( ! ( E_bit_index == 0 && E_limb_index == 0 ) );
/* Convert X back to normal presentation */
const mbedtls_mpi_uint one = 1;
mbedtls_mpi_core_montmul( X, X, &one, 1, N, AN_limbs, mm, temp );
mbedtls_platform_zeroize( mempool, total_limbs * sizeof(mbedtls_mpi_uint) );
mbedtls_free( mempool );
return( 0 );
}
/* END MERGE SLOT 1 */
/* BEGIN MERGE SLOT 2 */
@ -590,6 +747,22 @@ cleanup:
/* BEGIN MERGE SLOT 3 */
mbedtls_mpi_uint mbedtls_mpi_core_sub_int( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
mbedtls_mpi_uint c, /* doubles as carry */
size_t limbs )
{
for( size_t i = 0; i < limbs; i++ )
{
mbedtls_mpi_uint s = A[i];
mbedtls_mpi_uint t = s - c;
c = ( t > s );
X[i] = t;
}
return( c );
}
/* END MERGE SLOT 3 */
/* BEGIN MERGE SLOT 4 */

View File

@ -452,6 +452,7 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
int mbedtls_mpi_core_get_mont_r2_unsafe( mbedtls_mpi *X,
const mbedtls_mpi *N );
#if defined(MBEDTLS_TEST_HOOKS)
/**
* Copy an MPI from a table without leaking the index.
*
@ -469,6 +470,7 @@ void mbedtls_mpi_core_ct_uint_table_lookup( mbedtls_mpi_uint *dest,
size_t limbs,
size_t count,
size_t index );
#endif /* MBEDTLS_TEST_HOOKS */
/**
* \brief Fill an integer with a number of random bytes.
@ -496,6 +498,29 @@ int mbedtls_mpi_core_fill_random( mbedtls_mpi_uint *X, size_t X_limbs,
/* BEGIN MERGE SLOT 1 */
/**
* \brief Perform a modular exponentiation with secret exponent:
* X = A^E mod N
*
* \param[out] X The destination MPI, as a little endian array of length
* \p AN_limbs.
* \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
* \param[in] N The modulus, as a little endian array of length \p AN_limbs.
* \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR.
* \param[in] E The exponent, as a little endian array of length \p E_limbs.
* \param E_limbs The number of limbs in \p E.
* \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little
* endian array of length \p AN_limbs.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
*/
int mbedtls_mpi_core_exp_mod( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N, size_t AN_limbs,
const mbedtls_mpi_uint *E, size_t E_limbs,
const mbedtls_mpi_uint *RR );
/* END MERGE SLOT 1 */
/* BEGIN MERGE SLOT 2 */
@ -504,6 +529,23 @@ int mbedtls_mpi_core_fill_random( mbedtls_mpi_uint *X, size_t X_limbs,
/* BEGIN MERGE SLOT 3 */
/**
* \brief Subtract unsigned integer from known-size large unsigned integers.
* Return the borrow.
*
* \param[out] X The result of the subtraction.
* \param[in] A The left operand.
* \param b The unsigned scalar to subtract.
* \param limbs Number of limbs of \p X and \p A.
*
* \return 1 if `A < b`.
* 0 if `A >= b`.
*/
mbedtls_mpi_uint mbedtls_mpi_core_sub_int( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
mbedtls_mpi_uint b,
size_t limbs );
/* END MERGE SLOT 3 */
/* BEGIN MERGE SLOT 4 */

View File

@ -39,7 +39,7 @@ int mbedtls_mpi_mod_residue_setup( mbedtls_mpi_mod_residue *r,
mbedtls_mpi_uint *p,
size_t p_limbs )
{
if( p_limbs < m->limbs || !mbedtls_mpi_core_lt_ct( m->p, p, p_limbs ) )
if( p_limbs != m->limbs || !mbedtls_mpi_core_lt_ct( p, m->p, m->limbs ) )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
r->limbs = m->limbs;
@ -50,7 +50,7 @@ int mbedtls_mpi_mod_residue_setup( mbedtls_mpi_mod_residue *r,
void mbedtls_mpi_mod_residue_release( mbedtls_mpi_mod_residue *r )
{
if ( r == NULL )
if( r == NULL )
return;
r->limbs = 0;
@ -59,19 +59,18 @@ void mbedtls_mpi_mod_residue_release( mbedtls_mpi_mod_residue *r )
void mbedtls_mpi_mod_modulus_init( mbedtls_mpi_mod_modulus *m )
{
if ( m == NULL )
if( m == NULL )
return;
m->p = NULL;
m->limbs = 0;
m->bits = 0;
m->ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
}
void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m )
{
if ( m == NULL )
if( m == NULL )
return;
switch( m->int_rep )
@ -96,7 +95,6 @@ void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m )
m->p = NULL;
m->limbs = 0;
m->bits = 0;
m->ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
}
@ -112,17 +110,17 @@ static int set_mont_const_square( const mbedtls_mpi_uint **X,
mbedtls_mpi_init( &N );
mbedtls_mpi_init( &RR );
if ( A == NULL || limbs == 0 || limbs >= ( MBEDTLS_MPI_MAX_LIMBS / 2 ) - 2 )
if( A == NULL || limbs == 0 || limbs >= ( MBEDTLS_MPI_MAX_LIMBS / 2 ) - 2 )
goto cleanup;
if ( mbedtls_mpi_grow( &N, limbs ) )
if( mbedtls_mpi_grow( &N, limbs ) )
goto cleanup;
memcpy( N.p, A, sizeof(mbedtls_mpi_uint) * limbs );
ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
if ( ret == 0 )
if( ret == 0 )
{
*X = RR.p;
RR.p = NULL;
@ -138,7 +136,6 @@ cleanup:
int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
const mbedtls_mpi_uint *p,
size_t p_limbs,
mbedtls_mpi_mod_ext_rep ext_rep,
mbedtls_mpi_mod_rep_selector int_rep )
{
int ret = 0;
@ -147,17 +144,6 @@ int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
m->limbs = p_limbs;
m->bits = mbedtls_mpi_core_bitlen( p, p_limbs );
switch( ext_rep )
{
case MBEDTLS_MPI_MOD_EXT_REP_LE:
case MBEDTLS_MPI_MOD_EXT_REP_BE:
m->ext_rep = ext_rep;
break;
default:
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
goto exit;
}
switch( int_rep )
{
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
@ -209,7 +195,71 @@ exit:
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
int mbedtls_mpi_mod_read( mbedtls_mpi_mod_residue *r,
const mbedtls_mpi_mod_modulus *m,
const unsigned char *buf,
size_t buflen,
mbedtls_mpi_mod_ext_rep ext_rep )
{
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
/* Do our best to check if r and m have been set up */
if( r->limbs == 0 || m->limbs == 0 )
goto cleanup;
if( r->limbs != m->limbs )
goto cleanup;
ret = mbedtls_mpi_mod_raw_read( r->p, m, buf, buflen, ext_rep );
if( ret != 0 )
goto cleanup;
r->limbs = m->limbs;
if( m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
ret = mbedtls_mpi_mod_raw_to_mont_rep( r->p, m );
cleanup:
return ( ret );
}
int mbedtls_mpi_mod_write( const mbedtls_mpi_mod_residue *r,
const mbedtls_mpi_mod_modulus *m,
unsigned char *buf,
size_t buflen,
mbedtls_mpi_mod_ext_rep ext_rep )
{
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
/* Do our best to check if r and m have been set up */
if( r->limbs == 0 || m->limbs == 0 )
goto cleanup;
if( r->limbs != m->limbs )
goto cleanup;
if( m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
{
ret = mbedtls_mpi_mod_raw_from_mont_rep( r->p, m );
if( ret != 0 )
goto cleanup;
}
ret = mbedtls_mpi_mod_raw_write( r->p, m, buf, buflen, ext_rep );
if( m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
{
/* If this fails, the value of r is corrupted and we want to return
* this error (as opposed to the error code from the write above) to
* let the caller know. If it succeeds, we want to return the error
* code from write above. */
int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep( r->p, m );
if( ret == 0 )
ret = conv_ret;
}
cleanup:
return ( ret );
}
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View File

@ -64,7 +64,6 @@ typedef struct {
const mbedtls_mpi_uint *p;
size_t limbs; // number of limbs
size_t bits; // bitlen of p
mbedtls_mpi_mod_ext_rep ext_rep; // signals external representation (eg. byte order)
mbedtls_mpi_mod_rep_selector int_rep; // selector to signal the active member of the union
union rep
{
@ -75,16 +74,27 @@ typedef struct {
/** Setup a residue structure.
*
* \param[out] r The address of residue to setup. The size is determined by
* \p m.
* (In particular, it must have at least as many limbs as the
* modulus \p m.)
* The residue will be set up with the buffer \p p and modulus \p m.
*
* The memory pointed to by \p p will be used by the resulting residue structure.
* The value at the pointed-to memory will be the initial value of \p r and must
* hold a value that is less than the modulus. This value will be used as-is
* and interpreted according to the value of the `m->int_rep` field.
*
* The modulus \p m will be the modulus associated with \p r. The residue \p r
* should only be used in operations where the modulus is \p m.
*
* \param[out] r The address of the residue to setup.
* \param[in] m The address of the modulus related to \p r.
* \param[in] p The address of the limb array storing the value of \p r.
* \param[in] p The address of the limb array containing the value of \p r.
* The memory pointed to by \p p will be used by \p r and must
* not be modified in any way until after
* mbedtls_mpi_mod_residue_release() is called.
* \param p_limbs The number of limbs of \p p.
* mbedtls_mpi_mod_residue_release() is called. The data
* pointed to by \p p must be less than the modulus (the value
* pointed to by `m->p`) and already in the representation
* indicated by `m->int_rep`.
* \param p_limbs The number of limbs of \p p. Must be the same as the number
* of limbs in the modulus \p m.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the
@ -121,19 +131,15 @@ void mbedtls_mpi_mod_modulus_init( mbedtls_mpi_mod_modulus *m );
* not be modified in any way until after
* mbedtls_mpi_mod_modulus_free() is called.
* \param p_limbs The number of limbs of \p p.
* \param ext_rep The external representation to be used for residues
* associated with \p m (see #mbedtls_mpi_mod_ext_rep).
* \param int_rep The internal representation to be used for residues
* associated with \p m (see #mbedtls_mpi_mod_rep_selector).
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep or \p int_rep is
* invalid.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p int_rep is invalid.
*/
int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
const mbedtls_mpi_uint *p,
size_t p_limbs,
mbedtls_mpi_mod_ext_rep ext_rep,
mbedtls_mpi_mod_rep_selector int_rep );
/** Free elements of a modulus structure.
@ -173,7 +179,72 @@ void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m );
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
/** Read a residue from a byte buffer.
*
* The residue will be automatically converted to the internal representation
* based on the value of the `m->int_rep` field.
*
* The modulus \p m will be the modulus associated with \p r. The residue \p r
* should only be used in operations where the modulus is \p m or a modulus
* equivalent to \p m (in the sense that all their fields or memory pointed by
* their fields hold the same value).
*
* \param[out] r The address of the residue. It must have exactly the same
* number of limbs as the modulus \p m.
* \param[in] m The address of the modulus.
* \param[in] buf The input buffer to import from.
* \param buflen The length in bytes of \p buf.
* \param ext_rep The endianness of the number in the input buffer.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p r isn't
* large enough to hold the value in \p buf.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep
* is invalid or the value in the buffer is not less than \p m.
*/
int mbedtls_mpi_mod_read( mbedtls_mpi_mod_residue *r,
const mbedtls_mpi_mod_modulus *m,
const unsigned char *buf,
size_t buflen,
mbedtls_mpi_mod_ext_rep ext_rep );
/** Write a residue into a byte buffer.
*
* The modulus \p m must be the modulus associated with \p r (see
* mbedtls_mpi_mod_residue_setup() and mbedtls_mpi_mod_read()).
*
* The residue will be automatically converted from the internal representation
* based on the value of `m->int_rep` field.
*
* \warning If the buffer is smaller than `m->bits`, the number of
* leading zeroes is leaked through timing. If \p r is
* secret, the caller must ensure that \p buflen is at least
* (`m->bits`+7)/8.
*
* \param[in] r The address of the residue. It must have the same number of
* limbs as the modulus \p m. (\p r is an input parameter, but
* its value will be modified during execution and restored
* before the function returns.)
* \param[in] m The address of the modulus associated with \r.
* \param[out] buf The output buffer to export to.
* \param buflen The length in bytes of \p buf.
* \param ext_rep The endianness in which the number should be written into
* the output buffer.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
* large enough to hold the value of \p r (without leading
* zeroes).
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep is invalid.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough
* memory for conversion. Can occur only for moduli with
* MBEDTLS_MPI_MOD_REP_MONTGOMERY.
*/
int mbedtls_mpi_mod_write( const mbedtls_mpi_mod_residue *r,
const mbedtls_mpi_mod_modulus *m,
unsigned char *buf,
size_t buflen,
mbedtls_mpi_mod_ext_rep ext_rep );
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View File

@ -52,11 +52,12 @@ void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X,
int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m,
const unsigned char *input,
size_t input_length )
size_t input_length,
mbedtls_mpi_mod_ext_rep ext_rep )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
switch( m->ext_rep )
switch( ext_rep )
{
case MBEDTLS_MPI_MOD_EXT_REP_LE:
ret = mbedtls_mpi_core_read_le( X, m->limbs,
@ -87,9 +88,10 @@ cleanup:
int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
const mbedtls_mpi_mod_modulus *m,
unsigned char *output,
size_t output_length )
size_t output_length,
mbedtls_mpi_mod_ext_rep ext_rep )
{
switch( m->ext_rep )
switch( ext_rep )
{
case MBEDTLS_MPI_MOD_EXT_REP_LE:
return( mbedtls_mpi_core_write_le( A, m->limbs,
@ -108,6 +110,16 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* BEGIN MERGE SLOT 2 */
void mbedtls_mpi_mod_raw_sub( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
const mbedtls_mpi_mod_modulus *N )
{
mbedtls_mpi_uint c = mbedtls_mpi_core_sub( X, A, B, N->limbs );
(void) mbedtls_mpi_core_add_if( X, N->p, N->limbs, (unsigned) c );
}
/* END MERGE SLOT 2 */
/* BEGIN MERGE SLOT 3 */
@ -119,7 +131,16 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* END MERGE SLOT 4 */
/* BEGIN MERGE SLOT 5 */
void mbedtls_mpi_mod_raw_add( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
const mbedtls_mpi_mod_modulus *N )
{
mbedtls_mpi_uint carry, borrow;
carry = mbedtls_mpi_core_add( X, A, B, N->limbs );
borrow = mbedtls_mpi_core_sub( X, X, N->p, N->limbs );
(void) mbedtls_mpi_core_add_if( X, N->p, N->limbs, (unsigned) ( carry ^ borrow ) );
}
/* END MERGE SLOT 5 */
/* BEGIN MERGE SLOT 6 */
@ -127,7 +148,40 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
int mbedtls_mpi_mod_raw_to_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m )
{
mbedtls_mpi_uint *T;
const size_t t_limbs = m->limbs * 2 + 1;
if( ( T = (mbedtls_mpi_uint *) mbedtls_calloc( t_limbs, ciL ) ) == NULL )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
mbedtls_mpi_core_montmul( X, X, m->rep.mont.rr, m->limbs, m->p, m->limbs,
m->rep.mont.mm, T );
mbedtls_platform_zeroize( T, t_limbs * ciL );
mbedtls_free( T );
return( 0 );
}
int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m )
{
const mbedtls_mpi_uint one = 1;
const size_t t_limbs = m->limbs * 2 + 1;
mbedtls_mpi_uint *T;
if( ( T = (mbedtls_mpi_uint *) mbedtls_calloc( t_limbs, ciL ) ) == NULL )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
mbedtls_mpi_core_montmul( X, X, &one, 1, m->p, m->limbs,
m->rep.mont.mm, T );
mbedtls_platform_zeroize( T, t_limbs * ciL );
mbedtls_free( T );
return( 0 );
}
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View File

@ -106,6 +106,7 @@ void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X,
* \param[in] m The address of the modulus related to \p X.
* \param[in] input The input buffer to import from.
* \param input_length The length in bytes of \p input.
* \param ext_rep The endianness of the number in the input buffer.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
@ -116,7 +117,8 @@ void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X,
int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m,
const unsigned char *input,
size_t input_length );
size_t input_length,
mbedtls_mpi_mod_ext_rep ext_rep );
/** Export A into unsigned binary data.
*
@ -126,6 +128,7 @@ int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
* \param[in] m The address of the modulus related to \p A.
* \param[out] output The output buffer to export to.
* \param output_length The length in bytes of \p output.
* \param ext_rep The endianness in which the number should be written into the output buffer.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
@ -136,7 +139,8 @@ int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
const mbedtls_mpi_mod_modulus *m,
unsigned char *output,
size_t output_length );
size_t output_length,
mbedtls_mpi_mod_ext_rep ext_rep );
/* BEGIN MERGE SLOT 1 */
@ -144,6 +148,28 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* BEGIN MERGE SLOT 2 */
/** \brief Subtract two MPIs, returning the residue modulo the specified
* modulus.
*
* The size of the operation is determined by \p N. \p A and \p B must have
* the same number of limbs as \p N.
*
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
* either otherwise.
*
* \param[out] X The address of the result MPI.
* This must be initialized. Must have enough limbs to
* store the full value of the result.
* \param[in] A The address of the first MPI. This must be initialized.
* \param[in] B The address of the second MPI. This must be initialized.
* \param[in] N The address of the modulus. Used to perform a modulo
* operation on the result of the subtraction.
*/
void mbedtls_mpi_mod_raw_sub( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
const mbedtls_mpi_mod_modulus *N );
/* END MERGE SLOT 2 */
/* BEGIN MERGE SLOT 3 */
@ -155,7 +181,28 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* END MERGE SLOT 4 */
/* BEGIN MERGE SLOT 5 */
/**
* \brief Perform a known-size modular addition.
*
* Calculate `A + B modulo N`.
*
* The number of limbs in each operand, and the result, is given by the
* modulus \p N.
*
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
* either otherwise.
*
* \param[out] X The result of the modular addition.
* \param[in] A Little-endian presentation of the left operand. This
* must be smaller than \p N.
* \param[in] B Little-endian presentation of the right operand. This
* must be smaller than \p N.
* \param[in] N The address of the modulus.
*/
void mbedtls_mpi_mod_raw_add( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
const mbedtls_mpi_mod_modulus *N );
/* END MERGE SLOT 5 */
/* BEGIN MERGE SLOT 6 */
@ -163,7 +210,29 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
/** Convert an MPI into Montgomery form.
*
* \param X The address of the MPI.
* Must have the same number of limbs as \p m.
* \param m The address of the modulus, which gives the size of
* the base `R` = 2^(biL*m->limbs).
*
* \return \c 0 if successful.
*/
int mbedtls_mpi_mod_raw_to_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m );
/** Convert an MPI back from Montgomery representation.
*
* \param X The address of the MPI.
* Must have the same number of limbs as \p m.
* \param m The address of the modulus, which gives the size of
* the base `R`= 2^(biL*m->limbs).
*
* \return \c 0 if successful.
*/
int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m );
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View File

@ -36,11 +36,6 @@
#if !defined(MBEDTLS_CHACHA20_ALT)
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define ROTL32( value, amount ) \
( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )

View File

@ -500,7 +500,7 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
}
#endif
return( 0 );
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
@ -1129,7 +1129,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
}
#endif
return( 0 );
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
@ -1156,11 +1156,8 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Status to return on a non-authenticated algorithm. It would make sense
* to return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT or perhaps
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, but at the time I write this our
* unit tests assume 0. */
ret = 0;
/* Status to return on a non-authenticated algorithm. */
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )

View File

@ -25,6 +25,7 @@
#include "mbedtls/build_info.h"
#include <stddef.h>
#include <stdint.h>
/** Helper to define a function as static except when building invasive tests.
@ -68,6 +69,44 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c
*/
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
/** Return an offset into a buffer.
*
* This is just the addition of an offset to a pointer, except that this
* function also accepts an offset of 0 into a buffer whose pointer is null.
* (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
* A null pointer is a valid buffer pointer when the size is 0, for example
* as the result of `malloc(0)` on some platforms.)
*
* \param p Pointer to a buffer of at least n bytes.
* This may be \p NULL if \p n is zero.
* \param n An offset in bytes.
* \return Pointer to offset \p n in the buffer \p p.
* Note that this is only a valid pointer if the size of the
* buffer is at least \p n + 1.
*/
static inline unsigned char *mbedtls_buffer_offset(
unsigned char *p, size_t n )
{
return( p == NULL ? NULL : p + n );
}
/** Return an offset into a read-only buffer.
*
* Similar to mbedtls_buffer_offset(), but for const pointers.
*
* \param p Pointer to a buffer of at least n bytes.
* This may be \p NULL if \p n is zero.
* \param n An offset in bytes.
* \return Pointer to offset \p n in the buffer \p p.
* Note that this is only a valid pointer if the size of the
* buffer is at least \p n + 1.
*/
static inline const unsigned char *mbedtls_buffer_offset_const(
const unsigned char *p, size_t n )
{
return( p == NULL ? NULL : p + n );
}
/** Byte Reading Macros
*
* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th

View File

@ -138,6 +138,7 @@ unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
* \param B The right-hand MPI. This must point to an array of limbs
* with the same allocated length as \p A.
* \param limbs The number of limbs in \p A and \p B.
* This must not be 0.
*
* \return The result of the comparison:
* \c 1 if \p A is less than \p B.

View File

@ -30,11 +30,6 @@
#include <stdio.h>
#include <string.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define DEBUG_BUF_SIZE 512
static int debug_threshold = 0;

View File

@ -88,11 +88,6 @@
#include "ecp_internal_alt.h"
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#if defined(MBEDTLS_SELF_TEST)
/*
* Counts of point addition and doubling, and field multiplications.

View File

@ -39,11 +39,6 @@
#define ECP_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
#define ECP_MPI_INIT_ARRAY(x) \

View File

@ -29,11 +29,6 @@
#include <string.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER;
#endif /* MBEDTLS_MPS_ENABLE_TRACE */

727
library/pkcs7.c Normal file
View File

@ -0,0 +1,727 @@
/*
* 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.
*/
#include "common.h"
#include "mbedtls/build_info.h"
#if defined(MBEDTLS_PKCS7_C)
#include "mbedtls/pkcs7.h"
#include "mbedtls/x509.h"
#include "mbedtls/asn1.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_crl.h"
#include "mbedtls/oid.h"
#include "mbedtls/error.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined(MBEDTLS_FS_IO)
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
#include <time.h>
#endif
/**
* Initializes the pkcs7 structure.
*/
void mbedtls_pkcs7_init( mbedtls_pkcs7 *pkcs7 )
{
memset( pkcs7, 0, sizeof( *pkcs7 ) );
}
static int pkcs7_get_next_content_len( unsigned char **p, unsigned char *end,
size_t *len )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_CONTEXT_SPECIFIC );
if( ret != 0 )
{
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret );
}
return( ret );
}
/**
* version Version
* Version ::= INTEGER
**/
static int pkcs7_get_version( unsigned char **p, unsigned char *end, int *ver )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_asn1_get_int( p, end, ver );
if( ret != 0 )
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret );
/* If version != 1, return invalid version */
if( *ver != MBEDTLS_PKCS7_SUPPORTED_VERSION )
ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
return( ret );
}
/**
* ContentInfo ::= SEQUENCE {
* contentType ContentType,
* content
* [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
**/
static int pkcs7_get_content_info_type( unsigned char **p, unsigned char *end,
mbedtls_pkcs7_buf *pkcs7 )
{
size_t len = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *start = *p;
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE );
if( ret != 0 ) {
*p = start;
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret ) );
}
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OID );
if( ret != 0 ) {
*p = start;
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret ) );
}
pkcs7->tag = MBEDTLS_ASN1_OID;
pkcs7->len = len;
pkcs7->p = *p;
*p += len;
return( ret );
}
/**
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
*
* This is from x509.h
**/
static int pkcs7_get_digest_algorithm( unsigned char **p, unsigned char *end,
mbedtls_x509_buf *alg )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_ALG, ret );
return( ret );
}
/**
* DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
**/
static int pkcs7_get_digest_algorithm_set( unsigned char **p,
unsigned char *end,
mbedtls_x509_buf *alg )
{
size_t len = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SET );
if( ret != 0 )
{
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_ALG, ret ) );
}
end = *p + len;
ret = mbedtls_asn1_get_alg_null( p, end, alg );
if( ret != 0 )
{
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_ALG, ret ) );
}
/** For now, it assumes there is only one digest algorithm specified **/
if ( *p != end )
return( MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE );
return( 0 );
}
/**
* certificates :: SET OF ExtendedCertificateOrCertificate,
* ExtendedCertificateOrCertificate ::= CHOICE {
* certificate Certificate -- x509,
* extendedCertificate[0] IMPLICIT ExtendedCertificate }
* Return number of certificates added to the signed data,
* 0 or higher is valid.
* Return negative error code for failure.
**/
static int pkcs7_get_certificates( unsigned char **p, unsigned char *end,
mbedtls_x509_crt *certs )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len1 = 0;
size_t len2 = 0;
unsigned char *end_set, *end_cert, *start;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
{
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
return( 0 );
else
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret ) );
}
start = *p;
end_set = *p + len1;
ret = mbedtls_asn1_get_tag( p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE );
if( ret != 0 )
{
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_CERT, ret ) );
}
end_cert = *p + len2;
/*
* This is to verify that there is only one signer certificate. It seems it is
* not easy to differentiate between the chain vs different signer's certificate.
* So, we support only the root certificate and the single signer.
* The behaviour would be improved with addition of multiple signer support.
*/
if ( end_cert != end_set )
{
return( MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE );
}
*p = start;
if( ( ret = mbedtls_x509_crt_parse_der( certs, *p, len1 ) ) < 0 )
{
return( MBEDTLS_ERR_PKCS7_INVALID_CERT );
}
*p = *p + len1;
/*
* Since in this version we strictly support single certificate, and reaching
* here implies we have parsed successfully, we return 1.
*/
return( 1 );
}
/**
* EncryptedDigest ::= OCTET STRING
**/
static int pkcs7_get_signature( unsigned char **p, unsigned char *end,
mbedtls_pkcs7_buf *signature )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OCTET_STRING );
if( ret != 0 )
return( ret );
signature->tag = MBEDTLS_ASN1_OCTET_STRING;
signature->len = len;
signature->p = *p;
*p = *p + len;
return( 0 );
}
/**
* SignerInfo ::= SEQUENCE {
* version Version;
* issuerAndSerialNumber IssuerAndSerialNumber,
* digestAlgorithm DigestAlgorithmIdentifier,
* authenticatedAttributes
* [0] IMPLICIT Attributes OPTIONAL,
* digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
* encryptedDigest EncryptedDigest,
* unauthenticatedAttributes
* [1] IMPLICIT Attributes OPTIONAL,
* Returns 0 if the signerInfo is valid.
* Return negative error code for failure.
* Structure must not contain vales for authenticatedAttributes
* and unauthenticatedAttributes.
**/
static int pkcs7_get_signer_info( unsigned char **p, unsigned char *end,
mbedtls_pkcs7_signer_info *signer )
{
unsigned char *end_signer;
int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
asn1_ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE );
if( asn1_ret != 0 )
goto out;
end_signer = *p + len;
ret = pkcs7_get_version( p, end_signer, &signer->version );
if( ret != 0 )
goto out;
asn1_ret = mbedtls_asn1_get_tag( p, end_signer, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
if( asn1_ret != 0 )
goto out;
/* Parsing IssuerAndSerialNumber */
signer->issuer_raw.p = *p;
asn1_ret = mbedtls_asn1_get_tag( p, end_signer, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
if( asn1_ret != 0 )
goto out;
ret = mbedtls_x509_get_name( p, *p + len, &signer->issuer );
if( ret != 0 )
goto out;
signer->issuer_raw.len = *p - signer->issuer_raw.p;
ret = mbedtls_x509_get_serial( p, end_signer, &signer->serial );
if( ret != 0 )
goto out;
ret = pkcs7_get_digest_algorithm( p, end_signer, &signer->alg_identifier );
if( ret != 0 )
goto out;
/* Asssume authenticatedAttributes is nonexistent */
ret = pkcs7_get_digest_algorithm( p, end_signer, &signer->sig_alg_identifier );
if( ret != 0 )
goto out;
ret = pkcs7_get_signature( p, end_signer, &signer->sig );
if( ret != 0 )
goto out;
/* Do not permit any unauthenticated attributes */
if( *p != end_signer )
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
out:
if( asn1_ret != 0 )
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
asn1_ret );
else if( ret != 0 )
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
return( ret );
}
static void pkcs7_free_signer_info( mbedtls_pkcs7_signer_info *signer )
{
mbedtls_x509_name *name_cur;
mbedtls_x509_name *name_prv;
if( signer == NULL )
return;
name_cur = signer->issuer.next;
while( name_cur != NULL )
{
name_prv = name_cur;
name_cur = name_cur->next;
mbedtls_free( name_prv );
}
signer->issuer.next = NULL;
}
/**
* SignerInfos ::= SET of SignerInfo
* Return number of signers added to the signed data,
* 0 or higher is valid.
* Return negative error code for failure.
**/
static int pkcs7_get_signers_info_set( unsigned char **p, unsigned char *end,
mbedtls_pkcs7_signer_info *signers_set )
{
unsigned char *end_set;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int count = 0;
size_t len = 0;
ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SET );
if( ret != 0 )
{
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret ) );
}
/* Detect zero signers */
if( len == 0 )
{
return( 0 );
}
end_set = *p + len;
ret = pkcs7_get_signer_info( p, end_set, signers_set );
if( ret != 0 )
goto cleanup;
count++;
mbedtls_pkcs7_signer_info *prev = signers_set;
while( *p != end_set )
{
mbedtls_pkcs7_signer_info *signer =
mbedtls_calloc( 1, sizeof( mbedtls_pkcs7_signer_info ) );
if( !signer )
{
ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
goto cleanup;
}
ret = pkcs7_get_signer_info( p, end_set, signer );
if( ret != 0 ) {
mbedtls_free( signer );
goto cleanup;
}
prev->next = signer;
prev = signer;
count++;
}
return( count );
cleanup:
pkcs7_free_signer_info( signers_set );
mbedtls_pkcs7_signer_info *signer = signers_set->next;
while( signer != NULL )
{
prev = signer;
signer = signer->next;
pkcs7_free_signer_info( prev );
mbedtls_free( prev );
}
signers_set->next = NULL;
return( ret );
}
/**
* SignedData ::= SEQUENCE {
* version Version,
* digestAlgorithms DigestAlgorithmIdentifiers,
* contentInfo ContentInfo,
* certificates
* [0] IMPLICIT ExtendedCertificatesAndCertificates
* OPTIONAL,
* crls
* [0] IMPLICIT CertificateRevocationLists OPTIONAL,
* signerInfos SignerInfos }
*/
static int pkcs7_get_signed_data( unsigned char *buf, size_t buflen,
mbedtls_pkcs7_signed_data *signed_data )
{
unsigned char *p = buf;
unsigned char *end = buf + buflen;
unsigned char *end_set;
size_t len = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_alg;
ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE );
if( ret != 0 )
{
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret ) );
}
end_set = p + len;
/* Get version of signed data */
ret = pkcs7_get_version( &p, end_set, &signed_data->version );
if( ret != 0 )
return( ret );
/* Get digest algorithm */
ret = pkcs7_get_digest_algorithm_set( &p, end_set,
&signed_data->digest_alg_identifiers );
if( ret != 0 )
return( ret );
ret = mbedtls_oid_get_md_alg( &signed_data->digest_alg_identifiers, &md_alg );
if( ret != 0 )
{
return( MBEDTLS_ERR_PKCS7_INVALID_ALG );
}
/* Do not expect any content */
ret = pkcs7_get_content_info_type( &p, end_set, &signed_data->content.oid );
if( ret != 0 )
return( ret );
if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &signed_data->content.oid ) )
{
return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO );
}
/* Look for certificates, there may or may not be any */
mbedtls_x509_crt_init( &signed_data->certs );
ret = pkcs7_get_certificates( &p, end_set, &signed_data->certs );
if( ret < 0 )
return( ret );
signed_data->no_of_certs = ret;
/*
* Currently CRLs are not supported. If CRL exist, the parsing will fail
* at next step of getting signers info and return error as invalid
* signer info.
*/
signed_data->no_of_crls = 0;
/* Get signers info */
ret = pkcs7_get_signers_info_set( &p, end_set, &signed_data->signers );
if( ret < 0 )
return( ret );
signed_data->no_of_signers = ret;
/* Don't permit trailing data */
if ( p != end )
return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT );
return( 0 );
}
int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
const size_t buflen )
{
unsigned char *p;
unsigned char *end;
size_t len = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int isoidset = 0;
if( pkcs7 == NULL )
{
return( MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA );
}
/* make an internal copy of the buffer for parsing */
pkcs7->raw.p = p = mbedtls_calloc( 1, buflen );
if( pkcs7->raw.p == NULL )
{
ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
goto out;
}
memcpy( p, buf, buflen );
pkcs7->raw.len = buflen;
end = p + buflen;
ret = pkcs7_get_content_info_type( &p, end, &pkcs7->content_type_oid );
if( ret != 0 )
{
len = buflen;
goto try_data;
}
if( ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid )
|| ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid )
|| ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENVELOPED_DATA, &pkcs7->content_type_oid )
|| ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, &pkcs7->content_type_oid )
|| ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DIGESTED_DATA, &pkcs7->content_type_oid )
|| ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid ) )
{
ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
goto out;
}
if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->content_type_oid ) )
{
ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
goto out;
}
isoidset = 1;
ret = pkcs7_get_next_content_len( &p, end, &len );
if( ret != 0 )
goto out;
try_data:
ret = pkcs7_get_signed_data( p, len, &pkcs7->signed_data );
if ( ret != 0 )
goto out;
if ( !isoidset )
{
pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID;
pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS7_SIGNED_DATA );
pkcs7->content_type_oid.p = (unsigned char *)MBEDTLS_OID_PKCS7_SIGNED_DATA;
}
ret = MBEDTLS_PKCS7_SIGNED_DATA;
out:
if ( ret < 0 )
mbedtls_pkcs7_free( pkcs7 );
return( ret );
}
static int mbedtls_pkcs7_data_or_hash_verify( mbedtls_pkcs7 *pkcs7,
const mbedtls_x509_crt *cert,
const unsigned char *data,
size_t datalen,
const int is_data_hash )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *hash;
mbedtls_pk_context pk_cxt = cert->pk;
const mbedtls_md_info_t *md_info;
mbedtls_md_type_t md_alg;
mbedtls_pkcs7_signer_info *signer;
if( pkcs7->signed_data.no_of_signers == 0 )
{
return( MBEDTLS_ERR_PKCS7_INVALID_CERT );
}
if( mbedtls_x509_time_is_past( &cert->valid_to ) ||
mbedtls_x509_time_is_future( &cert->valid_from ))
{
return( MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID );
}
/*
* Potential TODOs
* Currently we iterate over all signers and return success if any of them
* verify.
*
* However, we could make this better by checking against the certificate's
* identification and SignerIdentifier fields first. That would also allow
* us to distinguish between 'no signature for key' and 'signature for key
* failed to validate'.
*
* We could also cache hashes by md, so if there are several sigs all using
* the same algo we don't recalculate the hash each time.
*/
for( signer = &pkcs7->signed_data.signers; signer; signer = signer->next )
{
ret = mbedtls_oid_get_md_alg( &signer->alg_identifier, &md_alg );
if( ret != 0 )
{
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
continue;
}
md_info = mbedtls_md_info_from_type( md_alg );
if( md_info == NULL )
{
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
continue;
}
hash = mbedtls_calloc( mbedtls_md_get_size( md_info ), 1 );
if( hash == NULL ) {
return( MBEDTLS_ERR_PKCS7_ALLOC_FAILED );
}
/* BEGIN must free hash before jumping out */
if( is_data_hash )
{
if( datalen != mbedtls_md_get_size( md_info ))
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
else
memcpy(hash, data, datalen);
}
else
{
ret = mbedtls_md( md_info, data, datalen, hash );
}
if( ret != 0 )
{
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
mbedtls_free( hash );
continue;
}
ret = mbedtls_pk_verify( &pk_cxt, md_alg, hash,
mbedtls_md_get_size( md_info ),
signer->sig.p, signer->sig.len );
mbedtls_free( hash );
/* END must free hash before jumping out */
if( ret == 0 )
break;
}
return( ret );
}
int mbedtls_pkcs7_signed_data_verify( mbedtls_pkcs7 *pkcs7,
const mbedtls_x509_crt *cert,
const unsigned char *data,
size_t datalen )
{
return( mbedtls_pkcs7_data_or_hash_verify( pkcs7, cert, data, datalen, 0 ) );
}
int mbedtls_pkcs7_signed_hash_verify( mbedtls_pkcs7 *pkcs7,
const mbedtls_x509_crt *cert,
const unsigned char *hash,
size_t hashlen )
{
return( mbedtls_pkcs7_data_or_hash_verify( pkcs7, cert, hash, hashlen, 1 ) );
}
/*
* Unallocate all pkcs7 data
*/
void mbedtls_pkcs7_free( mbedtls_pkcs7 *pkcs7 )
{
mbedtls_pkcs7_signer_info *signer_cur;
mbedtls_pkcs7_signer_info *signer_prev;
if( pkcs7 == NULL || pkcs7->raw.p == NULL )
return;
mbedtls_free( pkcs7->raw.p );
mbedtls_x509_crt_free( &pkcs7->signed_data.certs );
mbedtls_x509_crl_free( &pkcs7->signed_data.crl );
signer_cur = pkcs7->signed_data.signers.next;
pkcs7_free_signer_info( &pkcs7->signed_data.signers );
while( signer_cur != NULL )
{
signer_prev = signer_cur;
signer_cur = signer_prev->next;
pkcs7_free_signer_info( signer_prev );
mbedtls_free( signer_prev );
}
pkcs7->raw.p = NULL;
}
#endif

View File

@ -32,11 +32,6 @@
#if !defined(MBEDTLS_POLY1305_ALT)
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
/*

View File

@ -877,20 +877,7 @@ static psa_status_t psa_restrict_key_policy(
return( PSA_SUCCESS );
}
/** Get the description of a key given its identifier and policy constraints
* and lock it.
*
* The key must have allow all the usage flags set in \p usage. If \p alg is
* nonzero, the key must allow operations with this algorithm. If \p alg is
* zero, the algorithm is not checked.
*
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* On success, the returned key slot is locked. It is the responsibility of
* the caller to unlock the key slot when it does not access it anymore.
*/
static psa_status_t psa_get_and_lock_key_slot_with_policy(
psa_status_t psa_get_and_lock_key_slot_with_policy(
mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot,
psa_key_usage_t usage,
@ -3467,8 +3454,8 @@ psa_status_t psa_cipher_encrypt( mbedtls_svc_key_id_t key,
status = psa_driver_wrapper_cipher_encrypt(
&attributes, slot->key.data, slot->key.bytes,
alg, local_iv, default_iv_length, input, input_length,
output + default_iv_length, output_size - default_iv_length,
output_length );
mbedtls_buffer_offset( output, default_iv_length ),
output_size - default_iv_length, output_length );
exit:
unlock_status = psa_unlock_key_slot( slot );
@ -5736,63 +5723,46 @@ psa_status_t psa_key_derivation_input_key(
/* Key agreement */
/****************************************************************/
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
psa_status_t psa_key_agreement_raw_builtin( const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *peer_key,
size_t peer_key_length,
const mbedtls_ecp_keypair *our_key,
uint8_t *shared_secret,
size_t shared_secret_size,
size_t *shared_secret_length )
{
mbedtls_ecp_keypair *their_key = NULL;
mbedtls_ecdh_context ecdh;
psa_status_t status;
size_t bits = 0;
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
mbedtls_ecdh_init( &ecdh );
status = mbedtls_psa_ecp_load_representation(
PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
bits,
peer_key,
peer_key_length,
&their_key );
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_to_psa_error(
mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_to_psa_error(
mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_to_psa_error(
mbedtls_ecdh_calc_secret( &ecdh,
shared_secret_length,
shared_secret, shared_secret_size,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE ) );
if( status != PSA_SUCCESS )
goto exit;
if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
status = PSA_ERROR_CORRUPTION_DETECTED;
exit:
if( status != PSA_SUCCESS )
mbedtls_platform_zeroize( shared_secret, shared_secret_size );
mbedtls_ecdh_free( &ecdh );
mbedtls_ecp_keypair_free( their_key );
mbedtls_free( their_key );
return( status );
}
switch( alg )
{
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
case PSA_ALG_ECDH:
return( mbedtls_psa_key_agreement_ecdh( attributes, key_buffer,
key_buffer_size, alg,
peer_key, peer_key_length,
shared_secret,
shared_secret_size,
shared_secret_length ) );
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
default:
(void) attributes;
(void) key_buffer;
(void) key_buffer_size;
(void) peer_key;
(void) peer_key_length;
(void) shared_secret;
(void) shared_secret_size;
(void) shared_secret_length;
return( PSA_ERROR_NOT_SUPPORTED );
}
}
#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
/** Internal function for raw key agreement
* Calls the driver wrapper which will hand off key agreement task
* to the driver's implementation if a driver is present.
* Fallback specified in the driver wrapper is built-in raw key agreement
* (psa_key_agreement_raw_builtin).
*/
static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
psa_key_slot_t *private_key,
const uint8_t *peer_key,
@ -5801,38 +5771,20 @@ static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
size_t shared_secret_size,
size_t *shared_secret_length )
{
switch( alg )
{
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
case PSA_ALG_ECDH:
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
return( PSA_ERROR_INVALID_ARGUMENT );
mbedtls_ecp_keypair *ecp = NULL;
psa_status_t status = mbedtls_psa_ecp_load_representation(
private_key->attr.type,
private_key->attr.bits,
private_key->key.data,
private_key->key.bytes,
&ecp );
if( status != PSA_SUCCESS )
return( status );
status = psa_key_agreement_ecdh( peer_key, peer_key_length,
ecp,
shared_secret, shared_secret_size,
shared_secret_length );
mbedtls_ecp_keypair_free( ecp );
mbedtls_free( ecp );
return( status );
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
default:
(void) private_key;
(void) peer_key;
(void) peer_key_length;
(void) shared_secret;
(void) shared_secret_size;
(void) shared_secret_length;
return( PSA_ERROR_NOT_SUPPORTED );
}
if( !PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
return( PSA_ERROR_NOT_SUPPORTED );
psa_key_attributes_t attributes = {
.core = private_key->attr
};
return( psa_driver_wrapper_key_agreement( &attributes,
private_key->key.data,
private_key->key.bytes, alg,
peer_key, peer_key_length,
shared_secret,
shared_secret_size,
shared_secret_length ) );
}
/* Note that if this function fails, you must call psa_key_derivation_abort()
@ -5845,7 +5797,7 @@ static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *
size_t peer_key_length )
{
psa_status_t status;
uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
size_t shared_secret_length = 0;
psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );

View File

@ -516,10 +516,10 @@ psa_status_t mbedtls_psa_cipher_encrypt(
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_psa_cipher_finish( &operation,
output + update_output_length,
output_size - update_output_length,
&finish_output_length );
status = mbedtls_psa_cipher_finish(
&operation,
mbedtls_buffer_offset( output, update_output_length ),
output_size - update_output_length, &finish_output_length );
if( status != PSA_SUCCESS )
goto exit;
@ -563,17 +563,20 @@ psa_status_t mbedtls_psa_cipher_decrypt(
goto exit;
}
status = mbedtls_psa_cipher_update( &operation, input + operation.iv_length,
input_length - operation.iv_length,
output, output_size, &olength );
status = mbedtls_psa_cipher_update(
&operation,
mbedtls_buffer_offset_const( input, operation.iv_length ),
input_length - operation.iv_length,
output, output_size, &olength );
if( status != PSA_SUCCESS )
goto exit;
accumulated_length = olength;
status = mbedtls_psa_cipher_finish( &operation, output + accumulated_length,
output_size - accumulated_length,
&olength );
status = mbedtls_psa_cipher_finish(
&operation,
mbedtls_buffer_offset( output, accumulated_length ),
output_size - accumulated_length, &olength );
if( status != PSA_SUCCESS )
goto exit;

View File

@ -183,6 +183,24 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number(
}
#endif
/** Get the description of a key given its identifier and policy constraints
* and lock it.
*
* The key must have allow all the usage flags set in \p usage. If \p alg is
* nonzero, the key must allow operations with this algorithm. If \p alg is
* zero, the algorithm is not checked.
*
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* On success, the returned key slot is locked. It is the responsibility of
* the caller to unlock the key slot when it does not access it anymore.
*/
psa_status_t psa_get_and_lock_key_slot_with_policy( mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot,
psa_key_usage_t usage,
psa_algorithm_t alg );
/** Completely wipe a slot in memory, including its policy.
*
* Persistent storage is not affected.
@ -531,4 +549,62 @@ psa_status_t psa_verify_hash_builtin(
*/
psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type,
size_t bits );
/** Perform a key agreement and return the raw shared secret, using
built-in raw key agreement functions.
*
* \note The signature of this function is that of a PSA driver
* key_agreement entry point. This function behaves as a key_agreement
* entry point as defined in the PSA driver interface specification for
* transparent drivers.
*
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The buffer containing the private key
* context.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in
* bytes.
* \param[in] alg A key agreement algorithm that is
* compatible with the type of the key.
* \param[in] peer_key The buffer containing the key context
* of the peer's public key.
* \param[in] peer_key_length Size of the \p peer_key buffer in
* bytes.
* \param[out] shared_secret The buffer to which the shared secret
* is to be written.
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
* bytes.
* \param[out] shared_secret_length On success, the number of bytes that make
* up the returned shared secret.
* \retval #PSA_SUCCESS
* Success. Shared secret successfully calculated.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p alg is not a key agreement algorithm, or
* \p private_key is not compatible with \p alg,
* or \p peer_key is not valid for \p alg or not compatible with
* \p private_key.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p shared_secret_size is too small
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not a supported key agreement algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
*/
psa_status_t psa_key_agreement_raw_builtin(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *shared_secret,
size_t shared_secret_size,
size_t *shared_secret_length );
#endif /* PSA_CRYPTO_CORE_H */

View File

@ -357,6 +357,20 @@ psa_status_t psa_driver_wrapper_asymmetric_decrypt(
size_t output_size,
size_t *output_length );
/*
* Raw Key Agreement
*/
psa_status_t psa_driver_wrapper_key_agreement(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *shared_secret,
size_t shared_secret_size,
size_t *shared_secret_length );
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
/* End of automatically generated file. */

View File

@ -33,6 +33,7 @@
#include "mbedtls/platform.h"
#include <mbedtls/ecdsa.h>
#include <mbedtls/ecdh.h>
#include <mbedtls/ecp.h>
#include <mbedtls/error.h>
@ -464,4 +465,76 @@ cleanup:
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
/****************************************************************/
/* ECDH Key Agreement */
/****************************************************************/
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
psa_status_t mbedtls_psa_key_agreement_ecdh(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
uint8_t *shared_secret, size_t shared_secret_size,
size_t *shared_secret_length )
{
psa_status_t status;
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( attributes->core.type ) ||
! PSA_ALG_IS_ECDH(alg) )
return( PSA_ERROR_INVALID_ARGUMENT );
mbedtls_ecp_keypair *ecp = NULL;
status = mbedtls_psa_ecp_load_representation(
attributes->core.type,
attributes->core.bits,
key_buffer,
key_buffer_size,
&ecp );
if( status != PSA_SUCCESS )
return( status );
mbedtls_ecp_keypair *their_key = NULL;
mbedtls_ecdh_context ecdh;
size_t bits = 0;
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( ecp->grp.id, &bits );
mbedtls_ecdh_init( &ecdh );
status = mbedtls_psa_ecp_load_representation(
PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
bits,
peer_key,
peer_key_length,
&their_key );
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_to_psa_error(
mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_to_psa_error(
mbedtls_ecdh_get_params( &ecdh, ecp, MBEDTLS_ECDH_OURS ) );
if( status != PSA_SUCCESS )
goto exit;
status = mbedtls_to_psa_error(
mbedtls_ecdh_calc_secret( &ecdh,
shared_secret_length,
shared_secret, shared_secret_size,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE ) );
if( status != PSA_SUCCESS )
goto exit;
if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
status = PSA_ERROR_CORRUPTION_DETECTED;
exit:
if( status != PSA_SUCCESS )
mbedtls_platform_zeroize( shared_secret, shared_secret_size );
mbedtls_ecdh_free( &ecdh );
mbedtls_ecp_keypair_free( their_key );
mbedtls_free( their_key );
mbedtls_ecp_keypair_free( ecp );
mbedtls_free( ecp );
return( status );
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
#endif /* MBEDTLS_PSA_CRYPTO_C */

View File

@ -218,4 +218,53 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash(
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length );
/** Perform a key agreement and return the raw ECDH shared secret.
*
* \note The signature of this function is that of a PSA driver
* key_agreement entry point. This function behaves as a key_agreement
* entry point as defined in the PSA driver interface specification for
* transparent drivers.
*
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The buffer containing the private key
* context.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in
* bytes.
* \param[in] alg A key agreement algorithm that is
* compatible with the type of the key.
* \param[in] peer_key The buffer containing the key context
* of the peer's public key.
* \param[in] peer_key_length Size of the \p peer_key buffer in
* bytes.
* \param[out] shared_secret The buffer to which the shared secret
* is to be written.
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
* bytes.
* \param[out] shared_secret_length On success, the number of bytes that make
* up the returned shared secret.
* \retval #PSA_SUCCESS
* Success. Shared secret successfully calculated.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p alg is not a key agreement algorithm, or
* \p private_key is not compatible with \p alg,
* or \p peer_key is not valid for \p alg or not compatible with
* \p private_key.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p shared_secret_size is too small
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not a supported key agreement algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
*/
psa_status_t mbedtls_psa_key_agreement_ecdh(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
uint8_t *shared_secret, size_t shared_secret_size,
size_t *shared_secret_length );
#endif /* PSA_CRYPTO_ECP_H */

View File

@ -197,9 +197,14 @@ static psa_status_t mbedtls_ecjpake_to_psa_error( int ret )
psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
const psa_pake_cipher_suite_t *cipher_suite)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
/* A context must be freshly initialized before it can be set up. */
if( operation->alg != PSA_ALG_NONE )
return( PSA_ERROR_BAD_STATE );
{
status = PSA_ERROR_BAD_STATE;
goto error;
}
if( cipher_suite == NULL ||
PSA_ALG_IS_PAKE(cipher_suite->algorithm ) == 0 ||
@ -207,7 +212,8 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_DH ) ||
PSA_ALG_IS_HASH( cipher_suite->hash ) == 0 )
{
return( PSA_ERROR_INVALID_ARGUMENT );
status = PSA_ERROR_INVALID_ARGUMENT;
goto error;
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
@ -218,7 +224,8 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
cipher_suite->bits != 256 ||
cipher_suite->hash != PSA_ALG_SHA_256 )
{
return( PSA_ERROR_NOT_SUPPORTED );
status = PSA_ERROR_NOT_SUPPORTED;
goto error;
}
operation->alg = cipher_suite->algorithm;
@ -238,7 +245,11 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
}
else
#endif
return( PSA_ERROR_NOT_SUPPORTED );
status = PSA_ERROR_NOT_SUPPORTED;
error:
psa_pake_abort( operation );
return status;
}
psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
@ -248,16 +259,18 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
psa_key_attributes_t attributes = psa_key_attributes_init();
psa_key_type_t type;
psa_key_usage_t usage;
psa_key_slot_t *slot = NULL;
if( operation->alg == PSA_ALG_NONE ||
operation->state != PSA_PAKE_STATE_SETUP )
{
return( PSA_ERROR_BAD_STATE );
status = PSA_ERROR_BAD_STATE;
goto error;
}
status = psa_get_key_attributes( password, &attributes );
if( status != PSA_SUCCESS )
return( status );
goto error;
type = psa_get_key_type( &attributes );
usage = psa_get_key_usage_flags( &attributes );
@ -267,56 +280,106 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
if( type != PSA_KEY_TYPE_PASSWORD &&
type != PSA_KEY_TYPE_PASSWORD_HASH )
{
return( PSA_ERROR_INVALID_ARGUMENT );
status = PSA_ERROR_INVALID_ARGUMENT;
goto error;
}
if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 )
return( PSA_ERROR_NOT_PERMITTED );
if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 ) {
status = PSA_ERROR_NOT_PERMITTED;
goto error;
}
operation->password = password;
if( operation->password != NULL )
return( PSA_ERROR_BAD_STATE );
status = psa_get_and_lock_key_slot_with_policy( password, &slot,
PSA_KEY_USAGE_DERIVE,
PSA_ALG_JPAKE );
if( status != PSA_SUCCESS )
return( status );
operation->password = mbedtls_calloc( 1, slot->key.bytes );
if( operation->password == NULL )
{
psa_unlock_key_slot( slot );
return( PSA_ERROR_INSUFFICIENT_MEMORY );
}
memcpy( operation->password, slot->key.data, slot->key.bytes );
operation->password_len = slot->key.bytes;
status = psa_unlock_key_slot( slot );
if( status != PSA_SUCCESS )
return( status );
return( PSA_SUCCESS );
error:
psa_pake_abort(operation);
return( status );
}
psa_status_t psa_pake_set_user( psa_pake_operation_t *operation,
const uint8_t *user_id,
size_t user_id_len )
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if( operation->alg == PSA_ALG_NONE ||
operation->state != PSA_PAKE_STATE_SETUP )
{
return( PSA_ERROR_BAD_STATE );
status = PSA_ERROR_BAD_STATE;
goto error;
}
if( user_id_len == 0 || user_id == NULL )
return( PSA_ERROR_INVALID_ARGUMENT );
{
status = PSA_ERROR_INVALID_ARGUMENT;
goto error;
}
return( PSA_ERROR_NOT_SUPPORTED );
status = PSA_ERROR_NOT_SUPPORTED;
error:
psa_pake_abort(operation);
return( status );
}
psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation,
const uint8_t *peer_id,
size_t peer_id_len )
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if( operation->alg == PSA_ALG_NONE ||
operation->state != PSA_PAKE_STATE_SETUP )
{
return( PSA_ERROR_BAD_STATE );
status = PSA_ERROR_BAD_STATE;
goto error;
}
if( peer_id_len == 0 || peer_id == NULL )
return( PSA_ERROR_INVALID_ARGUMENT );
{
status = PSA_ERROR_INVALID_ARGUMENT;
goto error;
}
return( PSA_ERROR_NOT_SUPPORTED );
status = PSA_ERROR_NOT_SUPPORTED;
error:
psa_pake_abort(operation);
return( status );
}
psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
psa_pake_role_t role )
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if( operation->alg == PSA_ALG_NONE ||
operation->state != PSA_PAKE_STATE_SETUP )
{
return( PSA_ERROR_BAD_STATE );
status = PSA_ERROR_BAD_STATE;
goto error;
}
if( role != PSA_PAKE_ROLE_NONE &&
@ -325,7 +388,8 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
role != PSA_PAKE_ROLE_CLIENT &&
role != PSA_PAKE_ROLE_SERVER )
{
return( PSA_ERROR_INVALID_ARGUMENT );
status = PSA_ERROR_INVALID_ARGUMENT;
goto error;
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
@ -341,16 +405,18 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
}
else
#endif
return( PSA_ERROR_NOT_SUPPORTED );
status = PSA_ERROR_NOT_SUPPORTED;
error:
psa_pake_abort(operation);
return( status );
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_ecjpake_role role;
psa_key_slot_t *slot = NULL;
if( operation->role == PSA_PAKE_ROLE_CLIENT )
role = MBEDTLS_ECJPAKE_CLIENT;
@ -359,22 +425,20 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
else
return( PSA_ERROR_BAD_STATE );
if( psa_is_valid_key_id( operation->password, 1 ) == 0 )
if( operation->password_len == 0 )
return( PSA_ERROR_BAD_STATE );
status = psa_get_and_lock_key_slot( operation->password, &slot );
if( status != PSA_SUCCESS )
return( status );
ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake,
role,
MBEDTLS_MD_SHA256,
MBEDTLS_ECP_DP_SECP256R1,
slot->key.data, slot->key.bytes );
operation->password,
operation->password_len );
psa_unlock_key_slot( slot );
slot = NULL;
mbedtls_platform_zeroize( operation->password, operation->password_len );
mbedtls_free( operation->password );
operation->password = NULL;
operation->password_len = 0;
if( ret != 0 )
return( mbedtls_ecjpake_to_psa_error( ret ) );
@ -795,7 +859,10 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
operation->state != PSA_PAKE_STATE_READY ||
operation->input_step != PSA_PAKE_STEP_DERIVE ||
operation->output_step != PSA_PAKE_STEP_DERIVE )
return( PSA_ERROR_BAD_STATE );
{
status = PSA_ERROR_BAD_STATE;
goto error;
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
if( operation->alg == PSA_ALG_JPAKE )
@ -825,7 +892,13 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
}
else
#endif
return( PSA_ERROR_NOT_SUPPORTED );
status = PSA_ERROR_NOT_SUPPORTED;
error:
psa_key_derivation_abort( output );
psa_pake_abort( operation );
return( status );
}
psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
@ -840,7 +913,11 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
{
operation->input_step = PSA_PAKE_STEP_INVALID;
operation->output_step = PSA_PAKE_STEP_INVALID;
operation->password = MBEDTLS_SVC_KEY_ID_INIT;
if( operation->password_len > 0 )
mbedtls_platform_zeroize( operation->password, operation->password_len );
mbedtls_free( operation->password );
operation->password = NULL;
operation->password_len = 0;
operation->role = PSA_PAKE_ROLE_NONE;
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;

View File

@ -106,6 +106,9 @@ static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
*olen = hostname_len + 9;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_SERVERNAME );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
@ -177,6 +180,9 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
/* Extension length = *out_len - 2 (ext_type) - 2 (ext_len) */
MBEDTLS_PUT_UINT16_BE( *out_len - 4, buf, 2 );
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_ALPN );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */
@ -296,7 +302,8 @@ static int ssl_write_supported_groups_ext( mbedtls_ssl_context *ssl,
*out_len = p - buf;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_SUPPORTED_GROUPS );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
@ -557,7 +564,7 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* Keeping track of the included extensions */
handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
#endif
/* First write extensions, then the total length */
@ -667,6 +674,11 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
p_extensions_len, extensions_len );
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_CLIENT_HELLO, handshake->sent_extensions );
#endif
*out_len = p - buf;
return( 0 );
}

View File

@ -43,6 +43,32 @@ const char *mbedtls_ssl_sig_alg_to_str( uint16_t in );
const char *mbedtls_ssl_named_group_to_str( uint16_t in );
const char *mbedtls_ssl_get_extension_name( unsigned int extension_type );
void mbedtls_ssl_print_extensions( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, uint32_t extensions_mask,
const char *extra );
void mbedtls_ssl_print_extension( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, unsigned int extension_type,
const char *extra_msg0, const char *extra_msg1 );
#define MBEDTLS_SSL_PRINT_EXTS( level, hs_msg_type, extensions_mask ) \
mbedtls_ssl_print_extensions( ssl, level, __FILE__, __LINE__, \
hs_msg_type, extensions_mask, NULL )
#define MBEDTLS_SSL_PRINT_EXT( level, hs_msg_type, extension_type, extra ) \
mbedtls_ssl_print_extension( ssl, level, __FILE__, __LINE__, \
hs_msg_type, extension_type, \
extra, NULL )
#else
#define MBEDTLS_SSL_PRINT_EXTS( level, hs_msg_type, extension_mask )
#define MBEDTLS_SSL_PRINT_EXT( level, hs_msg_type, extension_type, extra )
#endif /* MBEDTLS_DEBUG_C */
#endif /* SSL_DEBUG_HELPERS_H */
#endif /* MBEDTLS_SSL_DEBUG_HELPERS_H */

View File

@ -50,17 +50,13 @@
#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
!defined(MBEDTLS_USE_PSA_CRYPTO)
#include "mbedtls/ecjpake.h"
#endif
#include "common.h"
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/* Shorthand for restartable ECC */
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
defined(MBEDTLS_SSL_CLI_C) && \
@ -74,34 +70,147 @@
#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */
#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */
/*
* Mask of TLS 1.3 handshake extensions used in extensions_present
* of mbedtls_ssl_handshake_params.
*/
#define MBEDTLS_SSL_EXT_NONE 0
/* Faked handshake message identity for HelloRetryRequest. */
#define MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST ( -MBEDTLS_SSL_HS_SERVER_HELLO )
#define MBEDTLS_SSL_EXT_SERVERNAME ( 1 << 0 )
#define MBEDTLS_SSL_EXT_MAX_FRAGMENT_LENGTH ( 1 << 1 )
#define MBEDTLS_SSL_EXT_STATUS_REQUEST ( 1 << 2 )
#define MBEDTLS_SSL_EXT_SUPPORTED_GROUPS ( 1 << 3 )
#define MBEDTLS_SSL_EXT_SIG_ALG ( 1 << 4 )
#define MBEDTLS_SSL_EXT_USE_SRTP ( 1 << 5 )
#define MBEDTLS_SSL_EXT_HEARTBEAT ( 1 << 6 )
#define MBEDTLS_SSL_EXT_ALPN ( 1 << 7 )
#define MBEDTLS_SSL_EXT_SCT ( 1 << 8 )
#define MBEDTLS_SSL_EXT_CLI_CERT_TYPE ( 1 << 9 )
#define MBEDTLS_SSL_EXT_SERV_CERT_TYPE ( 1 << 10 )
#define MBEDTLS_SSL_EXT_PADDING ( 1 << 11 )
#define MBEDTLS_SSL_EXT_PRE_SHARED_KEY ( 1 << 12 )
#define MBEDTLS_SSL_EXT_EARLY_DATA ( 1 << 13 )
#define MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS ( 1 << 14 )
#define MBEDTLS_SSL_EXT_COOKIE ( 1 << 15 )
#define MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ( 1 << 16 )
#define MBEDTLS_SSL_EXT_CERT_AUTH ( 1 << 17 )
#define MBEDTLS_SSL_EXT_OID_FILTERS ( 1 << 18 )
#define MBEDTLS_SSL_EXT_POST_HANDSHAKE_AUTH ( 1 << 19 )
#define MBEDTLS_SSL_EXT_SIG_ALG_CERT ( 1 << 20 )
#define MBEDTLS_SSL_EXT_KEY_SHARE ( 1 << 21 )
/*
* Internal identity of handshake extensions
*/
#define MBEDTLS_SSL_EXT_ID_UNRECOGNIZED 0
#define MBEDTLS_SSL_EXT_ID_SERVERNAME 1
#define MBEDTLS_SSL_EXT_ID_SERVERNAME_HOSTNAME 1
#define MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH 2
#define MBEDTLS_SSL_EXT_ID_STATUS_REQUEST 3
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS 4
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_ELLIPTIC_CURVES 4
#define MBEDTLS_SSL_EXT_ID_SIG_ALG 5
#define MBEDTLS_SSL_EXT_ID_USE_SRTP 6
#define MBEDTLS_SSL_EXT_ID_HEARTBEAT 7
#define MBEDTLS_SSL_EXT_ID_ALPN 8
#define MBEDTLS_SSL_EXT_ID_SCT 9
#define MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE 10
#define MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE 11
#define MBEDTLS_SSL_EXT_ID_PADDING 12
#define MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY 13
#define MBEDTLS_SSL_EXT_ID_EARLY_DATA 14
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS 15
#define MBEDTLS_SSL_EXT_ID_COOKIE 16
#define MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES 17
#define MBEDTLS_SSL_EXT_ID_CERT_AUTH 18
#define MBEDTLS_SSL_EXT_ID_OID_FILTERS 19
#define MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH 20
#define MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT 21
#define MBEDTLS_SSL_EXT_ID_KEY_SHARE 22
#define MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC 23
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS 24
#define MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC 25
#define MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET 26
#define MBEDTLS_SSL_EXT_ID_SESSION_TICKET 27
/* Utility for translating IANA extension type. */
uint32_t mbedtls_ssl_get_extension_id( unsigned int extension_type );
uint32_t mbedtls_ssl_get_extension_mask( unsigned int extension_type );
/* Macros used to define mask constants */
#define MBEDTLS_SSL_EXT_MASK( id ) ( 1ULL << ( MBEDTLS_SSL_EXT_ID_##id ) )
/* Reset value of extension mask */
#define MBEDTLS_SSL_EXT_MASK_NONE 0
/* In messages containing extension requests, we should ignore unrecognized
* extensions. In messages containing extension responses, unrecognized
* extensions should result in handshake abortion. Messages containing
* extension requests include ClientHello, CertificateRequest and
* NewSessionTicket. Messages containing extension responses include
* ServerHello, HelloRetryRequest, EncryptedExtensions and Certificate.
*
* RFC 8446 section 4.1.3
*
* The ServerHello MUST only include extensions which are required to establish
* the cryptographic context and negotiate the protocol version.
*
* RFC 8446 section 4.2
*
* If an implementation receives an extension which it recognizes and which is
* not specified for the message in which it appears, it MUST abort the handshake
* with an "illegal_parameter" alert.
*/
/* Extensions that are not recognized by TLS 1.3 */
#define MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED \
( MBEDTLS_SSL_EXT_MASK( SUPPORTED_POINT_FORMATS ) | \
MBEDTLS_SSL_EXT_MASK( ENCRYPT_THEN_MAC ) | \
MBEDTLS_SSL_EXT_MASK( EXTENDED_MASTER_SECRET ) | \
MBEDTLS_SSL_EXT_MASK( SESSION_TICKET ) | \
MBEDTLS_SSL_EXT_MASK( TRUNCATED_HMAC ) | \
MBEDTLS_SSL_EXT_MASK( UNRECOGNIZED ) )
/* RFC 8446 section 4.2. Allowed extensions for ClienHello */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH \
( MBEDTLS_SSL_EXT_MASK( SERVERNAME ) | \
MBEDTLS_SSL_EXT_MASK( MAX_FRAGMENT_LENGTH ) | \
MBEDTLS_SSL_EXT_MASK( STATUS_REQUEST ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG ) | \
MBEDTLS_SSL_EXT_MASK( USE_SRTP ) | \
MBEDTLS_SSL_EXT_MASK( HEARTBEAT ) | \
MBEDTLS_SSL_EXT_MASK( ALPN ) | \
MBEDTLS_SSL_EXT_MASK( SCT ) | \
MBEDTLS_SSL_EXT_MASK( CLI_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( SERV_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( PADDING ) | \
MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) | \
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | \
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) | \
MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) | \
MBEDTLS_SSL_EXT_MASK( COOKIE ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_VERSIONS ) | \
MBEDTLS_SSL_EXT_MASK( CERT_AUTH ) | \
MBEDTLS_SSL_EXT_MASK( POST_HANDSHAKE_AUTH ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG_CERT ) | \
MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED )
/* RFC 8446 section 4.2. Allowed extensions for EncryptedExtensions */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE \
( MBEDTLS_SSL_EXT_MASK( SERVERNAME ) | \
MBEDTLS_SSL_EXT_MASK( MAX_FRAGMENT_LENGTH ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) | \
MBEDTLS_SSL_EXT_MASK( USE_SRTP ) | \
MBEDTLS_SSL_EXT_MASK( HEARTBEAT ) | \
MBEDTLS_SSL_EXT_MASK( ALPN ) | \
MBEDTLS_SSL_EXT_MASK( CLI_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( SERV_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) )
/* RFC 8446 section 4.2. Allowed extensions for CertificateRequest */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR \
( MBEDTLS_SSL_EXT_MASK( STATUS_REQUEST ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG ) | \
MBEDTLS_SSL_EXT_MASK( SCT ) | \
MBEDTLS_SSL_EXT_MASK( CERT_AUTH ) | \
MBEDTLS_SSL_EXT_MASK( OID_FILTERS ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG_CERT ) | \
MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED )
/* RFC 8446 section 4.2. Allowed extensions for Certificate */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CT \
( MBEDTLS_SSL_EXT_MASK( STATUS_REQUEST ) | \
MBEDTLS_SSL_EXT_MASK( SCT ) )
/* RFC 8446 section 4.2. Allowed extensions for ServerHello */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH \
( MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) | \
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_VERSIONS ) )
/* RFC 8446 section 4.2. Allowed extensions for HelloRetryRequest */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR \
( MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) | \
MBEDTLS_SSL_EXT_MASK( COOKIE ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_VERSIONS ) )
/* RFC 8446 section 4.2. Allowed extensions for NewSessionTicket */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST \
( MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) | \
MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED )
/*
* Helper macros for function call with return check.
@ -663,7 +772,13 @@ struct mbedtls_ssl_handshake_params
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_pake_operation_t psa_pake_ctx; /*!< EC J-PAKE key exchange */
mbedtls_svc_key_id_t psa_pake_password;
uint8_t psa_pake_ctx_is_ok;
#else
mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SSL_CLI_C)
unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */
size_t ecjpake_cache_len; /*!< Length of cached data */
@ -775,13 +890,6 @@ struct mbedtls_ssl_handshake_params
uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/*! TLS 1.3 transforms for 0-RTT and encrypted handshake messages.
* Those pointers own the transforms they reference. */
mbedtls_ssl_transform *transform_handshake;
mbedtls_ssl_transform *transform_earlydata;
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
/*
* Checksum contexts
*/
@ -858,15 +966,16 @@ struct mbedtls_ssl_handshake_params
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
int extensions_present; /*!< extension presence; Each bitfield
represents an extension and defined
as \c MBEDTLS_SSL_EXT_XXX */
uint32_t sent_extensions; /*!< extensions sent by endpoint */
uint32_t received_extensions; /*!< extensions received by endpoint */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
unsigned char certificate_request_context_len;
unsigned char *certificate_request_context;
#endif
/** TLS 1.3 transform for encrypted handshake messages. */
mbedtls_ssl_transform *transform_handshake;
union
{
unsigned char early [MBEDTLS_TLS1_3_MD_MAX_SIZE];
@ -875,6 +984,11 @@ struct mbedtls_ssl_handshake_params
} tls13_master_secrets;
mbedtls_ssl_tls13_handshake_secrets tls13_hs_secrets;
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_tls13_early_secrets tls13_early_secrets;
/** TLS 1.3 transform for early data and handshake messages. */
mbedtls_ssl_transform *transform_earlydata;
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@ -1838,6 +1952,24 @@ static inline int mbedtls_ssl_tls13_some_psk_enabled( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_SRV_C &&
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
/*
* Helper functions for extensions checking.
*/
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_tls13_check_received_extension(
mbedtls_ssl_context *ssl,
int hs_msg_type,
unsigned int received_extension_type,
uint32_t hs_msg_allowed_extensions_mask );
static inline void mbedtls_ssl_tls13_set_hs_sent_ext_mask(
mbedtls_ssl_context *ssl, unsigned int extension_type )
{
ssl->handshake->sent_extensions |=
mbedtls_ssl_get_extension_mask( extension_type );
}
/*
* Helper functions to check the selected key exchange mode.
*/
@ -1916,6 +2048,12 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
size_t *out_len );
#endif /* MBEDTLS_ECDH_C */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_tls13_write_early_data_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len );
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
@ -2357,6 +2495,52 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status )
}
#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
typedef enum {
MBEDTLS_ECJPAKE_ROUND_ONE,
MBEDTLS_ECJPAKE_ROUND_TWO
} mbedtls_ecjpake_rounds_t;
/**
* \brief Parse the provided input buffer for getting the first round
* of key exchange. This code is common between server and client
*
* \param pake_ctx [in] the PAKE's operation/context structure
* \param buf [in] input buffer to parse
* \param len [in] length of the input buffer
* \param round [in] either MBEDTLS_ECJPAKE_ROUND_ONE or
* MBEDTLS_ECJPAKE_ROUND_TWO
*
* \return 0 on success or a negative error code in case of failure
*/
int mbedtls_psa_ecjpake_read_round(
psa_pake_operation_t *pake_ctx,
const unsigned char *buf,
size_t len, mbedtls_ecjpake_rounds_t round );
/**
* \brief Write the first round of key exchange into the provided output
* buffer. This code is common between server and client
*
* \param pake_ctx [in] the PAKE's operation/context structure
* \param buf [out] the output buffer in which data will be written to
* \param len [in] length of the output buffer
* \param olen [out] the length of the data really written on the buffer
* \param round [in] either MBEDTLS_ECJPAKE_ROUND_ONE or
* MBEDTLS_ECJPAKE_ROUND_TWO
*
* \return 0 on success or a negative error code in case of failure
*/
int mbedtls_psa_ecjpake_write_round(
psa_pake_operation_t *pake_ctx,
unsigned char *buf,
size_t len, size_t *olen,
mbedtls_ecjpake_rounds_t round );
#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO
/**
* \brief TLS record protection modes
*/

View File

@ -382,30 +382,80 @@ static int ssl_parse_inner_plaintext( unsigned char const *content,
}
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */
/* `add_data` must have size 13 Bytes if the CID extension is disabled,
* and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
/* The size of the `add_data` structure depends on various
* factors, namely
*
* 1) CID functionality disabled
*
* additional_data =
* 8: seq_num +
* 1: type +
* 2: version +
* 2: length of inner plaintext +
*
* size = 13 bytes
*
* 2) CID functionality based on RFC 9146 enabled
*
* size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length
* = 23 + CID-length
*
* 3) CID functionality based on legacy CID version
according to draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* size = 13 + 1 + CID-length
*
* More information about the CID usage:
*
* Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the
* size of the additional data structure is calculated as:
*
* additional_data =
* 8: seq_num +
* 1: tls12_cid +
* 2: DTLSCipherText.version +
* n: cid +
* 1: cid_length +
* 2: length_of_DTLSInnerPlaintext
*
* Per RFC 9146 the size of the add_data structure is calculated as:
*
* additional_data =
* 8: seq_num_placeholder +
* 1: tls12_cid +
* 1: cid_length +
* 1: tls12_cid +
* 2: DTLSCiphertext.version +
* 2: epoch +
* 6: sequence_number +
* n: cid +
* 2: length_of_DTLSInnerPlaintext
*
*/
static void ssl_extract_add_data_from_record( unsigned char* add_data,
size_t *add_data_len,
mbedtls_record *rec,
mbedtls_ssl_protocol_version
tls_version,
tls_version,
size_t taglen )
{
/* Quoting RFC 5246 (TLS 1.2):
/* Several types of ciphers have been defined for use with TLS and DTLS,
* and the MAC calculations for those ciphers differ slightly. Further
* variants were added when the CID functionality was added with RFC 9146.
* This implementations also considers the use of a legacy version of the
* CID specification published in draft-ietf-tls-dtls-connection-id-05,
* which is used in deployments.
*
* We will distinguish between the non-CID and the CID cases below.
*
* --- Non-CID cases ---
*
* Quoting RFC 5246 (TLS 1.2):
*
* additional_data = seq_num + TLSCompressed.type +
* TLSCompressed.version + TLSCompressed.length;
*
* For the CID extension, this is extended as follows
* (quoting draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
*
* additional_data = seq_num + DTLSPlaintext.type +
* DTLSPlaintext.version +
* cid +
* cid_length +
* length_of_DTLSInnerPlaintext;
*
* For TLS 1.3, the record sequence number is dropped from the AAD
* and encoded within the nonce of the AEAD operation instead.
* Moreover, the additional data involves the length of the TLS
@ -421,11 +471,72 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data,
*
* TLSCiphertext.length = TLSInnerPlaintext.length + taglen.
*
*/
* --- CID cases ---
*
* RFC 9146 uses a common pattern when constructing the data
* passed into a MAC / AEAD cipher.
*
* Data concatenation for MACs used with block ciphers with
* Encrypt-then-MAC Processing (with CID):
*
* data = seq_num_placeholder +
* tls12_cid +
* cid_length +
* tls12_cid +
* DTLSCiphertext.version +
* epoch +
* sequence_number +
* cid +
* DTLSCiphertext.length +
* IV +
* ENC(content + padding + padding_length)
*
* Data concatenation for MACs used with block ciphers (with CID):
*
* data = seq_num_placeholder +
* tls12_cid +
* cid_length +
* tls12_cid +
* DTLSCiphertext.version +
* epoch +
* sequence_number +
* cid +
* length_of_DTLSInnerPlaintext +
* DTLSInnerPlaintext.content +
* DTLSInnerPlaintext.real_type +
* DTLSInnerPlaintext.zeros
*
* AEAD ciphers use the following additional data calculation (with CIDs):
*
* additional_data = seq_num_placeholder +
* tls12_cid +
* cid_length +
* tls12_cid +
* DTLSCiphertext.version +
* epoch +
* sequence_number +
* cid +
* length_of_DTLSInnerPlaintext
*
* Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use)
* defines the additional data calculation as follows:
*
* additional_data = seq_num +
* tls12_cid +
* DTLSCipherText.version +
* cid +
* cid_length +
* length_of_DTLSInnerPlaintext
*/
unsigned char *cur = add_data;
size_t ad_len_field = rec->data_len;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if( tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
{
@ -439,25 +550,72 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data,
{
((void) tls_version);
((void) taglen);
memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
cur += sizeof( rec->ctr );
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
if( rec->cid_len != 0 )
{
// seq_num_placeholder
memcpy( cur, seq_num_placeholder, sizeof(seq_num_placeholder) );
cur += sizeof( seq_num_placeholder );
// tls12_cid type
*cur = rec->type;
cur++;
// cid_length
*cur = rec->cid_len;
cur++;
}
else
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
{
// epoch + sequence number
memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
cur += sizeof( rec->ctr );
}
}
// type
*cur = rec->type;
cur++;
// version
memcpy( cur, rec->ver, sizeof( rec->ver ) );
cur += sizeof( rec->ver );
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
if( rec->cid_len != 0 )
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1
if (rec->cid_len != 0)
{
memcpy( cur, rec->cid, rec->cid_len );
// CID
memcpy(cur, rec->cid, rec->cid_len);
cur += rec->cid_len;
// cid_length
*cur = rec->cid_len;
cur++;
// length of inner plaintext
MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
cur += 2;
}
else
#elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
if( rec->cid_len != 0 )
{
// epoch + sequence number
memcpy(cur, rec->ctr, sizeof(rec->ctr));
cur += sizeof(rec->ctr);
// CID
memcpy( cur, rec->cid, rec->cid_len );
cur += rec->cid_len;
// length of inner plaintext
MBEDTLS_PUT_UINT16_BE( ad_len_field, cur, 0 );
cur += 2;
}
@ -532,7 +690,14 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
mbedtls_ssl_mode_t ssl_mode;
int auth_done = 0;
unsigned char * data;
unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
/* For an explanation of the additional data length see
* the descrpition of ssl_extract_add_data_from_record().
*/
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX];
#else
unsigned char add_data[13];
#endif
size_t add_data_len;
size_t post_avail;
@ -1015,13 +1180,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
size_t sign_mac_length = 0;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
* MAC(MAC_write_key, seq_num +
* TLSCipherText.type +
* TLSCipherText.version +
* length_of( (IV +) ENC(...) ) +
* IV +
* ENC(content + padding + padding_length));
/* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length))
*/
if( post_avail < transform->maclen)
@ -1129,7 +1288,14 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
size_t padlen = 0, correct = 1;
#endif
unsigned char* data;
unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
/* For an explanation of the additional data length see
* the descrpition of ssl_extract_add_data_from_record().
*/
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX];
#else
unsigned char add_data[13];
#endif
size_t add_data_len;
#if !defined(MBEDTLS_DEBUG_C)
@ -1797,8 +1963,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
"or mbedtls_ssl_set_bio()" ) );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
@ -1908,7 +2073,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
mbedtls_ssl_set_timer( ssl, 0 );
if( mbedtls_ssl_is_handshake_over( ssl ) == 0 )
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
if( ssl_double_retransmit_timeout( ssl ) != 0 )
{
@ -2013,8 +2178,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
if( ssl->f_send == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
"or mbedtls_ssl_set_bio()" ) );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
@ -3483,7 +3647,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
{
/* Shift pointers to account for record header including CID
* struct {
* ContentType special_type = tls12_cid;
* ContentType outer_type = tls12_cid;
* ProtocolVersion version;
* uint16 epoch;
* uint48 sequence_number;
@ -5301,7 +5465,7 @@ static int ssl_tls13_check_new_session_ticket( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "NewSessionTicket received" ) );
mbedtls_ssl_handshake_set_state( ssl,
MBEDTLS_SSL_NEW_SESSION_TICKET );
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET );
return( MBEDTLS_ERR_SSL_WANT_READ );
}
@ -5504,7 +5668,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
}
#endif
if( mbedtls_ssl_is_handshake_over( ssl ) == 0 )
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
ret = mbedtls_ssl_handshake( ssl );
if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
@ -5760,7 +5924,7 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_
}
#endif
if( mbedtls_ssl_is_handshake_over( ssl ) == 0 )
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
{

View File

@ -521,6 +521,245 @@ static void ssl_clear_peer_cert( mbedtls_ssl_session *session )
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
uint32_t mbedtls_ssl_get_extension_id( unsigned int extension_type )
{
switch( extension_type )
{
case MBEDTLS_TLS_EXT_SERVERNAME:
return( MBEDTLS_SSL_EXT_ID_SERVERNAME );
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
return( MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH );
case MBEDTLS_TLS_EXT_STATUS_REQUEST:
return( MBEDTLS_SSL_EXT_ID_STATUS_REQUEST );
case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
return( MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS );
case MBEDTLS_TLS_EXT_SIG_ALG:
return( MBEDTLS_SSL_EXT_ID_SIG_ALG );
case MBEDTLS_TLS_EXT_USE_SRTP:
return( MBEDTLS_SSL_EXT_ID_USE_SRTP );
case MBEDTLS_TLS_EXT_HEARTBEAT:
return( MBEDTLS_SSL_EXT_ID_HEARTBEAT );
case MBEDTLS_TLS_EXT_ALPN:
return( MBEDTLS_SSL_EXT_ID_ALPN );
case MBEDTLS_TLS_EXT_SCT:
return( MBEDTLS_SSL_EXT_ID_SCT );
case MBEDTLS_TLS_EXT_CLI_CERT_TYPE:
return( MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE );
case MBEDTLS_TLS_EXT_SERV_CERT_TYPE:
return( MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE );
case MBEDTLS_TLS_EXT_PADDING:
return( MBEDTLS_SSL_EXT_ID_PADDING );
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
return( MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY );
case MBEDTLS_TLS_EXT_EARLY_DATA:
return( MBEDTLS_SSL_EXT_ID_EARLY_DATA );
case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
return( MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS );
case MBEDTLS_TLS_EXT_COOKIE:
return( MBEDTLS_SSL_EXT_ID_COOKIE );
case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES:
return( MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES );
case MBEDTLS_TLS_EXT_CERT_AUTH:
return( MBEDTLS_SSL_EXT_ID_CERT_AUTH );
case MBEDTLS_TLS_EXT_OID_FILTERS:
return( MBEDTLS_SSL_EXT_ID_OID_FILTERS );
case MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH:
return( MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH );
case MBEDTLS_TLS_EXT_SIG_ALG_CERT:
return( MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT );
case MBEDTLS_TLS_EXT_KEY_SHARE:
return( MBEDTLS_SSL_EXT_ID_KEY_SHARE );
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
return( MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC );
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
return( MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS );
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
return( MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC );
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
return( MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET );
case MBEDTLS_TLS_EXT_SESSION_TICKET:
return( MBEDTLS_SSL_EXT_ID_SESSION_TICKET );
}
return( MBEDTLS_SSL_EXT_ID_UNRECOGNIZED );
}
uint32_t mbedtls_ssl_get_extension_mask( unsigned int extension_type )
{
return( 1 << mbedtls_ssl_get_extension_id( extension_type ) );
}
#if defined(MBEDTLS_DEBUG_C)
static const char *extension_name_table[] = {
[MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = "unrecognized",
[MBEDTLS_SSL_EXT_ID_SERVERNAME] = "server_name",
[MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = "max_fragment_length",
[MBEDTLS_SSL_EXT_ID_STATUS_REQUEST] = "status_request",
[MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS] = "supported_groups",
[MBEDTLS_SSL_EXT_ID_SIG_ALG] = "signature_algorithms",
[MBEDTLS_SSL_EXT_ID_USE_SRTP] = "use_srtp",
[MBEDTLS_SSL_EXT_ID_HEARTBEAT] = "heartbeat",
[MBEDTLS_SSL_EXT_ID_ALPN] = "application_layer_protocol_negotiation",
[MBEDTLS_SSL_EXT_ID_SCT] = "signed_certificate_timestamp",
[MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE] = "client_certificate_type",
[MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE] = "server_certificate_type",
[MBEDTLS_SSL_EXT_ID_PADDING] = "padding",
[MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY] = "pre_shared_key",
[MBEDTLS_SSL_EXT_ID_EARLY_DATA] = "early_data",
[MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS] = "supported_versions",
[MBEDTLS_SSL_EXT_ID_COOKIE] = "cookie",
[MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES] = "psk_key_exchange_modes",
[MBEDTLS_SSL_EXT_ID_CERT_AUTH] = "certificate_authorities",
[MBEDTLS_SSL_EXT_ID_OID_FILTERS] = "oid_filters",
[MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH] = "post_handshake_auth",
[MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT] = "signature_algorithms_cert",
[MBEDTLS_SSL_EXT_ID_KEY_SHARE] = "key_share",
[MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC] = "truncated_hmac",
[MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS] = "supported_point_formats",
[MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC] = "encrypt_then_mac",
[MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET] = "extended_master_secret",
[MBEDTLS_SSL_EXT_ID_SESSION_TICKET] = "session_ticket"
};
static unsigned int extension_type_table[]={
[MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = 0xff,
[MBEDTLS_SSL_EXT_ID_SERVERNAME] = MBEDTLS_TLS_EXT_SERVERNAME,
[MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH,
[MBEDTLS_SSL_EXT_ID_STATUS_REQUEST] = MBEDTLS_TLS_EXT_STATUS_REQUEST,
[MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS] = MBEDTLS_TLS_EXT_SUPPORTED_GROUPS,
[MBEDTLS_SSL_EXT_ID_SIG_ALG] = MBEDTLS_TLS_EXT_SIG_ALG,
[MBEDTLS_SSL_EXT_ID_USE_SRTP] = MBEDTLS_TLS_EXT_USE_SRTP,
[MBEDTLS_SSL_EXT_ID_HEARTBEAT] = MBEDTLS_TLS_EXT_HEARTBEAT,
[MBEDTLS_SSL_EXT_ID_ALPN] = MBEDTLS_TLS_EXT_ALPN,
[MBEDTLS_SSL_EXT_ID_SCT] = MBEDTLS_TLS_EXT_SCT,
[MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE] = MBEDTLS_TLS_EXT_CLI_CERT_TYPE,
[MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE] = MBEDTLS_TLS_EXT_SERV_CERT_TYPE,
[MBEDTLS_SSL_EXT_ID_PADDING] = MBEDTLS_TLS_EXT_PADDING,
[MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY] = MBEDTLS_TLS_EXT_PRE_SHARED_KEY,
[MBEDTLS_SSL_EXT_ID_EARLY_DATA] = MBEDTLS_TLS_EXT_EARLY_DATA,
[MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS] = MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS,
[MBEDTLS_SSL_EXT_ID_COOKIE] = MBEDTLS_TLS_EXT_COOKIE,
[MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES] = MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES,
[MBEDTLS_SSL_EXT_ID_CERT_AUTH] = MBEDTLS_TLS_EXT_CERT_AUTH,
[MBEDTLS_SSL_EXT_ID_OID_FILTERS] = MBEDTLS_TLS_EXT_OID_FILTERS,
[MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH] = MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH,
[MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT] = MBEDTLS_TLS_EXT_SIG_ALG_CERT,
[MBEDTLS_SSL_EXT_ID_KEY_SHARE] = MBEDTLS_TLS_EXT_KEY_SHARE,
[MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC] = MBEDTLS_TLS_EXT_TRUNCATED_HMAC,
[MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS] = MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS,
[MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC] = MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC,
[MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET] = MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET,
[MBEDTLS_SSL_EXT_ID_SESSION_TICKET] = MBEDTLS_TLS_EXT_SESSION_TICKET
};
const char *mbedtls_ssl_get_extension_name( unsigned int extension_type )
{
return( extension_name_table[
mbedtls_ssl_get_extension_id( extension_type ) ] );
}
static const char *ssl_tls13_get_hs_msg_name( int hs_msg_type )
{
switch( hs_msg_type )
{
case MBEDTLS_SSL_HS_CLIENT_HELLO:
return( "ClientHello" );
case MBEDTLS_SSL_HS_SERVER_HELLO:
return( "ServerHello" );
case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:
return( "HelloRetryRequest" );
case MBEDTLS_SSL_HS_NEW_SESSION_TICKET:
return( "NewSessionTicket" );
case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:
return( "EncryptedExtensions" );
case MBEDTLS_SSL_HS_CERTIFICATE:
return( "Certificate" );
case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST:
return( "CertificateRequest" );
}
return( "Unknown" );
}
void mbedtls_ssl_print_extension( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, unsigned int extension_type,
const char *extra_msg0, const char *extra_msg1 )
{
const char *extra_msg;
if( extra_msg0 && extra_msg1 )
{
mbedtls_debug_print_msg(
ssl, level, file, line,
"%s: %s(%u) extension %s %s.",
ssl_tls13_get_hs_msg_name( hs_msg_type ),
mbedtls_ssl_get_extension_name( extension_type ),
extension_type,
extra_msg0, extra_msg1 );
return;
}
extra_msg = extra_msg0 ? extra_msg0 : extra_msg1;
if( extra_msg )
{
mbedtls_debug_print_msg(
ssl, level, file, line,
"%s: %s(%u) extension %s.", ssl_tls13_get_hs_msg_name( hs_msg_type ),
mbedtls_ssl_get_extension_name( extension_type ), extension_type,
extra_msg );
return;
}
mbedtls_debug_print_msg(
ssl, level, file, line,
"%s: %s(%u) extension.", ssl_tls13_get_hs_msg_name( hs_msg_type ),
mbedtls_ssl_get_extension_name( extension_type ), extension_type );
}
void mbedtls_ssl_print_extensions( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, uint32_t extensions_mask,
const char *extra )
{
for( unsigned i = 0;
i < sizeof( extension_name_table ) / sizeof( extension_name_table[0] );
i++ )
{
mbedtls_ssl_print_extension(
ssl, level, file, line, hs_msg_type, extension_type_table[i],
extensions_mask & ( 1 << i ) ? "exists" : "does not exist", extra );
}
}
#endif /* MBEDTLS_DEBUG_C */
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
{
@ -668,7 +907,12 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
mbedtls_ecdh_init( &handshake->ecdh_ctx );
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
handshake->psa_pake_ctx = psa_pake_operation_init();
handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT;
#else
mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SSL_CLI_C)
handshake->ecjpake_cache = NULL;
handshake->ecjpake_cache_len = 0;
@ -1203,9 +1447,11 @@ void mbedtls_ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
if( ssl->handshake != NULL )
{
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_transform_free( ssl->handshake->transform_earlydata );
mbedtls_free( ssl->handshake->transform_earlydata );
ssl->handshake->transform_earlydata = NULL;
#endif
mbedtls_ssl_transform_free( ssl->handshake->transform_handshake );
mbedtls_free( ssl->handshake->transform_handshake );
@ -1611,6 +1857,73 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
/*
* Set EC J-PAKE password for current handshake
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len )
{
psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_pake_role_t psa_role;
psa_status_t status;
if( ssl->handshake == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
psa_role = PSA_PAKE_ROLE_SERVER;
else
psa_role = PSA_PAKE_ROLE_CLIENT;
/* Empty password is not valid */
if( ( pw == NULL) || ( pw_len == 0 ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE );
psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD );
status = psa_import_key( &attributes, pw, pw_len,
&ssl->handshake->psa_pake_password );
if( status != PSA_SUCCESS )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE );
psa_pake_cs_set_primitive( &cipher_suite,
PSA_PAKE_PRIMITIVE( PSA_PAKE_PRIMITIVE_TYPE_ECC,
PSA_ECC_FAMILY_SECP_R1,
256) );
psa_pake_cs_set_hash( &cipher_suite, PSA_ALG_SHA_256 );
status = psa_pake_setup( &ssl->handshake->psa_pake_ctx, &cipher_suite );
if( status != PSA_SUCCESS )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role );
if( status != PSA_SUCCESS )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx,
ssl->handshake->psa_pake_password );
if( status != PSA_SUCCESS )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
ssl->handshake->psa_pake_ctx_is_ok = 1;
return( 0 );
}
#else /* MBEDTLS_USE_PSA_CRYPTO */
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len )
@ -1631,6 +1944,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
MBEDTLS_ECP_DP_SECP256R1,
pw, pw_len ) );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
@ -3363,7 +3677,7 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
if( ssl == NULL ||
ssl->conf == NULL ||
ssl->handshake == NULL ||
mbedtls_ssl_is_handshake_over( ssl ) == 1 )
ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
{
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
@ -3376,6 +3690,10 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
if( ret != 0 )
goto cleanup;
/* If ssl->conf->endpoint is not one of MBEDTLS_SSL_IS_CLIENT or
* MBEDTLS_SSL_IS_SERVER, this is the return code we give */
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
#if defined(MBEDTLS_SSL_CLI_C)
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
{
@ -3386,6 +3704,7 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
{
case MBEDTLS_SSL_HELLO_REQUEST:
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
ret = 0;
break;
case MBEDTLS_SSL_CLIENT_HELLO:
@ -3462,7 +3781,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
/* Main handshake loop */
while( mbedtls_ssl_is_handshake_over( ssl ) == 0 )
while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
ret = mbedtls_ssl_handshake_step( ssl );
@ -3664,8 +3983,15 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_free( &handshake->ecdh_ctx );
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_pake_abort( &handshake->psa_pake_ctx );
psa_destroy_key( handshake->psa_pake_password );
handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT;
#else
mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SSL_CLI_C)
mbedtls_free( handshake->ecjpake_cache );
handshake->ecjpake_cache = NULL;
@ -3743,9 +4069,11 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_transform_free( handshake->transform_handshake );
mbedtls_free( handshake->transform_handshake );
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_transform_free( handshake->transform_earlydata );
mbedtls_free( handshake->transform_earlydata );
mbedtls_free( handshake->transform_handshake );
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
@ -5879,6 +6207,55 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
else
#endif
{
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
psa_status_t status;
psa_algorithm_t alg = PSA_ALG_TLS12_ECJPAKE_TO_PMS;
psa_key_derivation_operation_t derivation =
PSA_KEY_DERIVATION_OPERATION_INIT;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PMS KDF for ECJPAKE" ) );
handshake->pmslen = PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE;
status = psa_key_derivation_setup( &derivation, alg );
if( status != PSA_SUCCESS )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
status = psa_key_derivation_set_capacity( &derivation,
PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE );
if( status != PSA_SUCCESS )
{
psa_key_derivation_abort( &derivation );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_pake_get_implicit_key( &handshake->psa_pake_ctx,
&derivation );
if( status != PSA_SUCCESS )
{
psa_key_derivation_abort( &derivation );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_key_derivation_output_bytes( &derivation,
handshake->premaster,
handshake->pmslen );
if( status != PSA_SUCCESS )
{
psa_key_derivation_abort( &derivation );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_key_derivation_abort( &derivation );
if( status != PSA_SUCCESS )
{
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
}
#endif
ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
lbl, seed, seed_len,
master,
@ -7300,7 +7677,7 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
#endif
mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
ssl->state++;
ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
}
@ -8062,6 +8439,99 @@ end:
return( ret );
}
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_psa_ecjpake_read_round(
psa_pake_operation_t *pake_ctx,
const unsigned char *buf,
size_t len, mbedtls_ecjpake_rounds_t round )
{
psa_status_t status;
size_t input_offset = 0;
/*
* At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice
* At round two perform a single cycle
*/
unsigned int remaining_steps = ( round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1;
for( ; remaining_steps > 0; remaining_steps-- )
{
for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE;
step <= PSA_PAKE_STEP_ZK_PROOF;
++step )
{
/* Length is stored at the first byte */
size_t length = buf[input_offset];
input_offset += 1;
if( input_offset + length > len )
{
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
status = psa_pake_input( pake_ctx, step,
buf + input_offset, length );
if( status != PSA_SUCCESS)
{
return psa_ssl_status_to_mbedtls( status );
}
input_offset += length;
}
}
if( input_offset != len )
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
return( 0 );
}
int mbedtls_psa_ecjpake_write_round(
psa_pake_operation_t *pake_ctx,
unsigned char *buf,
size_t len, size_t *olen,
mbedtls_ecjpake_rounds_t round )
{
psa_status_t status;
size_t output_offset = 0;
size_t output_len;
/*
* At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice
* At round two perform a single cycle
*/
unsigned int remaining_steps = ( round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1;
for( ; remaining_steps > 0; remaining_steps-- )
{
for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE;
step <= PSA_PAKE_STEP_ZK_PROOF;
++step )
{
/*
* For each step, prepend 1 byte with the length of the data as
* given by psa_pake_output().
*/
status = psa_pake_output( pake_ctx, step,
buf + output_offset + 1,
len - output_offset - 1,
&output_len );
if( status != PSA_SUCCESS )
{
return( psa_ssl_status_to_mbedtls( status ) );
}
*(buf + output_offset) = (uint8_t) output_len;
output_offset += output_len + 1;
}
}
*olen = output_offset;
return( 0 );
}
#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *hash, size_t *hashlen,
@ -8620,8 +9090,13 @@ int mbedtls_ssl_validate_ciphersuite(
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_CLI_C)
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
ssl->handshake->psa_pake_ctx_is_ok != 1 )
#else
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
return( -1 );
}
@ -8739,8 +9214,9 @@ int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
*out_len = p - buf;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_SIG_ALG );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
@ -8939,6 +9415,11 @@ int mbedtls_ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
p[6] = MBEDTLS_BYTE_0( protocol_name_len );
memcpy( p + 7, ssl->alpn_chosen, protocol_name_len );
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_ALPN );
#endif
return ( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */

View File

@ -132,13 +132,18 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
size_t kkpp_len;
size_t kkpp_len = 0;
*olen = 0;
/* Skip costly extension if we can't use EC J-PAKE anyway */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ssl->handshake->psa_pake_ctx_is_ok != 1 )
return( 0 );
#else
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
return( 0 );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
MBEDTLS_SSL_DEBUG_MSG( 3,
( "client hello, adding ecjpake_kkpp extension" ) );
@ -158,6 +163,18 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
p + 2, end - p - 2, &kkpp_len,
MBEDTLS_ECJPAKE_ROUND_ONE );
if ( ret != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret );
return( ret );
}
#else
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
@ -167,6 +184,7 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
"mbedtls_ecjpake_write_round_one", ret );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
if( ssl->handshake->ecjpake_cache == NULL )
@ -208,9 +226,6 @@ static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
size_t ext_len;
/*
* Quoting draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* struct {
* opaque cid<0..2^8-1>;
* } ConnectionId;
@ -849,10 +864,11 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
ssl->handshake->ecdh_ctx.point_format = p[0];
#endif /* !MBEDTLS_USE_PSA_CRYPTO &&
( MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ) */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_set_point_format( &ssl->handshake->ecjpake_ctx,
p[0] );
#endif
#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 );
}
@ -889,6 +905,24 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
ssl->handshake->ecjpake_cache = NULL;
ssl->handshake->ecjpake_cache_len = 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ( ret = mbedtls_psa_ecjpake_read_round(
&ssl->handshake->psa_pake_ctx, buf, len,
MBEDTLS_ECJPAKE_ROUND_ONE ) ) != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret );
mbedtls_ssl_send_alert_message(
ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( ret );
}
return( 0 );
#else
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
@ -901,6 +935,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
}
return( 0 );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
@ -2296,6 +2331,47 @@ start_processing:
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* The first 3 bytes are:
* [0] MBEDTLS_ECP_TLS_NAMED_CURVE
* [1, 2] elliptic curve's TLS ID
*
* However since we only support secp256r1 for now, we check only
* that TLS ID here
*/
uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE( p, 1 );
const mbedtls_ecp_curve_info *curve_info;
if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id(
MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL )
{
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
if( ( *p != MBEDTLS_ECP_TLS_NAMED_CURVE ) ||
( read_tls_id != curve_info->tls_id ) )
{
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
p += 3;
if( ( ret = mbedtls_psa_ecjpake_read_round(
&ssl->handshake->psa_pake_ctx, p, end - p,
MBEDTLS_ECJPAKE_ROUND_TWO ) ) != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round two", ret );
mbedtls_ssl_send_alert_message(
ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
}
#else
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
@ -2307,6 +2383,7 @@ start_processing:
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
@ -2654,7 +2731,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
for( size_t i = 0; i < sig_alg_len; i += 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 3,
( "Supported Signature Algorithm found: %d,%d",
( "Supported Signature Algorithm found: %02x %02x",
sig_alg[i], sig_alg[i + 1] ) );
}
#endif
@ -2680,7 +2757,6 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
unsigned char *p = dn + i + 2;
mbedtls_x509_name name;
mbedtls_x509_name *name_cur, *name_prv;
size_t asn1_len;
char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
memset( &name, 0, sizeof( name ) );
@ -2700,14 +2776,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "DN hint: %.*s",
mbedtls_x509_dn_gets( s, sizeof(s), &name ), s ) );
name_cur = name.next;
while( name_cur != NULL )
{
name_prv = name_cur;
name_cur = name_cur->next;
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
mbedtls_free( name_prv );
}
mbedtls_asn1_free_named_data_list_shallow( name.next );
}
#endif
@ -3235,6 +3304,21 @@ ecdh_calc_secret:
{
header_len = 4;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
unsigned char *out_p = ssl->out_msg + header_len;
unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
header_len;
ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx,
out_p, end_p - out_p, &content_len,
MBEDTLS_ECJPAKE_ROUND_TWO );
if ( ret != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret );
return( ret );
}
#else
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
ssl->out_msg + header_len,
MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
@ -3254,6 +3338,7 @@ ecdh_calc_secret:
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */

View File

@ -268,10 +268,11 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
ssl->handshake->ecdh_ctx.point_format = p[0];
#endif /* !MBEDTLS_USE_PSA_CRYPTO &&
( MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ) */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_set_point_format( &ssl->handshake->ecjpake_ctx,
p[0] );
#endif
#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 );
}
@ -289,16 +290,37 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ssl->handshake->psa_pake_ctx_is_ok != 1 )
#else
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 0 );
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ( ret = mbedtls_psa_ecjpake_read_round(
&ssl->handshake->psa_pake_ctx, buf, len,
MBEDTLS_ECJPAKE_ROUND_ONE ) ) != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret );
mbedtls_ssl_send_alert_message(
ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( ret );
}
#else
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
@ -307,6 +329,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Only mark the extension as OK when we're sure it is */
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
@ -353,9 +376,6 @@ static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
}
/*
* Quoting draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* struct {
* opaque cid<0..2^8-1>;
* } ConnectionId;
@ -1752,9 +1772,6 @@ static void ssl_write_cid_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) );
/*
* Quoting draft-ietf-tls-dtls-connection-id-05
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
*
* struct {
* opaque cid<0..2^8-1>;
* } ConnectionId;
@ -1996,6 +2013,18 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
p += 2;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx,
p + 2, end - p - 2, &kkpp_len,
MBEDTLS_ECJPAKE_ROUND_ONE );
if ( ret != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret );
return;
}
#else
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
@ -2004,6 +2033,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
return;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
p += 2;
@ -2531,10 +2561,15 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ! mbedtls_ssl_sig_alg_is_supported( ssl, *sig_alg ) )
continue;
MBEDTLS_PUT_UINT16_BE( *sig_alg, p, sa_len );
/* Write elements at offsets starting from 1 (offset 0 is for the
* length). Thus the offset of each element is the length of the
* partial list including that element. */
sa_len += 2;
MBEDTLS_PUT_UINT16_BE( *sig_alg, p, sa_len );
}
/* Fill in list length. */
MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 );
sa_len += 2;
p += sa_len;
@ -2808,6 +2843,46 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
unsigned char *out_p = ssl->out_msg + ssl->out_msglen;
unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
ssl->out_msglen;
size_t output_offset = 0;
size_t output_len = 0;
const mbedtls_ecp_curve_info *curve_info;
/*
* The first 3 bytes are:
* [0] MBEDTLS_ECP_TLS_NAMED_CURVE
* [1, 2] elliptic curve's TLS ID
*
* However since we only support secp256r1 for now, we hardcode its
* TLS ID here
*/
if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id(
MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL )
{
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
*out_p = MBEDTLS_ECP_TLS_NAMED_CURVE;
MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p, 1 );
output_offset += 3;
ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx,
out_p + output_offset,
end_p - out_p - output_offset, &output_len,
MBEDTLS_ECJPAKE_ROUND_TWO );
if( ret != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret );
return( ret );
}
output_offset += output_len;
ssl->out_msglen += output_offset;
#else
size_t len = 0;
ret = mbedtls_ecjpake_write_round_two(
@ -2822,6 +2897,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
}
ssl->out_msglen += len;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
@ -4039,6 +4115,18 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ( ret = mbedtls_psa_ecjpake_read_round(
&ssl->handshake->psa_pake_ctx, p, end - p,
MBEDTLS_ECJPAKE_ROUND_TWO ) ) != 0 )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round two", ret );
return( ret );
}
#else
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
@ -4055,6 +4143,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */

View File

@ -32,6 +32,7 @@
#include "ssl_misc.h"
#include "ssl_client.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"
/* Write extensions */
@ -89,6 +90,9 @@ static int ssl_tls13_write_supported_versions_ext( mbedtls_ssl_context *ssl,
*out_len = 5 + versions_len;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS );
return( 0 );
}
@ -359,7 +363,7 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, key_share extension", buf, *out_len );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_KEY_SHARE );
cleanup:
@ -512,7 +516,6 @@ static int ssl_tls13_parse_key_share_ext( mbedtls_ssl_context *ssl,
else
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
return( ret );
}
@ -600,6 +603,8 @@ static int ssl_tls13_write_cookie_ext( mbedtls_ssl_context *ssl,
*out_len = handshake->hrr_cookie_len + 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_COOKIE );
return( 0 );
}
@ -669,7 +674,10 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
buf[4] = ke_modes_len;
*out_len = p - buf;
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES );
return ( 0 );
}
@ -692,6 +700,19 @@ static int ssl_tls13_has_configured_ticket( mbedtls_ssl_context *ssl )
session != NULL && session->ticket != NULL );
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
static int ssl_tls13_early_data_has_valid_ticket( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_session *session = ssl->session_negotiate;
return( ssl->handshake->resume &&
session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
( session->ticket_flags &
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA ) &&
mbedtls_ssl_tls13_cipher_suite_is_offered(
ssl, session->ciphersuite ) );
}
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_ticket_get_identity( mbedtls_ssl_context *ssl,
psa_algorithm_t *hash_alg,
@ -981,8 +1002,6 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key identities", buf, p - buf );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
return( 0 );
}
@ -1037,6 +1056,9 @@ int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key binders", buf, p - buf );
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY );
return( 0 );
}
@ -1109,8 +1131,6 @@ static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
return( 0 );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
@ -1153,6 +1173,29 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
}
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
if( mbedtls_ssl_conf_tls13_some_psk_enabled( ssl ) &&
ssl_tls13_early_data_has_valid_ticket( ssl ) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED )
{
ret = mbedtls_ssl_tls13_write_early_data_ext( ssl, p, end, &ext_len );
if( ret != 0 )
return( ret );
p += ext_len;
/* Initializes the status to `rejected`. It will be updated to
* `accepted` if the EncryptedExtension message contain an early data
* indication extension.
*/
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write early_data extension" ) );
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* For PSK-based key exchange we need the pre_shared_key extension
* and the psk_key_exchange_modes extension.
@ -1388,7 +1431,7 @@ static int ssl_tls13_preprocess_server_hello( mbedtls_ssl_context *ssl,
ssl->session_negotiate->tls_version = ssl->tls_version;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
ret = ssl_server_hello_is_hrr( ssl, buf, end );
switch( ret )
@ -1498,6 +1541,9 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
uint16_t cipher_suite;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
int fatal_alert = 0;
uint32_t allowed_extensions_mask;
int hs_msg_type = is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST :
MBEDTLS_SSL_HS_SERVER_HELLO;
/*
* Check there is space for minimal fields
@ -1640,6 +1686,11 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello extensions", p, extensions_len );
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
allowed_extensions_mask = is_hrr ?
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR :
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH;
while( p < extensions_end )
{
unsigned int extension_type;
@ -1654,16 +1705,15 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
extension_data_end = p + extension_data_len;
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, hs_msg_type, extension_type, allowed_extensions_mask );
if( ret != 0 )
return( ret );
switch( extension_type )
{
case MBEDTLS_TLS_EXT_COOKIE:
if( !is_hrr )
{
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
goto cleanup;
}
ret = ssl_tls13_parse_cookie_ext( ssl,
p, extension_data_end );
if( ret != 0 )
@ -1686,11 +1736,6 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );
if( is_hrr )
{
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
goto cleanup;
}
if( ( ret = ssl_tls13_parse_server_pre_shared_key_ext(
ssl, p, extension_data_end ) ) != 0 )
@ -1726,18 +1771,15 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
break;
default:
MBEDTLS_SSL_DEBUG_MSG(
3,
( "unknown extension found: %u ( ignoring )",
extension_type ) );
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto cleanup;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, hs_msg_type, handshake->received_extensions );
cleanup:
if( fatal_alert == MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT )
@ -1786,21 +1828,21 @@ static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl )
* 3) If only the key_share extension was received then the key
* exchange mode is EPHEMERAL-only.
*/
switch( handshake->extensions_present &
( MBEDTLS_SSL_EXT_PRE_SHARED_KEY | MBEDTLS_SSL_EXT_KEY_SHARE ) )
switch( handshake->received_extensions &
( MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) ) )
{
/* Only the pre_shared_key extension was received */
case MBEDTLS_SSL_EXT_PRE_SHARED_KEY:
case MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ):
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
break;
/* Only the key_share extension was received */
case MBEDTLS_SSL_EXT_KEY_SHARE:
case MBEDTLS_SSL_EXT_MASK( KEY_SHARE ):
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
break;
/* Both the pre_shared_key and key_share extensions were received */
case ( MBEDTLS_SSL_EXT_PRE_SHARED_KEY | MBEDTLS_SSL_EXT_KEY_SHARE ):
case ( MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) ):
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
break;
@ -1969,6 +2011,7 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
size_t extensions_len;
const unsigned char *p = buf;
const unsigned char *extensions_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
extensions_len = MBEDTLS_GET_UINT16_BE( p, 0 );
@ -1978,6 +2021,8 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extensions_len );
extensions_end = p + extensions_len;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
@ -1996,22 +2041,14 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
/* The client MUST check EncryptedExtensions for the
* presence of any forbidden extensions and if any are found MUST abort
* the handshake with an "unsupported_extension" alert.
*/
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE );
if( ret != 0 )
return( ret );
switch( extension_type )
{
case MBEDTLS_TLS_EXT_SERVERNAME:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found server_name extension" ) );
/* The server_name extension should be an empty extension */
break;
case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extensions supported groups" ) );
break;
#if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
@ -2023,18 +2060,34 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
break;
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_TLS_EXT_EARLY_DATA:
if( extension_data_len != 0 )
{
/* The message must be empty. */
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */
default:
MBEDTLS_SSL_DEBUG_MSG(
3, ( "unsupported extension found: %u ", extension_type) );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
return ( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
handshake->received_extensions );
/* Check that we consumed all the message. */
if( p != end )
{
@ -2064,6 +2117,14 @@ static int ssl_tls13_process_encrypted_extensions( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_PROC_CHK(
ssl_tls13_parse_encrypted_extensions( ssl, buf, buf + buf_len ) );
#if defined(MBEDTLS_SSL_EARLY_DATA)
if( ssl->handshake->received_extensions &
MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) )
{
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
}
#endif
mbedtls_ssl_add_hs_msg_to_checksum( ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
buf, buf_len );
@ -2140,7 +2201,7 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
size_t certificate_request_context_len = 0;
size_t extensions_len = 0;
const unsigned char *extensions_end;
unsigned char sig_alg_ext_found = 0;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
/* ...
* opaque certificate_request_context<0..2^8-1>
@ -2156,7 +2217,6 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "Certificate Request Context",
p, certificate_request_context_len );
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
handshake->certificate_request_context =
mbedtls_calloc( 1, certificate_request_context_len );
if( handshake->certificate_request_context == NULL )
@ -2180,6 +2240,8 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extensions_len );
extensions_end = p + extensions_len;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
@ -2192,6 +2254,12 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR );
if( ret != 0 )
return( ret );
switch( extension_type )
{
case MBEDTLS_TLS_EXT_SIG_ALG:
@ -2201,25 +2269,22 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
p + extension_data_len );
if( ret != 0 )
return( ret );
if( ! sig_alg_ext_found )
sig_alg_ext_found = 1;
else
{
MBEDTLS_SSL_DEBUG_MSG( 3,
( "Duplicate signature algorithms extensions found" ) );
goto decode_error;
}
break;
default:
MBEDTLS_SSL_DEBUG_MSG(
3,
( "unknown extension found: %u ( ignoring )",
extension_type ) );
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
handshake->received_extensions );
/* Check that we consumed all the message. */
if( p != end )
{
@ -2227,8 +2292,12 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
( "CertificateRequest misaligned" ) );
goto decode_error;
}
/* Check that we found signature algorithms extension */
if( ! sig_alg_ext_found )
/* RFC 8446 section 4.3.2
*
* The "signature_algorithms" extension MUST be specified
*/
if( ( handshake->received_extensions & MBEDTLS_SSL_EXT_MASK( SIG_ALG ) ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3,
( "no signature algorithms extension found" ) );
@ -2468,14 +2537,17 @@ static int ssl_tls13_parse_new_session_ticket_exts( mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end )
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
const unsigned char *p = buf;
((void) ssl);
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < end )
{
unsigned int extension_type;
size_t extension_data_len;
int ret;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 4 );
extension_type = MBEDTLS_GET_UINT16_BE( p, 0 );
@ -2484,18 +2556,44 @@ static int ssl_tls13_parse_new_session_ticket_exts( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extension_data_len );
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST );
if( ret != 0 )
return( ret );
switch( extension_type )
{
#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_TLS_EXT_EARLY_DATA:
MBEDTLS_SSL_DEBUG_MSG( 4, ( "early_data extension received" ) );
if( extension_data_len != 4 )
{
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
}
if( ssl->session != NULL )
{
ssl->session->ticket_flags |=
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA;
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */
default:
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
handshake->received_extensions );
return( 0 );
}
@ -2668,7 +2766,7 @@ static int ssl_tls13_postprocess_new_session_ticket( mbedtls_ssl_context *ssl,
}
/*
* Handler for MBEDTLS_SSL_NEW_SESSION_TICKET
* Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
*/
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_new_session_ticket( mbedtls_ssl_context *ssl )
@ -2782,7 +2880,7 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
case MBEDTLS_SSL_NEW_SESSION_TICKET:
case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET:
ret = ssl_tls13_process_new_session_ticket( ssl );
if( ret != 0 )
break;

View File

@ -398,6 +398,7 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
size_t certificate_list_len = 0;
const unsigned char *p = buf;
const unsigned char *certificate_list_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 4 );
certificate_request_context_len = p[0];
@ -447,6 +448,7 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
while( p < certificate_list_end )
{
size_t cert_data_len, extensions_len;
const unsigned char *extensions_end;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, certificate_list_end, 3 );
cert_data_len = MBEDTLS_GET_UINT24_BE( p, 0 );
@ -504,7 +506,48 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
extensions_len = MBEDTLS_GET_UINT16_BE( p, 0 );
p += 2;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, certificate_list_end, extensions_len );
p += extensions_len;
extensions_end = p + extensions_len;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
size_t extension_data_len;
/*
* struct {
* ExtensionType extension_type; (2 bytes)
* opaque extension_data<0..2^16-1>;
* } Extension;
*/
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, 4 );
extension_type = MBEDTLS_GET_UINT16_BE( p, 0 );
extension_data_len = MBEDTLS_GET_UINT16_BE( p, 2 );
p += 4;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CERTIFICATE, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CT );
if( ret != 0 )
return( ret );
switch( extension_type )
{
default:
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_CERTIFICATE,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_CERTIFICATE,
handshake->received_extensions );
}
exit:
@ -512,7 +555,7 @@ exit:
if( p != end )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad Certificate message" ) );
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, \
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
}
@ -843,6 +886,9 @@ static int ssl_tls13_write_certificate_body( mbedtls_ssl_context *ssl,
*out_len = p - buf;
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_CERTIFICATE, ssl->handshake->sent_extensions );
return( 0 );
}
@ -1328,6 +1374,39 @@ cleanup:
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
/* Early Data Indication Extension
*
* struct {
* select ( Handshake.msg_type ) {
* ...
* case client_hello: Empty;
* case encrypted_extensions: Empty;
* };
* } EarlyDataIndication;
*/
#if defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_tls13_write_early_data_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len )
{
unsigned char *p = buf;
*out_len = 0;
((void) ssl);
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EARLY_DATA, p, 0 );
MBEDTLS_PUT_UINT16_BE( 0, p, 2 );
*out_len = 4;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_EARLY_DATA );
return( 0 );
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Reset SSL context and update hash for handling HRR.
*
* Replace Transcript-Hash(X) by
@ -1485,4 +1564,61 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
}
#endif /* MBEDTLS_ECDH_C */
/* RFC 8446 section 4.2
*
* If an implementation receives an extension which it recognizes and which is
* not specified for the message in which it appears, it MUST abort the handshake
* with an "illegal_parameter" alert.
*
*/
int mbedtls_ssl_tls13_check_received_extension(
mbedtls_ssl_context *ssl,
int hs_msg_type,
unsigned int received_extension_type,
uint32_t hs_msg_allowed_extensions_mask )
{
uint32_t extension_mask = mbedtls_ssl_get_extension_mask(
received_extension_type );
MBEDTLS_SSL_PRINT_EXT(
3, hs_msg_type, received_extension_type, "received" );
if( ( extension_mask & hs_msg_allowed_extensions_mask ) == 0 )
{
MBEDTLS_SSL_PRINT_EXT(
3, hs_msg_type, received_extension_type, "is illegal" );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
ssl->handshake->received_extensions |= extension_mask;
/*
* If it is a message containing extension responses, check that we
* previously sent the extension.
*/
switch( hs_msg_type )
{
case MBEDTLS_SSL_HS_SERVER_HELLO:
case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:
case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:
case MBEDTLS_SSL_HS_CERTIFICATE:
/* Check if the received extension is sent by peer message.*/
if( ( ssl->handshake->sent_extensions & extension_mask ) != 0 )
return( 0 );
break;
default:
return( 0 );
}
MBEDTLS_SSL_PRINT_EXT(
3, hs_msg_type, received_extension_type, "is unsupported" );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
}
#endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */

View File

@ -215,6 +215,33 @@ cleanup:
return( psa_ssl_status_to_mbedtls ( status ) );
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_make_traffic_key(
psa_algorithm_t hash_alg,
const unsigned char *secret, size_t secret_len,
unsigned char *key, size_t key_len,
unsigned char *iv, size_t iv_len )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_ssl_tls13_hkdf_expand_label(
hash_alg,
secret, secret_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
NULL, 0,
key, key_len );
if( ret != 0 )
return( ret );
ret = mbedtls_ssl_tls13_hkdf_expand_label(
hash_alg,
secret, secret_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
NULL, 0,
iv, iv_len );
return( ret );
}
/*
* The traffic keying material is generated from the following inputs:
*
@ -240,35 +267,17 @@ int mbedtls_ssl_tls13_make_traffic_keys(
{
int ret = 0;
ret = mbedtls_ssl_tls13_hkdf_expand_label( hash_alg,
client_secret, secret_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
NULL, 0,
keys->client_write_key, key_len );
ret = ssl_tls13_make_traffic_key(
hash_alg, client_secret, secret_len,
keys->client_write_key, key_len,
keys->client_write_iv, iv_len );
if( ret != 0 )
return( ret );
ret = mbedtls_ssl_tls13_hkdf_expand_label( hash_alg,
server_secret, secret_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
NULL, 0,
keys->server_write_key, key_len );
if( ret != 0 )
return( ret );
ret = mbedtls_ssl_tls13_hkdf_expand_label( hash_alg,
client_secret, secret_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
NULL, 0,
keys->client_write_iv, iv_len );
if( ret != 0 )
return( ret );
ret = mbedtls_ssl_tls13_hkdf_expand_label( hash_alg,
server_secret, secret_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
NULL, 0,
keys->server_write_iv, iv_len );
ret = ssl_tls13_make_traffic_key(
hash_alg, server_secret, secret_len,
keys->server_write_key, key_len,
keys->server_write_iv, iv_len );
if( ret != 0 )
return( ret );
@ -1052,6 +1061,194 @@ int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
return( 0 );
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_get_cipher_key_info(
const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
size_t *key_len, size_t *iv_len )
{
psa_key_type_t key_type;
psa_algorithm_t alg;
size_t taglen;
size_t key_bits;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG )
taglen = 8;
else
taglen = 16;
status = mbedtls_ssl_cipher_to_psa( ciphersuite_info->cipher, taglen,
&alg, &key_type, &key_bits );
if( status != PSA_SUCCESS )
return psa_ssl_status_to_mbedtls( status );
*key_len = PSA_BITS_TO_BYTES( key_bits );
/* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */
*iv_len = 12;
return 0;
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
/*
* ssl_tls13_generate_early_key() generates the key necessary for protecting
* the early application data and handshake messages as described in section 7
* of RFC 8446.
*
* NOTE: Only one key is generated, the key for the traffic from the client to
* the server. The TLS 1.3 specification does not define a secret and thus
* a key for server early traffic.
*/
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_generate_early_key( mbedtls_ssl_context *ssl,
mbedtls_ssl_key_set *traffic_keys )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_type;
psa_algorithm_t hash_alg;
size_t hash_len;
unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
size_t transcript_len;
size_t key_len;
size_t iv_len;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
mbedtls_ssl_tls13_early_secrets *tls13_early_secrets = &handshake->tls13_early_secrets;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_tls13_generate_early_key" ) );
ret = ssl_tls13_get_cipher_key_info( ciphersuite_info, &key_len, &iv_len );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_get_cipher_key_info", ret );
goto cleanup;
}
md_type = ciphersuite_info->mac;
hash_alg = mbedtls_hash_info_psa_from_md( ciphersuite_info->mac );
hash_len = PSA_HASH_LENGTH( hash_alg );
ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type,
transcript,
sizeof( transcript ),
&transcript_len );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1,
"mbedtls_ssl_get_handshake_transcript",
ret );
goto cleanup;
}
ret = mbedtls_ssl_tls13_derive_early_secrets(
hash_alg, handshake->tls13_master_secrets.early,
transcript, transcript_len, tls13_early_secrets );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_derive_early_secrets", ret );
goto cleanup;
}
MBEDTLS_SSL_DEBUG_BUF(
4, "Client early traffic secret",
tls13_early_secrets->client_early_traffic_secret, hash_len );
/*
* Export client handshake traffic secret
*/
if( ssl->f_export_keys != NULL )
{
ssl->f_export_keys(
ssl->p_export_keys,
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET,
tls13_early_secrets->client_early_traffic_secret,
hash_len,
handshake->randbytes,
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */ );
}
ret = ssl_tls13_make_traffic_key(
hash_alg,
tls13_early_secrets->client_early_traffic_secret,
hash_len, traffic_keys->client_write_key, key_len,
traffic_keys->client_write_iv, iv_len );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_make_traffic_key", ret );
goto cleanup;
}
traffic_keys->key_len = key_len;
traffic_keys->iv_len = iv_len;
MBEDTLS_SSL_DEBUG_BUF( 4, "client early write_key",
traffic_keys->client_write_key,
traffic_keys->key_len);
MBEDTLS_SSL_DEBUG_BUF( 4, "client early write_iv",
traffic_keys->client_write_iv,
traffic_keys->iv_len);
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_tls13_generate_early_key" ) );
cleanup:
/* Erase secret and transcript */
mbedtls_platform_zeroize(
tls13_early_secrets, sizeof( mbedtls_ssl_tls13_early_secrets ) );
mbedtls_platform_zeroize( transcript, sizeof( transcript ) );
return( ret );
}
int mbedtls_ssl_tls13_compute_early_transform( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_key_set traffic_keys;
mbedtls_ssl_transform *transform_earlydata = NULL;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
/* Next evolution in key schedule: Establish early_data secret and
* key material. */
ret = ssl_tls13_generate_early_key( ssl, &traffic_keys );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_generate_early_key",
ret );
goto cleanup;
}
transform_earlydata = mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) );
if( transform_earlydata == NULL )
{
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto cleanup;
}
ret = mbedtls_ssl_tls13_populate_transform(
transform_earlydata,
ssl->conf->endpoint,
ssl->session_negotiate->ciphersuite,
&traffic_keys,
ssl );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret );
goto cleanup;
}
handshake->transform_earlydata = transform_earlydata;
cleanup:
mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) );
if( ret != 0 )
mbedtls_free( transform_earlydata );
return( ret );
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
int mbedtls_ssl_tls13_key_schedule_stage_early( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -1098,51 +1295,19 @@ int mbedtls_ssl_tls13_key_schedule_stage_early( mbedtls_ssl_context *ssl )
return( 0 );
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int mbedtls_ssl_tls13_get_cipher_key_info(
const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
size_t *key_len, size_t *iv_len )
{
psa_key_type_t key_type;
psa_algorithm_t alg;
size_t taglen;
size_t key_bits;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
if( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG )
taglen = 8;
else
taglen = 16;
status = mbedtls_ssl_cipher_to_psa( ciphersuite_info->cipher, taglen,
&alg, &key_type, &key_bits );
if( status != PSA_SUCCESS )
return psa_ssl_status_to_mbedtls( status );
*key_len = PSA_BITS_TO_BYTES( key_bits );
/* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */
*iv_len = 12;
return 0;
}
/* mbedtls_ssl_tls13_generate_handshake_keys() generates keys necessary for
* protecting the handshake messages, as described in Section 7 of TLS 1.3. */
int mbedtls_ssl_tls13_generate_handshake_keys( mbedtls_ssl_context *ssl,
mbedtls_ssl_key_set *traffic_keys )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_type;
psa_algorithm_t hash_alg;
size_t hash_len;
unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
size_t transcript_len;
size_t key_len, iv_len;
size_t key_len;
size_t iv_len;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
@ -1150,11 +1315,10 @@ int mbedtls_ssl_tls13_generate_handshake_keys( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_tls13_generate_handshake_keys" ) );
ret = mbedtls_ssl_tls13_get_cipher_key_info( ciphersuite_info,
&key_len, &iv_len );
ret = ssl_tls13_get_cipher_key_info( ciphersuite_info, &key_len, &iv_len );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_get_cipher_key_info", ret );
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_get_cipher_key_info", ret );
return ret;
}
@ -1370,11 +1534,11 @@ int mbedtls_ssl_tls13_generate_application_keys(
/* Extract basic information about hash and ciphersuite */
ret = mbedtls_ssl_tls13_get_cipher_key_info( handshake->ciphersuite_info,
&key_len, &iv_len );
ret = ssl_tls13_get_cipher_key_info( handshake->ciphersuite_info,
&key_len, &iv_len );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_get_cipher_key_info", ret );
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_get_cipher_key_info", ret );
goto cleanup;
}

View File

@ -667,6 +667,27 @@ int mbedtls_ssl_tls13_calculate_verify_data( mbedtls_ssl_context *ssl,
size_t *actual_len,
int which );
#if defined(MBEDTLS_SSL_EARLY_DATA)
/**
* \brief Compute TLS 1.3 early transform
*
* \param ssl The SSL context to operate on.
*
* \returns \c 0 on success.
* \returns A negative error code on failure.
*
* \warning The function does not compute the early master secret. Call
* mbedtls_ssl_tls13_key_schedule_stage_early() before to
* call this function to generate the early master secret.
* \note For a client/server endpoint, the function computes only the
* encryption/decryption part of the transform as the decryption/
* encryption part is not defined by the specification (no early
* traffic from the server to the client).
*/
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_tls13_compute_early_transform( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_EARLY_DATA */
/**
* \brief Compute TLS 1.3 handshake transform
*

View File

@ -700,6 +700,8 @@ static int ssl_tls13_write_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 4, ( "sent selected_identity: %u",
ssl->handshake->selected_identity ) );
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY );
return( 0 );
}
@ -926,110 +928,69 @@ static int ssl_tls13_parse_key_shares_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_ECDH_C */
#if defined(MBEDTLS_DEBUG_C)
static void ssl_tls13_debug_print_client_hello_exts( mbedtls_ssl_context *ssl )
{
((void) ssl);
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Extensions:" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- KEY_SHARE_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_KEY_SHARE ) > 0 ) ? "TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- PSK_KEY_EXCHANGE_MODES_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) > 0 ) ?
"TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- PRE_SHARED_KEY_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_PRE_SHARED_KEY ) > 0 ) ? "TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SIGNATURE_ALGORITHM_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SIG_ALG ) > 0 ) ? "TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SUPPORTED_GROUPS_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SUPPORTED_GROUPS ) >0 ) ?
"TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SUPPORTED_VERSION_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS ) > 0 ) ?
"TRUE" : "FALSE" ) );
#if defined ( MBEDTLS_SSL_SERVER_NAME_INDICATION )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SERVERNAME_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SERVERNAME ) > 0 ) ?
"TRUE" : "FALSE" ) );
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined ( MBEDTLS_SSL_ALPN )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- ALPN_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_ALPN ) > 0 ) ?
"TRUE" : "FALSE" ) );
#endif /* MBEDTLS_SSL_ALPN */
}
#endif /* MBEDTLS_DEBUG_C */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts( mbedtls_ssl_context *ssl,
int exts_mask )
{
int masked = ssl->handshake->extensions_present & exts_mask;
int masked = ssl->handshake->received_extensions & exts_mask;
return( masked == exts_mask );
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(
mbedtls_ssl_context *ssl )
{
return( ssl_tls13_client_hello_has_exts(
ssl,
MBEDTLS_SSL_EXT_SUPPORTED_GROUPS |
MBEDTLS_SSL_EXT_KEY_SHARE |
MBEDTLS_SSL_EXT_SIG_ALG ) );
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) |
MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) |
MBEDTLS_SSL_EXT_MASK( SIG_ALG ) ) );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_key_exchange(
mbedtls_ssl_context *ssl )
{
return( ssl_tls13_client_hello_has_exts(
ssl,
MBEDTLS_SSL_EXT_PRE_SHARED_KEY |
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) );
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) |
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) ) );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(
mbedtls_ssl_context *ssl )
{
return( ssl_tls13_client_hello_has_exts(
ssl,
MBEDTLS_SSL_EXT_SUPPORTED_GROUPS |
MBEDTLS_SSL_EXT_KEY_SHARE |
MBEDTLS_SSL_EXT_PRE_SHARED_KEY |
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) );
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) |
MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) |
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) |
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) ) );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
return( mbedtls_ssl_conf_tls13_ephemeral_enabled( ssl ) &&
ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange( ssl ) );
#else
((void) ssl);
return( 0 );
#endif
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_psk_key_exchange( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
return( mbedtls_ssl_conf_tls13_psk_enabled( ssl ) &&
mbedtls_ssl_tls13_psk_enabled( ssl ) &&
ssl_tls13_client_hello_has_exts_for_psk_key_exchange( ssl ) );
@ -1042,7 +1003,7 @@ static int ssl_tls13_check_psk_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_psk_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
return( mbedtls_ssl_conf_tls13_psk_ephemeral_enabled( ssl ) &&
mbedtls_ssl_tls13_psk_ephemeral_enabled( ssl ) &&
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange( ssl ) );
@ -1289,6 +1250,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
const unsigned char *cipher_suites_end;
size_t extensions_len;
const unsigned char *extensions_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
int hrr_required = 0;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
@ -1297,8 +1259,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
const unsigned char *pre_shared_key_ext_end = NULL;
#endif
ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
/*
* ClientHello layout:
* 0 . 1 protocol version
@ -1356,7 +1316,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes",
p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
memcpy( &ssl->handshake->randbytes[0], p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
memcpy( &handshake->randbytes[0], p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
/* ...
@ -1426,13 +1386,13 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
continue;
ssl->session_negotiate->ciphersuite = cipher_suite;
ssl->handshake->ciphersuite_info = ciphersuite_info;
handshake->ciphersuite_info = ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %04x - %s",
cipher_suite,
ciphersuite_info->name ) );
}
if( ssl->handshake->ciphersuite_info == NULL )
if( handshake->ciphersuite_info == NULL )
{
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
@ -1468,27 +1428,29 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", p, extensions_len );
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
size_t extension_data_len;
const unsigned char *extension_data_end;
/* RFC 8446, page 57
/* RFC 8446, section 4.2.11
*
* The "pre_shared_key" extension MUST be the last extension in the
* ClientHello (this facilitates implementation as described below).
* Servers MUST check that it is the last extension and otherwise fail
* the handshake with an "illegal_parameter" alert.
*/
if( ssl->handshake->extensions_present & MBEDTLS_SSL_EXT_PRE_SHARED_KEY )
if( handshake->received_extensions & MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) )
{
MBEDTLS_SSL_DEBUG_MSG(
3, ( "pre_shared_key is not last extension." ) );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, 4 );
@ -1499,6 +1461,12 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
extension_data_end = p + extension_data_len;
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH );
if( ret != 0 )
return( ret );
switch( extension_type )
{
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@ -1512,7 +1480,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
1, "mbedtls_ssl_parse_servername_ext", ret );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SERVERNAME;
break;
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
@ -1535,7 +1502,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
break;
#endif /* MBEDTLS_ECDH_C */
@ -1565,7 +1531,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
break;
#endif /* MBEDTLS_ECDH_C */
@ -1580,7 +1545,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
( "ssl_tls13_parse_supported_versions_ext" ), ret );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS;
break;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
@ -1596,19 +1560,18 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES;
break;
#endif
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );
if( ( ssl->handshake->extensions_present &
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) == 0 )
if( ( handshake->received_extensions &
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) ) == 0 )
{
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* Delay processing of the PSK identity once we have
@ -1617,8 +1580,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
*/
pre_shared_key_ext = p;
pre_shared_key_ext_end = extension_data_end;
#endif
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
break;
#if defined(MBEDTLS_SSL_ALPN)
@ -1632,7 +1594,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
1, ( "mbedtls_ssl_parse_alpn_ext" ), ret );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_ALPN;
break;
#endif /* MBEDTLS_SSL_ALPN */
@ -1649,23 +1610,21 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
ret ) );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
break;
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
default:
MBEDTLS_SSL_DEBUG_MSG( 3,
( "unknown extension found: %ud ( ignoring )",
extension_type ) );
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_CLIENT_HELLO,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
#if defined(MBEDTLS_DEBUG_C)
/* List all the extensions we have received */
ssl_tls13_debug_print_client_hello_exts( ssl );
#endif /* MBEDTLS_DEBUG_C */
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_CLIENT_HELLO,
handshake->received_extensions );
mbedtls_ssl_add_hs_hdr_to_checksum( ssl,
MBEDTLS_SSL_HS_CLIENT_HELLO,
@ -1679,9 +1638,9 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
/* If we've settled on a PSK-based exchange, parse PSK identity ext */
if( mbedtls_ssl_tls13_some_psk_enabled( ssl ) &&
mbedtls_ssl_conf_tls13_some_psk_enabled( ssl ) &&
( ssl->handshake->extensions_present & MBEDTLS_SSL_EXT_PRE_SHARED_KEY ) )
( handshake->received_extensions & MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) ) )
{
ssl->handshake->update_checksum( ssl, buf,
handshake->update_checksum( ssl, buf,
pre_shared_key_ext - buf );
ret = ssl_tls13_parse_pre_shared_key_ext( ssl,
pre_shared_key_ext,
@ -1690,26 +1649,26 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
cipher_suites_end );
if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
{
ssl->handshake->extensions_present &= ~MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
handshake->received_extensions &= ~MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY );
}
else if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_tls13_parse_pre_shared_key_ext" ),
ret );
MBEDTLS_SSL_DEBUG_RET(
1, "ssl_tls13_parse_pre_shared_key_ext" , ret );
return( ret );
}
}
else
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
{
ssl->handshake->update_checksum( ssl, buf, p - buf );
handshake->update_checksum( ssl, buf, p - buf );
}
ret = ssl_tls13_determine_key_exchange_mode( ssl );
if( ret < 0 )
return( ret );
mbedtls_ssl_optimize_checksum( ssl, ssl->handshake->ciphersuite_info );
mbedtls_ssl_optimize_checksum( ssl, handshake->ciphersuite_info );
return( hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK );
}
@ -1856,6 +1815,9 @@ static int ssl_tls13_write_server_hello_supported_versions_ext(
*out_len = 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS );
return( 0 );
}
@ -1962,6 +1924,8 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
*out_len = p - buf;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_KEY_SHARE );
return( 0 );
}
@ -2026,6 +1990,8 @@ static int ssl_tls13_write_hrr_key_share_ext( mbedtls_ssl_context *ssl,
*out_len = 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_KEY_SHARE );
return( 0 );
}
@ -2054,6 +2020,7 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
size_t output_len;
*out_len = 0;
ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
/* ...
* ProtocolVersion legacy_version = 0x0303; // TLS 1.2
@ -2179,6 +2146,11 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello", buf, *out_len );
MBEDTLS_SSL_PRINT_EXTS(
3, is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST :
MBEDTLS_SSL_HS_SERVER_HELLO,
ssl->handshake->sent_extensions );
return( ret );
}
@ -2363,6 +2335,9 @@ static int ssl_tls13_write_encrypted_extensions_body( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 4, "encrypted extensions", buf, *out_len );
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, ssl->handshake->sent_extensions );
return( 0 );
}
@ -2492,6 +2467,9 @@ static int ssl_tls13_write_certificate_request_body( mbedtls_ssl_context *ssl,
*out_len = p - buf;
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, ssl->handshake->sent_extensions );
return( 0 );
}
@ -2650,7 +2628,7 @@ static int ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl )
mbedtls_ssl_tls13_handshake_wrapup( ssl );
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_NEW_SESSION_TICKET );
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET );
#else
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
#endif
@ -2658,7 +2636,7 @@ static int ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl )
}
/*
* Handler for MBEDTLS_SSL_NEW_SESSION_TICKET
* Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
*/
#define SSL_NEW_SESSION_TICKET_SKIP 0
#define SSL_NEW_SESSION_TICKET_WRITE 1
@ -2877,6 +2855,8 @@ static int ssl_tls13_write_new_session_ticket_body( mbedtls_ssl_context *ssl,
* Note: We currently don't have any extensions.
* Set length to zero.
*/
ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
MBEDTLS_PUT_UINT16_BE( 0, p, 0 );
p += 2;
@ -2885,11 +2865,14 @@ static int ssl_tls13_write_new_session_ticket_body( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 4, "ticket", buf, *out_len );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) );
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, ssl->handshake->sent_extensions );
return( 0 );
}
/*
* Handler for MBEDTLS_SSL_NEW_SESSION_TICKET
* Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
*/
static int ssl_tls13_write_new_session_ticket( mbedtls_ssl_context *ssl )
{
@ -2925,8 +2908,8 @@ static int ssl_tls13_write_new_session_ticket( mbedtls_ssl_context *ssl )
else
ssl->handshake->new_session_tickets_count--;
mbedtls_ssl_handshake_set_state( ssl,
MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH );
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH );
}
else
{
@ -3062,7 +3045,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
case MBEDTLS_SSL_NEW_SESSION_TICKET:
case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET:
ret = ssl_tls13_write_new_session_ticket( ssl );
if( ret != 0 )
{
@ -3071,9 +3054,9 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
ret );
}
break;
case MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH:
case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:
/* This state is necessary to do the flush of the New Session
* Ticket message written in MBEDTLS_SSL_NEW_SESSION_TICKET
* Ticket message written in MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
* as part of ssl_prepare_handshake_step.
*/
ret = 0;
@ -3081,7 +3064,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
if( ssl->handshake->new_session_tickets_count == 0 )
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
else
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_NEW_SESSION_TICKET );
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET );
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

View File

@ -472,7 +472,6 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
size_t set_len;
const unsigned char *end_set;
mbedtls_x509_name *head = cur;
mbedtls_x509_name *prev, *allocated;
/* don't use recursion, we'd risk stack overflow if not optimized */
while( 1 )
@ -530,18 +529,8 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
error:
/* Skip the first element as we did not allocate it */
allocated = head->next;
while( allocated != NULL )
{
prev = allocated;
allocated = allocated->next;
mbedtls_platform_zeroize( prev, sizeof( *prev ) );
mbedtls_free( prev );
}
mbedtls_platform_zeroize( head, sizeof( *head ) );
mbedtls_asn1_free_named_data_list_shallow( head->next );
head->next = NULL;
return( ret );
}

View File

@ -705,28 +705,16 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
{
mbedtls_x509_crl *crl_cur = crl;
mbedtls_x509_crl *crl_prv;
mbedtls_x509_name *name_cur;
mbedtls_x509_name *name_prv;
mbedtls_x509_crl_entry *entry_cur;
mbedtls_x509_crl_entry *entry_prv;
if( crl == NULL )
return;
do
while( crl_cur != NULL )
{
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
mbedtls_free( crl_cur->sig_opts );
#endif
name_cur = crl_cur->issuer.next;
while( name_cur != NULL )
{
name_prv = name_cur;
name_cur = name_cur->next;
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
mbedtls_free( name_prv );
}
mbedtls_asn1_free_named_data_list_shallow( crl_cur->issuer.next );
entry_cur = crl_cur->entry.next;
while( entry_cur != NULL )
@ -744,13 +732,6 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
mbedtls_free( crl_cur->raw.p );
}
crl_cur = crl_cur->next;
}
while( crl_cur != NULL );
crl_cur = crl;
do
{
crl_prv = crl_cur;
crl_cur = crl_cur->next;
@ -758,7 +739,6 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
if( crl_prv != crl )
mbedtls_free( crl_prv );
}
while( crl_cur != NULL );
}
#endif /* MBEDTLS_X509_CRL_PARSE_C */

View File

@ -685,16 +685,7 @@ static int x509_get_subject_alt_name( unsigned char **p,
*/
if( ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
{
mbedtls_x509_sequence *seq_cur = subject_alt_name->next;
mbedtls_x509_sequence *seq_prv;
while( seq_cur != NULL )
{
seq_prv = seq_cur;
seq_cur = seq_cur->next;
mbedtls_platform_zeroize( seq_prv,
sizeof( mbedtls_x509_sequence ) );
mbedtls_free( seq_prv );
}
mbedtls_asn1_sequence_free( subject_alt_name->next );
subject_alt_name->next = NULL;
return( ret );
}
@ -1846,6 +1837,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
const char *prefix )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
size_t n = *size;
char *p = *buf;
const mbedtls_x509_sequence *cur = subject_alt_name;
@ -1898,18 +1890,11 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
ret = mbedtls_snprintf( p, n, "\n%s hardware serial number : ", prefix );
MBEDTLS_X509_SAFE_SNPRINTF;
if( other_name->value.hardware_module_name.val.len >= n )
for( i = 0; i < other_name->value.hardware_module_name.val.len; i++ )
{
*p = '\0';
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
ret = mbedtls_snprintf( p, n, "%02X", other_name->value.hardware_module_name.val.p[i] );
MBEDTLS_X509_SAFE_SNPRINTF;
}
memcpy( p, other_name->value.hardware_module_name.val.p,
other_name->value.hardware_module_name.val.len );
p += other_name->value.hardware_module_name.val.len;
n -= other_name->value.hardware_module_name.val.len;
}/* MBEDTLS_OID_ON_HW_MODULE_NAME */
}
break;
@ -3300,15 +3285,8 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
{
mbedtls_x509_crt *cert_cur = crt;
mbedtls_x509_crt *cert_prv;
mbedtls_x509_name *name_cur;
mbedtls_x509_name *name_prv;
mbedtls_x509_sequence *seq_cur;
mbedtls_x509_sequence *seq_prv;
if( crt == NULL )
return;
do
while( cert_cur != NULL )
{
mbedtls_pk_free( &cert_cur->pk );
@ -3316,53 +3294,11 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
mbedtls_free( cert_cur->sig_opts );
#endif
name_cur = cert_cur->issuer.next;
while( name_cur != NULL )
{
name_prv = name_cur;
name_cur = name_cur->next;
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
mbedtls_free( name_prv );
}
name_cur = cert_cur->subject.next;
while( name_cur != NULL )
{
name_prv = name_cur;
name_cur = name_cur->next;
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
mbedtls_free( name_prv );
}
seq_cur = cert_cur->ext_key_usage.next;
while( seq_cur != NULL )
{
seq_prv = seq_cur;
seq_cur = seq_cur->next;
mbedtls_platform_zeroize( seq_prv,
sizeof( mbedtls_x509_sequence ) );
mbedtls_free( seq_prv );
}
seq_cur = cert_cur->subject_alt_names.next;
while( seq_cur != NULL )
{
seq_prv = seq_cur;
seq_cur = seq_cur->next;
mbedtls_platform_zeroize( seq_prv,
sizeof( mbedtls_x509_sequence ) );
mbedtls_free( seq_prv );
}
seq_cur = cert_cur->certificate_policies.next;
while( seq_cur != NULL )
{
seq_prv = seq_cur;
seq_cur = seq_cur->next;
mbedtls_platform_zeroize( seq_prv,
sizeof( mbedtls_x509_sequence ) );
mbedtls_free( seq_prv );
}
mbedtls_asn1_free_named_data_list_shallow( cert_cur->issuer.next );
mbedtls_asn1_free_named_data_list_shallow( cert_cur->subject.next );
mbedtls_asn1_sequence_free( cert_cur->ext_key_usage.next );
mbedtls_asn1_sequence_free( cert_cur->subject_alt_names.next );
mbedtls_asn1_sequence_free( cert_cur->certificate_policies.next );
if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
{
@ -3370,13 +3306,6 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
mbedtls_free( cert_cur->raw.p );
}
cert_cur = cert_cur->next;
}
while( cert_cur != NULL );
cert_cur = crt;
do
{
cert_prv = cert_cur;
cert_cur = cert_cur->next;
@ -3384,7 +3313,6 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
if( cert_prv != crt )
mbedtls_free( cert_prv );
}
while( cert_cur != NULL );
}
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)

View File

@ -375,9 +375,6 @@ void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
*/
void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
{
mbedtls_x509_name *name_cur;
mbedtls_x509_name *name_prv;
if( csr == NULL )
return;
@ -387,14 +384,7 @@ void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
mbedtls_free( csr->sig_opts );
#endif
name_cur = csr->subject.next;
while( name_cur != NULL )
{
name_prv = name_cur;
name_cur = name_cur->next;
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
mbedtls_free( name_prv );
}
mbedtls_asn1_free_named_data_list_shallow( csr->subject.next );
if( csr->raw.p != NULL )
{

View File

@ -1,6 +1,7 @@
fuzz_client
fuzz_dtlsclient
fuzz_dtlsserver
fuzz_pkcs7
fuzz_privkey
fuzz_pubkey
fuzz_server

View File

@ -12,6 +12,7 @@ set(executables_no_common_c
fuzz_x509crl
fuzz_x509crt
fuzz_x509csr
fuzz_pkcs7
)
set(executables_with_common_c

View File

@ -0,0 +1,19 @@
#include <stdint.h>
#include "mbedtls/pkcs7.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
#ifdef MBEDTLS_PKCS7_C
mbedtls_pkcs7 pkcs7;
mbedtls_pkcs7_init( &pkcs7 );
mbedtls_pkcs7_parse_der( &pkcs7, Data, Size );
mbedtls_pkcs7_free( &pkcs7 );
#else
(void) Data;
(void) Size;
#endif
return 0;
}

View File

@ -0,0 +1,2 @@
[libfuzzer]
max_len = 65535

View File

@ -157,8 +157,8 @@ int main( int argc, char **argv )
goto exit;
}
if( ( ret = mbedtls_mpi_write_file( "P = ", &P, 16, fout ) != 0 ) ||
( ret = mbedtls_mpi_write_file( "G = ", &G, 16, fout ) != 0 ) )
if( ( ( ret = mbedtls_mpi_write_file( "P = ", &P, 16, fout ) ) != 0 ) ||
( ( ret = mbedtls_mpi_write_file( "G = ", &G, 16, fout ) ) != 0 ) )
{
mbedtls_printf( " failed\n ! mbedtls_mpi_write_file returned %d\n\n", ret );
fclose( fout );

View File

@ -64,6 +64,7 @@ int main( void )
#define DFL_KEY_OPAQUE 0
#define DFL_KEY_PWD ""
#define DFL_PSK ""
#define DFL_EARLY_DATA MBEDTLS_SSL_EARLY_DATA_DISABLED
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
@ -344,6 +345,14 @@ int main( void )
#define USAGE_SERIALIZATION ""
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \
" early_data=%%d default: 0 (disabled)\n" \
" options: 0 (disabled), 1 (enabled)\n"
#else
#define USAGE_EARLY_DATA ""
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_PROTO_TLS1_3 */
#define USAGE_KEY_OPAQUE_ALGS \
" key_opaque_algs=%%s Allowed opaque key algorithms.\n" \
" comma-separated pair of values among the following:\n" \
@ -376,6 +385,8 @@ int main( void )
" a second non-empty message before attempting\n" \
" to read a response from the server\n" \
" debug_level=%%d default: 0 (disabled)\n" \
" build_version=%%d default: none (disabled)\n" \
" option: 1 (print build version only and stop)\n" \
" nbio=%%d default: 0 (blocking I/O)\n" \
" options: 1 (non-blocking), 2 (added delays)\n" \
" event=%%d default: 0 (loop)\n" \
@ -420,6 +431,7 @@ int main( void )
USAGE_REPRODUCIBLE \
USAGE_CURVES \
USAGE_SIG_ALGS \
USAGE_EARLY_DATA \
USAGE_DHMLEN \
USAGE_KEY_OPAQUE_ALGS \
"\n"
@ -531,6 +543,9 @@ struct options
* after renegotiation */
int reproducible; /* make communication reproducible */
int skip_close_notify; /* skip sending the close_notify alert */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int early_data; /* support for early data */
#endif
int query_config_mode; /* whether to read config */
int use_srtp; /* Support SRTP */
int force_srtp_profile; /* SRTP protection profile to use or all */
@ -930,6 +945,9 @@ int main( int argc, char *argv[] )
opt.alpn_string = DFL_ALPN_STRING;
opt.curves = DFL_CURVES;
opt.sig_algs = DFL_SIG_ALGS;
#if defined(MBEDTLS_SSL_EARLY_DATA)
opt.early_data = DFL_EARLY_DATA;
#endif
opt.transport = DFL_TRANSPORT;
opt.hs_to_min = DFL_HS_TO_MIN;
opt.hs_to_max = DFL_HS_TO_MAX;
@ -981,6 +999,16 @@ int main( int argc, char *argv[] )
if( opt.debug_level < 0 || opt.debug_level > 65535 )
goto usage;
}
else if( strcmp( p, "build_version" ) == 0 )
{
if( strcmp( q, "1" ) == 0 )
{
mbedtls_printf( "build version: %s (build %d)\n",
MBEDTLS_VERSION_STRING_FULL,
MBEDTLS_VERSION_NUMBER );
goto exit;
}
}
else if( strcmp( p, "context_crt_cb" ) == 0 )
{
opt.context_crt_cb = atoi( q );
@ -1177,7 +1205,24 @@ int main( int argc, char *argv[] )
default: goto usage;
}
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_SSL_EARLY_DATA)
else if( strcmp( p, "early_data" ) == 0 )
{
switch( atoi( q ) )
{
case 0:
opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
break;
case 1:
opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
break;
default: goto usage;
}
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
else if( strcmp( p, "tls13_kex_modes" ) == 0 )
{
if( strcmp( q, "psk" ) == 0 )
@ -1691,6 +1736,9 @@ int main( int argc, char *argv[] )
}
#endif /* MBEDTLS_SSL_ALPN */
mbedtls_printf( "build version: %s (build %d)\n",
MBEDTLS_VERSION_STRING_FULL, MBEDTLS_VERSION_NUMBER );
/*
* 0. Initialize the RNG and the session data
*/
@ -2076,6 +2124,10 @@ int main( int argc, char *argv[] )
if( opt.max_version != DFL_MAX_VERSION )
mbedtls_ssl_conf_max_tls_version( &conf, opt.max_version );
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_tls13_conf_early_data( &conf, opt.early_data );
#endif /* MBEDTLS_SSL_EARLY_DATA */
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned -0x%x\n\n",

View File

@ -488,6 +488,8 @@ int main( void )
" server_addr=%%s default: (all interfaces)\n" \
" server_port=%%d default: 4433\n" \
" debug_level=%%d default: 0 (disabled)\n" \
" build_version=%%d default: none (disabled)\n" \
" option: 1 (print build version only and stop)\n" \
" buffer_size=%%d default: 200 \n" \
" (minimum: 1)\n" \
" response_size=%%d default: about 152 (basic response)\n" \
@ -1743,6 +1745,16 @@ int main( int argc, char *argv[] )
if( opt.debug_level < 0 || opt.debug_level > 65535 )
goto usage;
}
else if( strcmp( p, "build_version" ) == 0 )
{
if( strcmp( q, "1" ) == 0 )
{
mbedtls_printf( "build version: %s (build %d)\n",
MBEDTLS_VERSION_STRING_FULL,
MBEDTLS_VERSION_NUMBER );
goto exit;
}
}
else if( strcmp( p, "nbio" ) == 0 )
{
opt.nbio = atoi( q );
@ -2572,6 +2584,9 @@ int main( int argc, char *argv[] )
}
#endif /* MBEDTLS_SSL_ALPN */
mbedtls_printf( "build version: %s (build %d)\n",
MBEDTLS_VERSION_STRING_FULL, MBEDTLS_VERSION_NUMBER );
/*
* 0. Initialize the RNG and the session data
*/

View File

@ -311,6 +311,7 @@ def include_in_crypto(name):
if name in [
'MBEDTLS_DEBUG_C', # part of libmbedtls
'MBEDTLS_NET_C', # part of libmbedtls
'MBEDTLS_PKCS7_C', # part of libmbedx509
]:
return False
return True

View File

@ -2476,4 +2476,72 @@ psa_status_t psa_driver_wrapper_asymmetric_decrypt(
}
}
psa_status_t psa_driver_wrapper_key_agreement(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *shared_secret,
size_t shared_secret_size,
size_t *shared_secret_length
)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
/* Key is stored in the slot in export representation, so
* cycle through all known transparent accelerators */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
status =
mbedtls_test_transparent_key_agreement( attributes,
key_buffer, key_buffer_size, alg, peer_key,
peer_key_length, shared_secret, shared_secret_size,
shared_secret_length );
if( status != PSA_ERROR_NOT_SUPPORTED )
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
/* Software Fallback */
status = psa_key_agreement_raw_builtin( attributes,
key_buffer,
key_buffer_size,
alg,
peer_key,
peer_key_length,
shared_secret,
shared_secret_size,
shared_secret_length );
return( status );
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
case PSA_CRYPTO_TEST_DRIVER_LOCATION:
return( mbedtls_test_opaque_key_agreement( attributes,
key_buffer, key_buffer_size, alg, peer_key,
peer_key_length, shared_secret, shared_secret_size,
shared_secret_length ) );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
default:
(void) attributes;
(void) key_buffer;
(void) key_buffer_size;
(void) peer_key;
(void) peer_key_length;
(void) shared_secret;
(void) shared_secret_size;
(void) shared_secret_length;
return( PSA_ERROR_NOT_SUPPORTED );
}
}
#endif /* MBEDTLS_PSA_CRYPTO_C */

View File

@ -52,7 +52,7 @@ my @low_level_modules = qw( AES ARIA ASN1 BASE64 BIGNUM
SHA1 SHA256 SHA512 THREADING );
my @high_level_modules = qw( CIPHER DHM ECP MD
PEM PK PKCS12 PKCS5
RSA SSL X509 );
RSA SSL X509 PKCS7 );
undef $/;
@ -136,6 +136,7 @@ foreach my $match (@matches)
$define_name = "ASN1_PARSE" if ($define_name eq "ASN1");
$define_name = "SSL_TLS" if ($define_name eq "SSL");
$define_name = "PEM_PARSE,PEM_WRITE" if ($define_name eq "PEM");
$define_name = "PKCS7" if ($define_name eq "PKCS7");
my $include_name = $module_name;
$include_name =~ tr/A-Z/a-z/;

View File

@ -14,11 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
import typing
from abc import abstractmethod
from typing import Iterator, List, Tuple, TypeVar
from typing import Iterator, List, Tuple, TypeVar, Any
from itertools import chain
from . import test_case
from . import test_data_generation
from .bignum_data import INPUTS_DEFAULT, MODULI_DEFAULT
T = TypeVar('T') #pylint: disable=invalid-name
@ -38,7 +40,13 @@ def invmod(a: int, n: int) -> int:
raise ValueError("Not invertible")
def hex_to_int(val: str) -> int:
return int(val, 16) if val else 0
"""Implement the syntax accepted by mbedtls_test_read_mpi().
This is a superset of what is accepted by mbedtls_test_read_mpi_core().
"""
if val in ['', '-']:
return 0
return int(val, 16)
def quote_str(val) -> str:
return "\"{}\"".format(val)
@ -57,18 +65,10 @@ def limbs_mpi(val: int, bits_in_limb: int) -> int:
return (val.bit_length() + bits_in_limb - 1) // bits_in_limb
def combination_pairs(values: List[T]) -> List[Tuple[T, T]]:
"""Return all pair combinations from input values.
"""Return all pair combinations from input values."""
return [(x, y) for x in values for y in values]
The return value is cast, as older versions of mypy are unable to derive
the specific type returned by itertools.combinations_with_replacement.
"""
return typing.cast(
List[Tuple[T, T]],
list(itertools.combinations_with_replacement(values, 2))
)
class OperationCommon:
class OperationCommon(test_data_generation.BaseTest):
"""Common features for bignum binary operations.
This adds functionality common in binary operation tests.
@ -82,22 +82,106 @@ class OperationCommon:
unique_combinations_only: Boolean to select if test case combinations
must be unique. If True, only A,B or B,A would be included as a test
case. If False, both A,B and B,A would be included.
input_style: Controls the way how test data is passed to the functions
in the generated test cases. "variable" passes them as they are
defined in the python source. "arch_split" pads the values with
zeroes depending on the architecture/limb size. If this is set,
test cases are generated for all architectures.
arity: the number of operands for the operation. Currently supported
values are 1 and 2.
"""
symbol = ""
input_values = [] # type: List[str]
input_cases = [] # type: List[Tuple[str, str]]
unique_combinations_only = True
input_values = INPUTS_DEFAULT # type: List[str]
input_cases = [] # type: List[Any]
unique_combinations_only = False
input_styles = ["variable", "fixed", "arch_split"] # type: List[str]
input_style = "variable" # type: str
limb_sizes = [32, 64] # type: List[int]
arities = [1, 2]
arity = 2
def __init__(self, val_a: str, val_b: str) -> None:
self.arg_a = val_a
self.arg_b = val_b
def __init__(self, val_a: str, val_b: str = "0", bits_in_limb: int = 32) -> None:
self.val_a = val_a
self.val_b = val_b
# Setting the int versions here as opposed to making them @properties
# provides earlier/more robust input validation.
self.int_a = hex_to_int(val_a)
self.int_b = hex_to_int(val_b)
if bits_in_limb not in self.limb_sizes:
raise ValueError("Invalid number of bits in limb!")
if self.input_style == "arch_split":
self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)]
self.bits_in_limb = bits_in_limb
@property
def boundary(self) -> int:
if self.arity == 1:
return self.int_a
elif self.arity == 2:
return max(self.int_a, self.int_b)
raise ValueError("Unsupported number of operands!")
@property
def limb_boundary(self) -> int:
return bound_mpi(self.boundary, self.bits_in_limb)
@property
def limbs(self) -> int:
return limbs_mpi(self.boundary, self.bits_in_limb)
@property
def hex_digits(self) -> int:
return 2 * (self.limbs * self.bits_in_limb // 8)
def format_arg(self, val) -> str:
if self.input_style not in self.input_styles:
raise ValueError("Unknown input style!")
if self.input_style == "variable":
return val
else:
return val.zfill(self.hex_digits)
def format_result(self, res) -> str:
res_str = '{:x}'.format(res)
return quote_str(self.format_arg(res_str))
@property
def arg_a(self) -> str:
return self.format_arg(self.val_a)
@property
def arg_b(self) -> str:
if self.arity == 1:
raise AttributeError("Operation is unary and doesn't have arg_b!")
return self.format_arg(self.val_b)
def arguments(self) -> List[str]:
return [
quote_str(self.arg_a), quote_str(self.arg_b)
] + self.result()
args = [quote_str(self.arg_a)]
if self.arity == 2:
args.append(quote_str(self.arg_b))
return args + self.result()
def description(self) -> str:
"""Generate a description for the test case.
If not set, case_description uses the form A `symbol` B, where symbol
is used to represent the operation. Descriptions of each value are
generated to provide some context to the test case.
"""
if not self.case_description:
if self.arity == 1:
self.case_description = "{} {:x}".format(
self.symbol, self.int_a
)
elif self.arity == 2:
self.case_description = "{:x} {} {:x}".format(
self.int_a, self.symbol, self.int_b
)
return super().description()
@property
def is_valid(self) -> bool:
return True
@abstractmethod
def result(self) -> List[str]:
@ -115,15 +199,134 @@ class OperationCommon:
Combinations are first generated from all input values, and then
specific cases provided.
"""
if cls.unique_combinations_only:
yield from combination_pairs(cls.input_values)
if cls.arity == 1:
yield from ((a, "0") for a in cls.input_values)
elif cls.arity == 2:
if cls.unique_combinations_only:
yield from combination_pairs(cls.input_values)
else:
yield from (
(a, b)
for a in cls.input_values
for b in cls.input_values
)
else:
yield from (
(a, b)
for a in cls.input_values
for b in cls.input_values
)
yield from cls.input_cases
raise ValueError("Unsupported number of operands!")
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
if cls.input_style not in cls.input_styles:
raise ValueError("Unknown input style!")
if cls.arity not in cls.arities:
raise ValueError("Unsupported number of operands!")
if cls.input_style == "arch_split":
test_objects = (cls(a, b, bits_in_limb=bil)
for a, b in cls.get_value_pairs()
for bil in cls.limb_sizes)
special_cases = (cls(*args, bits_in_limb=bil) # type: ignore
for args in cls.input_cases
for bil in cls.limb_sizes)
else:
test_objects = (cls(a, b)
for a, b in cls.get_value_pairs())
special_cases = (cls(*args) for args in cls.input_cases)
yield from (valid_test_object.create_test_case()
for valid_test_object in filter(
lambda test_object: test_object.is_valid,
chain(test_objects, special_cases)
)
)
class ModOperationCommon(OperationCommon):
#pylint: disable=abstract-method
"""Target for bignum mod_raw test case generation."""
moduli = MODULI_DEFAULT # type: List[str]
def __init__(self, val_n: str, val_a: str, val_b: str = "0",
bits_in_limb: int = 64) -> None:
super().__init__(val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb)
self.val_n = val_n
# Setting the int versions here as opposed to making them @properties
# provides earlier/more robust input validation.
self.int_n = hex_to_int(val_n)
@property
def boundary(self) -> int:
return self.int_n
@property
def arg_n(self) -> str:
return self.format_arg(self.val_n)
def arguments(self) -> List[str]:
return [quote_str(self.arg_n)] + super().arguments()
@property
def r(self) -> int: # pylint: disable=invalid-name
l = limbs_mpi(self.int_n, self.bits_in_limb)
return bound_mpi_limbs(l, self.bits_in_limb)
@property
def r_inv(self) -> int:
return invmod(self.r, self.int_n)
@property
def r2(self) -> int: # pylint: disable=invalid-name
return pow(self.r, 2)
@property
def is_valid(self) -> bool:
if self.int_a >= self.int_n:
return False
if self.arity == 2 and self.int_b >= self.int_n:
return False
return True
def description(self) -> str:
"""Generate a description for the test case.
It uses the form A `symbol` B mod N, where symbol is used to represent
the operation.
"""
if not self.case_description:
return super().description() + " mod {:x}".format(self.int_n)
return super().description()
@classmethod
def input_cases_args(cls) -> Iterator[Tuple[Any, Any, Any]]:
if cls.arity == 1:
yield from ((n, a, "0") for a, n in cls.input_cases)
elif cls.arity == 2:
yield from ((n, a, b) for a, b, n in cls.input_cases)
else:
raise ValueError("Unsupported number of operands!")
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
if cls.input_style not in cls.input_styles:
raise ValueError("Unknown input style!")
if cls.arity not in cls.arities:
raise ValueError("Unsupported number of operands!")
if cls.input_style == "arch_split":
test_objects = (cls(n, a, b, bits_in_limb=bil)
for n in cls.moduli
for a, b in cls.get_value_pairs()
for bil in cls.limb_sizes)
special_cases = (cls(*args, bits_in_limb=bil)
for args in cls.input_cases_args()
for bil in cls.limb_sizes)
else:
test_objects = (cls(n, a, b)
for n in cls.moduli
for a, b in cls.get_value_pairs())
special_cases = (cls(*args) for args in cls.input_cases_args())
yield from (valid_test_object.create_test_case()
for valid_test_object in filter(
lambda test_object: test_object.is_valid,
chain(test_objects, special_cases)
))
# BEGIN MERGE SLOT 1

View File

@ -16,20 +16,19 @@
import random
from abc import ABCMeta
from typing import Dict, Iterator, List, Tuple
from . import test_case
from . import test_data_generation
from . import bignum_common
class BignumCoreTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumCoreTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for bignum core test case generation."""
target_basename = 'test_suite_bignum_core.generated'
class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta):
class BignumCoreShiftR(BignumCoreTarget, test_data_generation.BaseTest):
"""Test cases for mbedtls_bignum_core_shift_r()."""
count = 0
test_function = "mpi_core_shift_r"
@ -69,7 +68,7 @@ class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta):
for count in counts:
yield cls(input_hex, descr, count).create_test_case()
class BignumCoreCTLookup(BignumCoreTarget, metaclass=ABCMeta):
class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest):
"""Test cases for mbedtls_mpi_core_ct_uint_table_lookup()."""
test_function = "mpi_core_ct_uint_table_lookup"
test_name = "Constant time MPI table lookup"
@ -107,104 +106,33 @@ class BignumCoreCTLookup(BignumCoreTarget, metaclass=ABCMeta):
yield (cls(bitsize, bitsize_description, window_size)
.create_test_case())
class BignumCoreOperation(bignum_common.OperationCommon, BignumCoreTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
"""Common features for bignum core operations."""
input_values = [
"0", "1", "3", "f", "fe", "ff", "100", "ff00", "fffe", "ffff", "10000",
"fffffffe", "ffffffff", "100000000", "1f7f7f7f7f7f7f",
"8000000000000000", "fefefefefefefefe", "fffffffffffffffe",
"ffffffffffffffff", "10000000000000000", "1234567890abcdef0",
"fffffffffffffffffefefefefefefefe", "fffffffffffffffffffffffffffffffe",
"ffffffffffffffffffffffffffffffff", "100000000000000000000000000000000",
"1234567890abcdef01234567890abcdef0",
"fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"10000000000000000000000000000000000000000000000000000000000000000",
"1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0",
(
"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029"
"643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947"
"c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0"
"cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b"
)
]
def description(self) -> str:
"""Generate a description for the test case.
If not set, case_description uses the form A `symbol` B, where symbol
is used to represent the operation. Descriptions of each value are
generated to provide some context to the test case.
"""
if not self.case_description:
self.case_description = "{:x} {} {:x}".format(
self.int_a, self.symbol, self.int_b
)
return super().description()
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
for a_value, b_value in cls.get_value_pairs():
yield cls(a_value, b_value).create_test_case()
class BignumCoreOperationArchSplit(BignumCoreOperation):
#pylint: disable=abstract-method
"""Common features for bignum core operations where the result depends on
the limb size."""
def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None:
super().__init__(val_a, val_b)
bound_val = max(self.int_a, self.int_b)
self.bits_in_limb = bits_in_limb
self.bound = bignum_common.bound_mpi(bound_val, self.bits_in_limb)
limbs = bignum_common.limbs_mpi(bound_val, self.bits_in_limb)
byte_len = limbs * self.bits_in_limb // 8
self.hex_digits = 2 * byte_len
if self.bits_in_limb == 32:
self.dependencies = ["MBEDTLS_HAVE_INT32"]
elif self.bits_in_limb == 64:
self.dependencies = ["MBEDTLS_HAVE_INT64"]
else:
raise ValueError("Invalid number of bits in limb!")
self.arg_a = self.arg_a.zfill(self.hex_digits)
self.arg_b = self.arg_b.zfill(self.hex_digits)
def pad_to_limbs(self, val) -> str:
return "{:x}".format(val).zfill(self.hex_digits)
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
for a_value, b_value in cls.get_value_pairs():
yield cls(a_value, b_value, 32).create_test_case()
yield cls(a_value, b_value, 64).create_test_case()
class BignumCoreAddAndAddIf(BignumCoreOperationArchSplit):
class BignumCoreAddAndAddIf(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for bignum core add and add-if."""
count = 0
symbol = "+"
test_function = "mpi_core_add_and_add_if"
test_name = "mpi_core_add_and_add_if"
input_style = "arch_split"
unique_combinations_only = True
def result(self) -> List[str]:
result = self.int_a + self.int_b
carry, result = divmod(result, self.bound)
carry, result = divmod(result, self.limb_boundary)
return [
bignum_common.quote_str(self.pad_to_limbs(result)),
self.format_result(result),
str(carry)
]
class BignumCoreSub(BignumCoreOperation):
class BignumCoreSub(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for bignum core sub."""
count = 0
symbol = "-"
test_function = "mpi_core_sub"
test_name = "mbedtls_mpi_core_sub"
unique_combinations_only = False
def result(self) -> List[str]:
if self.int_a >= self.int_b:
@ -224,12 +152,11 @@ class BignumCoreSub(BignumCoreOperation):
]
class BignumCoreMLA(BignumCoreOperation):
class BignumCoreMLA(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for fixed-size multiply accumulate."""
count = 0
test_function = "mpi_core_mla"
test_name = "mbedtls_mpi_core_mla"
unique_combinations_only = False
input_values = [
"0", "1", "fffe", "ffffffff", "100000000", "20000000000000",
@ -288,6 +215,16 @@ class BignumCoreMLA(BignumCoreOperation):
"\"{:x}\"".format(carry_8)
]
@classmethod
def get_value_pairs(cls) -> Iterator[Tuple[str, str]]:
"""Generator to yield pairs of inputs.
Combinations are first generated from all input values, and then
specific cases provided.
"""
yield from super().get_value_pairs()
yield from cls.input_cases
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
"""Override for additional scalar input."""
@ -297,7 +234,7 @@ class BignumCoreMLA(BignumCoreOperation):
yield cur_op.create_test_case()
class BignumCoreMontmul(BignumCoreTarget):
class BignumCoreMontmul(BignumCoreTarget, test_data_generation.BaseTest):
"""Test cases for Montgomery multiplication."""
count = 0
test_function = "mpi_core_montmul"
@ -818,6 +755,23 @@ def mpi_modmul_case_generate() -> None:
# BEGIN MERGE SLOT 1
class BignumCoreExpMod(BignumCoreTarget, bignum_common.ModOperationCommon):
"""Test cases for bignum core exponentiation."""
symbol = "^"
test_function = "mpi_core_exp_mod"
test_name = "Core modular exponentiation"
input_style = "fixed"
def result(self) -> List[str]:
result = pow(self.int_a, self.int_b, self.int_n)
return [self.format_result(result)]
@property
def is_valid(self) -> bool:
# The base needs to be canonical, but the exponent can be larger than
# the modulus (see for example exponent blinding)
return bool(self.int_a < self.int_n)
# END MERGE SLOT 1
# BEGIN MERGE SLOT 2
@ -826,6 +780,37 @@ def mpi_modmul_case_generate() -> None:
# BEGIN MERGE SLOT 3
class BignumCoreSubInt(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for bignum core sub int."""
count = 0
symbol = "-"
test_function = "mpi_core_sub_int"
test_name = "mpi_core_sub_int"
input_style = "arch_split"
@property
def is_valid(self) -> bool:
# This is "sub int", so b is only one limb
if bignum_common.limbs_mpi(self.int_b, self.bits_in_limb) > 1:
return False
return True
# Overriding because we don't want leading zeros on b
@property
def arg_b(self) -> str:
return self.val_b
def result(self) -> List[str]:
result = self.int_a - self.int_b
borrow, result = divmod(result, self.limb_boundary)
# Borrow will be -1 if non-zero, but we want it to be 1 in the test data
return [
self.format_result(result),
str(-borrow)
]
# END MERGE SLOT 3
# BEGIN MERGE SLOT 4

View File

@ -0,0 +1,136 @@
"""Base values and datasets for bignum generated tests and helper functions that
produced them."""
# 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.
import random
# Functions calling these were used to produce test data and are here only for
# reproducability, they are not used by the test generation framework/classes
try:
from Cryptodome.Util.number import isPrime, getPrime #type: ignore #pylint: disable=import-error
except ImportError:
pass
# Generated by bignum_common.gen_safe_prime(192,1)
SAFE_PRIME_192_BIT_SEED_1 = "d1c127a667786703830500038ebaef20e5a3e2dc378fb75b"
# First number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO1 = "177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"
# Second number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO2 = "cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
# Third number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO3 = "3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"
# Fourth number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO4 = "ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
# Ninth number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO9 = "2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"
# Generated by bignum_common.gen_safe_prime(1024,3)
SAFE_PRIME_1024_BIT_SEED_3 = ("c93ba7ec74d96f411ba008bdb78e63ff11bb5df46a51e16b"
"2c9d156f8e4e18abf5e052cb01f47d0d1925a77f60991577"
"e128fb6f52f34a27950a594baadd3d8057abeb222cf3cca9"
"62db16abf79f2ada5bd29ab2f51244bf295eff9f6aaba130"
"2efc449b128be75eeaca04bc3c1a155d11d14e8be32a2c82"
"87b3996cf6ad5223")
# First number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO1 = ("6905269ed6f0b09f165c8ce36e2f24b43000de01b2ed40ed"
"3addccb2c33be0ac79d679346d4ac7a5c3902b38963dc6e8"
"534f45738d048ec0f1099c6c3e1b258fd724452ccea71ff4"
"a14876aeaff1a098ca5996666ceab360512bd13110722311"
"710cf5327ac435a7a97c643656412a9b8a1abcd1a6916c74"
"da4f9fc3c6da5d7")
# Second number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO2 = ("f1cfd99216df648647adec26793d0e453f5082492d83a823"
"3fb62d2c81862fc9634f806fabf4a07c566002249b191bf4"
"d8441b5616332aca5f552773e14b0190d93936e1daca3c06"
"f5ff0c03bb5d7385de08caa1a08179104a25e4664f5253a0"
"2a3187853184ff27459142deccea264542a00403ce80c4b0"
"a4042bb3d4341aad")
# Third number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO3 = ("14c15c910b11ad28cc21ce88d0060cc54278c2614e1bcb38"
"3bb4a570294c4ea3738d243a6e58d5ca49c7b59b995253fd"
"6c79a3de69f85e3131f3b9238224b122c3e4a892d9196ada"
"4fcfa583e1df8af9b474c7e89286a1754abcb06ae8abb93f"
"01d89a024cdce7a6d7288ff68c320f89f1347e0cdd905ecf"
"d160c5d0ef412ed6")
# Fourth number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO4 = ("32decd6b8efbc170a26a25c852175b7a96b98b5fbf37a2be"
"6f98bca35b17b9662f0733c846bbe9e870ef55b1a1f65507"
"a2909cb633e238b4e9dd38b869ace91311021c9e32111ac1"
"ac7cc4a4ff4dab102522d53857c49391b36cc9aa78a330a1"
"a5e333cb88dcf94384d4cd1f47ca7883ff5a52f1a05885ac"
"7671863c0bdbc23a")
# Fifth number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO5 = ("53be4721f5b9e1f5acdac615bc20f6264922b9ccf469aef8"
"f6e7d078e55b85dd1525f363b281b8885b69dc230af5ac87"
"0692b534758240df4a7a03052d733dcdef40af2e54c0ce68"
"1f44ebd13cc75f3edcb285f89d8cf4d4950b16ffc3e1ac3b"
"4708d9893a973000b54a23020fc5b043d6e4a51519d9c9cc"
"52d32377e78131c1")
# Adding 192 bit and 1024 bit numbers because these are the shortest required
# for ECC and RSA respectively.
INPUTS_DEFAULT = [
"0", "1", # corner cases
"2", "3", # small primes
"4", # non-prime even
"38", # small random
SAFE_PRIME_192_BIT_SEED_1, # prime
RANDOM_192_BIT_SEED_2_NO1, # not a prime
RANDOM_192_BIT_SEED_2_NO2, # not a prime
SAFE_PRIME_1024_BIT_SEED_3, # prime
RANDOM_1024_BIT_SEED_4_NO1, # not a prime
RANDOM_1024_BIT_SEED_4_NO3, # not a prime
RANDOM_1024_BIT_SEED_4_NO2, # largest (not a prime)
]
# Only odd moduli are present as in the new bignum code only odd moduli are
# supported for now.
MODULI_DEFAULT = [
"53", # safe prime
"45", # non-prime
SAFE_PRIME_192_BIT_SEED_1, # safe prime
RANDOM_192_BIT_SEED_2_NO4, # not a prime
SAFE_PRIME_1024_BIT_SEED_3, # safe prime
RANDOM_1024_BIT_SEED_4_NO5, # not a prime
]
def __gen_safe_prime(bits, seed):
'''
Generate a safe prime.
This function is intended for generating constants offline and shouldn't be
used in test generation classes.
Requires pycryptodomex for getPrime and isPrime and python 3.9 or later for
randbytes.
'''
rng = random.Random()
# We want reproducability across python versions
rng.seed(seed, version=2)
while True:
prime = 2*getPrime(bits-1, rng.randbytes)+1 #pylint: disable=no-member
if isPrime(prime, 1e-30):
return prime

View File

@ -14,12 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from abc import ABCMeta
from typing import Dict, List # pylint: disable=unused-import
from . import test_data_generation
from . import bignum_common # pylint: disable=unused-import
class BignumModTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumModTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for bignum mod test case generation."""
target_basename = 'test_suite_bignum_mod.generated'

View File

@ -14,12 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from abc import ABCMeta
from typing import Dict, List
from . import test_data_generation
from . import bignum_common
class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumModRawTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for bignum mod_raw test case generation."""
target_basename = 'test_suite_bignum_mod_raw.generated'
@ -29,6 +30,25 @@ class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
# BEGIN MERGE SLOT 2
class BignumModRawSub(bignum_common.ModOperationCommon,
BignumModRawTarget):
"""Test cases for bignum mpi_mod_raw_sub()."""
symbol = "-"
test_function = "mpi_mod_raw_sub"
test_name = "mbedtls_mpi_mod_raw_sub"
input_style = "fixed"
arity = 2
def arguments(self) -> List[str]:
return [bignum_common.quote_str(n) for n in [self.arg_a,
self.arg_b,
self.arg_n]
] + self.result()
def result(self) -> List[str]:
result = (self.int_a - self.int_b) % self.int_n
return [self.format_result(result)]
# END MERGE SLOT 2
# BEGIN MERGE SLOT 3
@ -41,6 +61,19 @@ class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
# BEGIN MERGE SLOT 5
class BignumModRawAdd(bignum_common.ModOperationCommon,
BignumModRawTarget):
"""Test cases for bignum mpi_mod_raw_add()."""
symbol = "+"
test_function = "mpi_mod_raw_add"
test_name = "mbedtls_mpi_mod_raw_add"
input_style = "fixed"
arity = 2
def result(self) -> List[str]:
result = (self.int_a + self.int_b) % self.int_n
return [self.format_result(result)]
# END MERGE SLOT 5
# BEGIN MERGE SLOT 6
@ -49,6 +82,34 @@ class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
# BEGIN MERGE SLOT 7
class BignumModRawConvertToMont(bignum_common.ModOperationCommon,
BignumModRawTarget):
""" Test cases for mpi_mod_raw_to_mont_rep(). """
test_function = "mpi_mod_raw_to_mont_rep"
test_name = "Convert into Mont: "
symbol = "R *"
input_style = "arch_split"
arity = 1
def result(self) -> List[str]:
result = (self.int_a * self.r) % self.int_n
return [self.format_result(result)]
class BignumModRawConvertFromMont(bignum_common.ModOperationCommon,
BignumModRawTarget):
""" Test cases for mpi_mod_raw_from_mont_rep(). """
test_function = "mpi_mod_raw_from_mont_rep"
test_name = "Convert from Mont: "
symbol = "1/R *"
input_style = "arch_split"
arity = 1
def result(self) -> List[str]:
result = (self.int_a * self.r_inv) % self.int_n
return [self.format_result(result)]
# END MERGE SLOT 7
# BEGIN MERGE SLOT 8

View File

@ -25,6 +25,7 @@ import argparse
import os
import posixpath
import re
import inspect
from abc import ABCMeta, abstractmethod
from typing import Callable, Dict, Iterable, Iterator, List, Type, TypeVar
@ -35,12 +36,8 @@ from . import test_case
T = TypeVar('T') #pylint: disable=invalid-name
class BaseTarget(metaclass=ABCMeta):
"""Base target for test case generation.
Child classes of this class represent an output file, and can be referred
to as file targets. These indicate where test cases will be written to for
all subclasses of the file target, which is set by `target_basename`.
class BaseTest(metaclass=ABCMeta):
"""Base class for test case generation.
Attributes:
count: Counter for test cases from this class.
@ -48,8 +45,6 @@ class BaseTarget(metaclass=ABCMeta):
automatically generated using the class, or manually set.
dependencies: A list of dependencies required for the test case.
show_test_count: Toggle for inclusion of `count` in the test description.
target_basename: Basename of file to write generated tests to. This
should be specified in a child class of BaseTarget.
test_function: Test function which the class generates cases for.
test_name: A common name or description of the test function. This can
be `test_function`, a clearer equivalent, or a short summary of the
@ -59,7 +54,6 @@ class BaseTarget(metaclass=ABCMeta):
case_description = ""
dependencies = [] # type: List[str]
show_test_count = True
target_basename = ""
test_function = ""
test_name = ""
@ -121,6 +115,21 @@ class BaseTarget(metaclass=ABCMeta):
"""
raise NotImplementedError
class BaseTarget:
#pylint: disable=too-few-public-methods
"""Base target for test case generation.
Child classes of this class represent an output file, and can be referred
to as file targets. These indicate where test cases will be written to for
all subclasses of the file target, which is set by `target_basename`.
Attributes:
target_basename: Basename of file to write generated tests to. This
should be specified in a child class of BaseTarget.
"""
target_basename = ""
@classmethod
def generate_tests(cls) -> Iterator[test_case.TestCase]:
"""Generate test cases for the class and its subclasses.
@ -132,7 +141,8 @@ class BaseTarget(metaclass=ABCMeta):
yield from `generate_tests()` in each. Calling this method on a class X
will yield test cases from all classes derived from X.
"""
if cls.test_function:
if issubclass(cls, BaseTest) and not inspect.isabstract(cls):
#pylint: disable=no-member
yield from cls.generate_function_tests()
for subclass in sorted(cls.__subclasses__(), key=lambda c: c.__name__):
yield from subclass.generate_tests()

View File

@ -70,6 +70,8 @@ if(GEN_FILES)
${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_bignum_tests.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_common.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_core.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_mod_raw.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_mod.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_case.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_data_generation.py
)
@ -106,6 +108,10 @@ endif()
# the risk of a race.
add_custom_target(test_suite_bignum_generated_data DEPENDS ${bignum_generated_data_files})
add_custom_target(test_suite_psa_generated_data DEPENDS ${psa_generated_data_files})
# If SKIP_TEST_SUITES is not defined with -D, get it from the environment.
if((NOT DEFINED SKIP_TEST_SUITES) AND (DEFINED ENV{SKIP_TEST_SUITES}))
set(SKIP_TEST_SUITES $ENV{SKIP_TEST_SUITES})
endif()
# Test suites caught by SKIP_TEST_SUITES are built but not executed.
# "foo" as a skip pattern skips "test_suite_foo" and "test_suite_foo.bar"
# but not "test_suite_foobar".

View File

@ -94,6 +94,8 @@ $(GENERATED_BIGNUM_DATA_FILES): generated_bignum_test_data
generated_bignum_test_data: scripts/generate_bignum_tests.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_common.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_core.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_mod_raw.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_mod.py
generated_bignum_test_data: ../scripts/mbedtls_dev/test_case.py
generated_bignum_test_data: ../scripts/mbedtls_dev/test_data_generation.py
generated_bignum_test_data:

View File

@ -595,6 +595,20 @@ setup_arguments()
G_CLIENT_ARGS="-p $PORT --debug 3 $G_MODE"
G_CLIENT_PRIO="NONE:$G_PRIO_MODE:+COMP-NULL:+CURVE-ALL:+SIGN-ALL"
# Newer versions of OpenSSL have a syntax to enable all "ciphers", even
# low-security ones. This covers not just cipher suites but also protocol
# versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on
# OpenSSL 1.1.1f from Ubuntu 20.04. The syntax was only introduced in
# OpenSSL 1.1.0 (21e0c1d23afff48601eb93135defddae51f7e2e3) and I can't find
# a way to discover it from -help, so check the openssl version.
case $($OPENSSL_CMD version) in
"OpenSSL 0"*|"OpenSSL 1.0"*) :;;
*)
O_CLIENT_ARGS="$O_CLIENT_ARGS -cipher ALL@SECLEVEL=0"
O_SERVER_ARGS="$O_SERVER_ARGS -cipher ALL@SECLEVEL=0"
;;
esac
if [ "X$VERIFY" = "XYES" ];
then
M_SERVER_ARGS="$M_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"

View File

@ -34,6 +34,8 @@
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
/* Enable some invasive tests */
#define MBEDTLS_TEST_HOOKS

Some files were not shown because too many files have changed in this diff Show More