mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-01-30 15:32:58 +00:00
Merge pull request #976 from Mbed-TLS/merge-dev
Merge development into restricted
This commit is contained in:
commit
4705f2d8a1
34
.travis.yml
34
.travis.yml
@ -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
|
||||
|
@ -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).
|
||||
|
16
ChangeLog.d/dtls-connection-id.txt
Normal file
16
ChangeLog.d/dtls-connection-id.txt
Normal 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.
|
5
ChangeLog.d/ecjpake-in-tls.txt
Normal file
5
ChangeLog.d/ecjpake-in-tls.txt
Normal 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.
|
@ -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).
|
5
ChangeLog.d/fix-tls12server-sent-sigalgs.txt
Normal file
5
ChangeLog.d/fix-tls12server-sent-sigalgs.txt
Normal 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.
|
4
ChangeLog.d/fix_dh_genprime_error_reporting.txt
Normal file
4
ChangeLog.d/fix_dh_genprime_error_reporting.txt
Normal 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.
|
5
ChangeLog.d/fix_x509_info_hwmodulename.txt
Normal file
5
ChangeLog.d/fix_x509_info_hwmodulename.txt
Normal 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.
|
6
ChangeLog.d/mbedtls_asn1_type_free.txt
Normal file
6
ChangeLog.d/mbedtls_asn1_type_free.txt
Normal 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()
|
3
ChangeLog.d/move-ssl-modules.txt
Normal file
3
ChangeLog.d/move-ssl-modules.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Move some SSL-specific code out of libmbedcrypto where it had been placed
|
||||
accidentally.
|
4
ChangeLog.d/mpi-add-0-ub.txt
Normal file
4
ChangeLog.d/mpi-add-0-ub.txt
Normal 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.
|
4
ChangeLog.d/mpi-most-negative-sint.txt
Normal file
4
ChangeLog.d/mpi-most-negative-sint.txt
Normal 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.
|
6
ChangeLog.d/negative-zero-from-add.txt
Normal file
6
ChangeLog.d/negative-zero-from-add.txt
Normal 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.
|
13
ChangeLog.d/pkcs7-parser.txt
Normal file
13
ChangeLog.d/pkcs7-parser.txt
Normal 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.
|
3
ChangeLog.d/psa-ecb-ub.txt
Normal file
3
ChangeLog.d/psa-ecb-ub.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix undefined behavior (typically harmless in practice) in PSA ECB
|
||||
encryption and decryption.
|
5
ChangeLog.d/psa_driver_wrapper_for_raw_key_agreement.txt
Normal file
5
ChangeLog.d/psa_driver_wrapper_for_raw_key_agreement.txt
Normal 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.
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
241
include/mbedtls/pkcs7.h
Normal 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 */
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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) ) ) )
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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) \
|
||||
|
@ -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
727
library/pkcs7.c
Normal 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
|
@ -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 )
|
||||
|
||||
/*
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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 */
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 )
|
||||
{
|
||||
|
1
programs/fuzz/.gitignore
vendored
1
programs/fuzz/.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
fuzz_client
|
||||
fuzz_dtlsclient
|
||||
fuzz_dtlsserver
|
||||
fuzz_pkcs7
|
||||
fuzz_privkey
|
||||
fuzz_pubkey
|
||||
fuzz_server
|
||||
|
@ -12,6 +12,7 @@ set(executables_no_common_c
|
||||
fuzz_x509crl
|
||||
fuzz_x509crt
|
||||
fuzz_x509csr
|
||||
fuzz_pkcs7
|
||||
)
|
||||
|
||||
set(executables_with_common_c
|
||||
|
19
programs/fuzz/fuzz_pkcs7.c
Normal file
19
programs/fuzz/fuzz_pkcs7.c
Normal 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;
|
||||
}
|
2
programs/fuzz/fuzz_pkcs7.options
Normal file
2
programs/fuzz/fuzz_pkcs7.options
Normal file
@ -0,0 +1,2 @@
|
||||
[libfuzzer]
|
||||
max_len = 65535
|
@ -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 );
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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/;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
136
scripts/mbedtls_dev/bignum_data.py
Normal file
136
scripts/mbedtls_dev/bignum_data.py
Normal 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
|
@ -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'
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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".
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user